|
|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2012-08-18 11:53 UTC] kasper at webmasteren dot eu
Description:
------------
Core PHP,every version so far, 5.3.* and 5.4.*
When unserializing this string :
O:8:"DateTime":3:{s:4:"date";s:20:"10007-06-07
03:51:49";s:13:"timezone_type";i:3;s:8:"timezone";s:3:"UTC";}
created from: Datetime:createFromFormat("99-99-9999","j-n-Y");
then serialized, to a file. Later when read and working with, php crashes, from
the parse_tz.c, in timelib_get_time_zone_info. the Exception is "read at offset
0x00000010". it would appear that ts and / or tz is zero.
Test script:
---------------
$temp = unserialize('O:8:"DateTime":3:{s:4:"date";s:20:"10007-06-07 03:51:49";s:13:"timezone_type";i:3;s:8:"timezone";s:3:"UTC";}');
var_dump($temp);
Expected result:
----------------
error parsing invalid date or just a date with all entries 0.
Actual result:
--------------
php crash [read offset 0x00000010] ~ null pointer + offset. at the file
"ext\date\lib\parse_tz.c"
PatchesFix-add-exception-checking (last revision 2012-09-16 02:18 UTC by reeze@php.net)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||
|
All rights reserved. |
Last updated: Thu Nov 06 23:00:02 2025 UTC |
I'm getting an error since this bug was "fixed". In one of my databases, a DateTime object was inadvertently serialized as a child object. Now, with this bug fix, I'm getting the following error. The serialized object is represented by this short string: O:8:"DateTime":0:{} Running that through unserialize presents this error: "Invalid serialization data for DateTime object" I'm unable to catch this error and handle it gracefully (ie. ignoring this object unserialization entirely).My [ugly] workaround for this problem is to manually replace instances of serialized DateTime objects with a fake, non-existent class name, which avoids this crash. $str = 'O:8:"DateTime":0:{}'; $str = str_replace('O:8:"DateTime"', 'O:12:"PHP_DateTime"', $str); Of course, if the serialized data needed to be recovered, an alternate approach would be needed. In my own case, I want to be discarding this object. I'm hoping this issue that ran into is an unforeseen issue with this latest bug fix, and a proper fix can be made in a future update. I don't like adding in workarounds. :-)I'm also still getting this with empty DateTime object in session data O:8:"DateTime":0:{}.We've been seeing the same thing in production. It's been tough to trace down exactly how to reproduce it, so we ended up patching php_memcached.c so that these sorts of things don't get saved into memcache (we also had to do a similar filter for session saving as the serialization happens in a different place): Diff is below: --- php_memcached.c 2014-02-05 16:00:37.000000000 -0800 +++ memcached_master_02_05_2014/php_memcached.c 2014-02-06 11:01:27.000000000 -0800 @@ -3193,6 +3193,44 @@ php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not serialize value"); return 0; } + + const char * const cmp = "\"DateTime\":0:{}"; + const size_t cmplen = 15; + if (buf->len >= cmplen) + { + size_t len = buf->len - cmplen; + char *c = buf->c; + size_t i = 0; + while(i <= len) + { + if (*c == *cmp) { + char *cmp1 = cmp + 1; + + // Run the comparison + while (*cmp1) { + c++; + i++; + if (*c != *cmp1) + { + break; + } + cmp1++; + } + + // match + if (!*cmp1) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not serialize DateTime value"); + return 0; + } + } + else + { + c++; + i++; + } + } + } MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_SERIALIZED); } break;I believe this issue is still happening in 5.5.5. After looking at the code, I suspect that a new DateTime(null); breaks, but the almost equivalent 'new DateTime("now");' passes.I still get this in PHP 5.6.12. The fatal error can't be caught or suppressed in any way: *** Code *** $x = 'O:8:"DateTime":0:{}'; function exception_error_handler($errno, $errstr, $errfile, $errline ) { echo "how interesting!\n"; } set_error_handler("exception_error_handler"); try { $y = unserialize($x); } catch (Exception $e) { var_dump($e); } *** Result *** Fatal error: Invalid serialization data for DateTime object in - on line 12 Call Stack: 16.9971 235224 1. {main}() -:0 16.9971 235456 2. unserialize() -:12 16.9971 243928 3. DateTime->__wakeup() -:12