php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #75035 Datetime fails to unserialize "extreme" dates
Submitted: 2017-08-04 13:18 UTC Modified: -
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: weirdan at gmail dot com Assigned:
Status: Open Package: Date/time related
PHP Version: 7.1.8 OS: Debian Linux / sid
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2017-08-04 13:18 UTC] weirdan at gmail dot com
Description:
------------
It appears that you can construct a DateTime object, that, upon serialize/unserialize cycle will have *different* data or will fail to unserialize.

Granted, these dates are outside the range people will typically use, but if DateTime can't work with them reliably it should reject them in constructor.



Test script:
---------------
<?php
var_dump('PHP version', PHP_VERSION);

foreach ([PHP_INT_MIN, PHP_INT_MAX] as $extreme) {
    $i = 64;
    while ($i --> 0) {
        $d = new DateTime('@' . ($extreme >> $i));
        $s = serialize($d);
        try {
            $u = unserialize($s);
        } catch (Error $e) {
            $u = "failed unserialization: " . $e->getMessage() . ' : ' . $s;
        }
        $original = $d->format('Y-m-d H:i:s');
        $serializedUnserialized = is_string($u) ? $u : $u->format('Y-m-d H:i:s');
        if ($original !== $serializedUnserialized) {
            var_dump('[' . ($extreme >> $i) . '] ' . $original . ' => ' . $serializedUnserialized);
        }
    }
}


Expected result:
----------------
string(11) "PHP version"
string(5) "7.1.8"

Actual result:
--------------
string(11) "PHP version"
string(5) "7.1.8"
string(60) "[-549755813888] -15452-12-06 11:41:52 => 2002-12-06 11:41:52"
string(61) "[-1099511627776] -32873-11-12 23:23:44 => 1973-11-12 23:23:44"
string(61) "[-2199023255552] -67715-09-22 22:47:28 => 0715-09-22 22:47:28"
string(62) "[-4398046511104] -137399-06-15 21:34:56 => 0399-06-15 21:34:56"
string(62) "[-8796093022208] -276768-11-27 19:09:52 => 6768-11-27 19:09:52"
string(63) "[-17592186044416] -555505-10-25 14:19:44 => 0505-10-25 14:19:44"
string(64) "[-35184372088832] -1112979-08-20 04:39:28 => 0979-08-20 04:39:28"
string(64) "[-70368744177664] -2227927-04-07 09:18:56 => 0927-04-07 09:18:56"
string(65) "[-140737488355328] -4457824-07-13 18:37:52 => 7824-07-13 18:37:52"
string(65) "[-281474976710656] -8917617-01-25 13:15:44 => 2007-01-25 13:15:44"
string(66) "[-562949953421312] -17837204-02-19 02:31:28 => 2004-02-19 02:31:28"
string(67) "[-1125899906842624] -35676378-04-08 05:02:56 => 2008-04-08 05:02:56"
string(67) "[-2251799813685248] -71354726-07-14 10:05:52 => 2006-07-14 10:05:52"
string(245) "[-4503599627370496] -142711421-01-25 20:11:44 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:{s:4:"date";s:32:"-142711421-01-25 20:11:44.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(68) "[-9007199254740992] -285424812-02-20 16:23:28 => 0812-02-20 16:23:28"
string(246) "[-18014398509481984] -570851594-04-11 08:46:56 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:{s:4:"date";s:32:"-570851594-04-11 08:46:56.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(70) "[-36028797018963968] -1141705158-07-20 17:33:52 => 2058-07-20 17:33:52"
string(248) "[-72057594037927936] -2283412285-02-07 11:07:44 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:{s:4:"date";s:33:"-2283412285-02-07 11:07:44.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(71) "[-144115188075855872] -4566826540-03-15 22:15:28 => 0540-03-15 22:15:28"
string(249) "[-288230376151711744] -9133655050-05-29 20:30:56 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:{s:4:"date";s:33:"-9133655050-05-29 20:30:56.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(251) "[-576460752303423488] -18267312070-10-26 17:01:52 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:{s:4:"date";s:34:"-18267312070-10-26 17:01:52.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(252) "[-1152921504606846976] -36534626109-08-20 10:03:44 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:{s:4:"date";s:34:"-36534626109-08-20 10:03:44.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(73) "[-2305843009213693952] -73069254187-04-08 20:07:28 => 4187-04-08 20:07:28"
string(254) "[-4611686018427387904] -146138510344-07-14 16:14:56 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:{s:4:"date";s:35:"-146138510344-07-14 16:14:56.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(254) "[-9223372036854775808] -292277022657-01-27 08:29:53 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:{s:4:"date";s:35:"-292277022657-01-27 08:29:53.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(58) "[274877906943] 10680-07-14 06:09:03 => 2000-07-14 06:09:03"
string(230) "[549755813887] 19391-01-25 12:18:07 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:{s:4:"date";s:27:"19391-01-25 12:18:07.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(59) "[1099511627775] 36812-02-20 00:36:15 => 2002-02-20 00:36:15"
string(59) "[2199023255551] 71654-04-10 01:12:31 => 2004-04-10 01:12:31"
string(233) "[4398046511103] 141338-07-19 02:25:03 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:{s:4:"date";s:28:"141338-07-19 02:25:03.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(60) "[8796093022207] 280707-02-04 04:50:07 => 2007-02-04 04:50:07"
string(61) "[17592186044415] 559444-03-08 09:40:15 => 2044-03-08 09:40:15"
string(236) "[35184372088831] 1116918-05-14 19:20:31 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:s:4:"date";s:29:"1116918-05-14 19:20:31.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(236) "[70368744177663] 2231866-09-25 14:41:03 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:s:4:"date";s:29:"2231866-09-25 14:41:03.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(63) "[140737488355327] 4461763-06-20 05:22:07 => 0763-06-20 05:22:07"
string(63) "[281474976710655] 8921556-12-07 10:44:15 => 0556-12-07 10:44:15"
string(239) "[562949953421311] 17841143-11-13 21:28:31 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:s:4:"date";s:30:"17841143-11-13 21:28:31.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(240) "[1125899906842623] 35680317-09-25 18:57:03 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:s:4:"date";s:30:"35680317-09-25 18:57:03.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(65) "[2251799813685247] 71358665-06-19 13:54:07 => 8665-06-19 13:54:07"
string(242) "[4503599627370495] 142715360-12-06 03:48:15 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:s:4:"date";s:31:"142715360-12-06 03:48:15.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(242) "[9007199254740991] 285428751-11-12 07:36:31 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:s:4:"date";s:31:"285428751-11-12 07:36:31.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(67) "[18014398509481983] 570855533-09-22 15:13:03 => 2003-09-22 15:13:03"
string(245) "[36028797018963967] 1141709097-06-13 06:26:07 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:s:4:"date";s:32:"1141709097-06-13 06:26:07.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(68) "[72057594037927935] 2283416224-11-24 12:52:15 => 2024-11-24 12:52:15"
string(69) "[144115188075855871] 4566830479-10-18 01:44:31 => 1979-10-18 01:44:31"
string(69) "[288230376151711743] 9133658989-08-04 03:29:03 => 1989-08-04 03:29:03"
string(248) "[576460752303423487] 18267316009-03-08 06:58:07 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:s:4:"date";s:33:"18267316009-03-08 06:58:07.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(249) "[1152921504606846975] 36534630048-05-13 13:56:15 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:s:4:"date";s:33:"36534630048-05-13 13:56:15.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(249) "[2305843009213693951] 73069258126-09-25 03:52:31 => failed unserialization: Invalid serialization data for DateTime object : O:8:"DateTime":3:s:4:"date";s:33:"73069258126-09-25 03:52:31.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}"
string(72) "[4611686018427387903] 146138514283-06-19 07:45:03 => 4283-06-19 07:45:03"
string(72) "[9223372036854775807] 292277026596-12-04 15:30:07 => 6596-12-04 15:30:07"


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-08-04 15:18 UTC] weirdan at gmail dot com
7.2.0beta2 is also affected, with the exact same output
 [2017-08-04 16:50 UTC] weirdan at gmail dot com
This also affects string parsing in constructor:

$ php -r '$q = new DateTime("292277026596-12-04 15:30:07", new DateTimeZone("UTC")); var_dump($q);'

class DateTime#1 (3) {
  public $date =>
  string(26) "6596-12-04 15:30:07.000000"
  public $timezone_type =>
  int(3)
  public $timezone =>
  string(3) "UTC"
}
 [2017-08-05 07:24 UTC] as@php.net
This patch fixes the issue:

https://gist.github.com/adsr/63f2bc2bc952db2f1ca62a4721648a5a

However it is also at odds with the fix for bug #62852, which asserts that a 5-digit year should fail to unserialize[0]. This seems wrong for 2 reasons: (1) We already construct (via `'@%d'` format), serialize, and `date`-format 5+ digit years, and (2) ISO 8601 allows for 5+ digit years if the sender and receiver agree upon the format.

[0] https://github.com/php/php-src/blob/771e5cc/ext/date/tests/bug62852.phpt
 [2017-08-05 17:04 UTC] weirdan at gmail dot com
Also, documentation[1] says:

> The date and time information is internally stored as a 64-bit number so all conceivably useful dates (including negative years) are supported. The range is from about 292 billion years in the past to the same in the future.

[1] http://php.net/manual/en/intro.datetime.php
 [2017-08-05 17:20 UTC] weirdan at gmail dot com
> However it is also at odds with the fix for bug #62852, which asserts that a 5-digit year should fail to unserialize

It doesn't fail *all* 5-digits years though (just mangles the data), see this output line (the number in square brackets is the timestamp, to aid with reproduction):

string(59) "[1099511627775] 36812-02-20 00:36:15 => 2002-02-20 00:36:15"
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Fri Sep 20 07:01:26 2019 UTC