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: 2022-07-22 14:38 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:1 (50.0%)
From: weirdan at gmail dot com Assigned: derick (profile)
Status: Closed Package: Date/time related
PHP Version: 7.1.8 OS: Debian Linux / sid
Private report: No CVE-ID: None
 [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"
 [2021-06-29 16:09 UTC] ganbayar dot gansukh at kellpro dot com
Experiencing same bug on 7.4.19
 [2022-07-22 14:38 UTC] derick@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: derick
 [2022-07-22 14:38 UTC] derick@php.net
The fix for this bug has been committed.
If you are still experiencing this bug, try to check out latest source from https://github.com/php/php-src and re-test.
Thank you for the report, and for helping us make PHP better.

https://github.com/php/php-src/commit/9dcb0bd1dc966a70cf6386ca9d49979dd417e0c5
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 05:01:29 2024 UTC