php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #53502 strtotime with timezone memory leak
Submitted: 2010-12-08 21:04 UTC Modified: 2011-12-06 06:21 UTC
Votes:14
Avg. Score:4.9 ± 0.3
Reproduced:14 of 14 (100.0%)
Same Version:7 (50.0%)
Same OS:6 (42.9%)
From: jsheridan at tenable dot com Assigned: derick (profile)
Status: Closed Package: Date/time related
PHP Version: 5.3.3 OS: Redhat ES5
Private report: No CVE-ID: None
 [2010-12-08 21:04 UTC] jsheridan at tenable dot com
Description:
------------
strtotime calls with a timezone embedded function correctly but continually use up 
memory. In a daemon program this becomes quickly fatal.


Test script:
---------------
<?php
while (true) {
    strtotime('Monday 00:00 Europe/Paris');    // Memory leak
}
?>

<?php
while (true) {
    date_default_timezone_set("Europe/Paris");
    strtotime('Monday 00:00');    // No memory leak
}
?>

Expected result:
----------------
Memory usage should remain stable.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-12-08 21:05 UTC] jsheridan at tenable dot com
This was found on a 5.3.2 system but verified against a fresh built 5.3.3 with no 
additions.
 [2010-12-09 04:09 UTC] aharvey@php.net
-Status: Open +Status: Verified -Package: Reproducible crash +Package: Date/time related
 [2010-12-09 04:09 UTC] aharvey@php.net
Verified. I don't have time to look into this further today (or
likely this week), but valgrind on a current 5.3 build shows a loss
record demonstrating this:

==19168== 130,800 (11,200 direct, 119,600 indirect) bytes in 100 blocks are 
definitely lost in loss record 28 of 28
==19168==    at 0x4C27480: calloc (vg_replace_malloc.c:467)
==19168==    by 0x471A5F: timelib_tzinfo_ctor (timelib.c:108)
==19168==    by 0x471317: timelib_parse_tzfile (parse_tz.c:318)
==19168==    by 0x442F99: timelib_get_zone (parse_date.re:807)
==19168==    by 0x444520: scan (parse_date.re:1641)
==19168==    by 0x46ED0E: timelib_strtotime (parse_date.re:1795)
==19168==    by 0x435879: zif_strtotime (php_date.c:1427)
==19168==    by 0x9E5022: execute_internal (zend_execute.c:1261)
==19168==    by 0xBEA2D38: xdebug_execute_internal (xdebug.c:1335)
==19168==    by 0x9E6057: zend_do_fcall_common_helper_SPEC 
(zend_vm_execute.h:318)
==19168==    by 0x9EA9A7: ZEND_DO_FCALL_SPEC_CONST_HANDLER 
(zend_vm_execute.h:1606)
==19168==    by 0x9E53E1: execute (zend_vm_execute.h:107)
 [2010-12-12 10:33 UTC] cataphract@php.net
-Assigned To: +Assigned To: derick
 [2010-12-12 10:33 UTC] cataphract@php.net
Timezone identifier parsing initiated by the timelib is not tracked by the caching mechanism of php_date_parse_tzfile and ends up leaked.

The illustrate this, running php -d date.timezone="Europe/Lisbon" -r "echo strtotime('Monday 00:00 Europe/Paris');"

gives these distinct backtraces in one of the functions were leaked memory is allocated:

#0  read_transistions (tzf=0x7fff5facace0, tz=0x7fbbace67fe8)
    at /home/glopes/php/php-trunk/ext/date/lib/parse_tz.c:86
#1  0x0000000000459563 in timelib_parse_tzfile (
    timezone=0x27f7ee0 "Europe/Lisbon", tzdb=0x8558a0)
    at /home/glopes/php/php-trunk/ext/date/lib/parse_tz.c:322
#2  0x00000000004215ef in php_date_parse_tzfile (
    formal_tzname=0x27f7ee0 "Europe/Lisbon", tzdb=0x8558a0)
    at /home/glopes/php/php-trunk/ext/date/php_date.c:829
#3  0x0000000000421923 in get_timezone_info ()
    at /home/glopes/php/php-trunk/ext/date/php_date.c:939
#4  0x0000000000423ed8 in zif_strtotime (ht=1, return_value=0x7fbbace65e40,
    return_value_ptr=0x0, this_ptr=0x0, return_value_used=1)
    at /home/glopes/php/php-trunk/ext/date/php_date.c:1396


#0  read_transistions (tzf=0x7fff5facab10, tz=0x7fbbace68858)
    at /home/glopes/php/php-trunk/ext/date/lib/parse_tz.c:86
#1  0x0000000000459563 in timelib_parse_tzfile (
    timezone=0x7fbbace687f0 "Europe/Paris", tzdb=0x8558a0)
    at /home/glopes/php/php-trunk/ext/date/lib/parse_tz.c:322
#2  0x0000000000431c37 in timelib_get_zone (ptr=0x7fff5facac40,
    dst=0x7fbbace685d8, t=0x7fbbace68588, tz_not_found=0x7fff5facac3c,
    tzdb=0x8558a0) at /home/glopes/php/php-trunk/ext/date/lib/parse_date.c:808
#3  0x0000000000431f90 in scan (s=0x7fff5facad00)
    at /home/glopes/php/php-trunk/ext/date/lib/parse_date.c:1009
#4  0x0000000000456f07 in timelib_strtotime (
    s=0x7fbba90ed708 "Monday 00:00 Europe/Paris", len=25,
    errors=0x7fff5facadd8, tzdb=0x8558a0)
    at /home/glopes/php/php-trunk/ext/date/lib/parse_date.c:24690
#5  0x00000000004240f9 in zif_strtotime (ht=1, return_value=0x7fbbace65e40,
    return_value_ptr=0x0, this_ptr=0x0, return_value_used=1)
    at /home/glopes/php/php-trunk/ext/date/php_date.c:1426
 [2010-12-12 18:01 UTC] derick@php.net
Hmm, I suspected this would be the issue. It's going to be a bit tricky to solve.
 [2011-04-08 21:52 UTC] jstephens at qualtrics dot com
I can also reproduce it with:

for($i=0;$i<100000;++$i) {
	new DateTime('UTC');
}
 [2011-04-08 21:53 UTC] dr dot ductus at gmail dot com
This just took our entire production environment to its knees. This, even in a 
non-daemon program, can be quickly fatal with enough requests.
 [2011-12-06 06:20 UTC] derick@php.net
Automatic comment from SVN on behalf of derick
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=320481
Log: - Fixed bug #53502 (strtotime with timezone memory leak).
- Fixed bug #52062 (large timestamps with DateTime::getTimestamp and
  DateTime::setTimestamp).
- Fixed bug #51994 (date_parse_from_format is parsing invalid date using 'yz'
  format).
- Fixed bug #51223 (Seg fault while creating (by unserialization)
  DatePeriod).
 [2011-12-06 06:21 UTC] derick@php.net
-Status: Verified +Status: Closed
 [2011-12-06 06:21 UTC] derick@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2012-04-18 09:47 UTC] laruence@php.net
Automatic comment on behalf of derick
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4c9fad8b362a7d2b6a94b4961e4b2dc037b2766d
Log: - Fixed bug #53502 (strtotime with timezone memory leak). - Fixed bug #52062 (large timestamps with DateTime::getTimestamp and   DateTime::setTimestamp). - Fixed bug #51994 (date_parse_from_format is parsing invalid date using 'yz'   format). - Fixed bug #51223 (Seg fault while creating (by unserialization)   DatePeriod).
 [2012-07-24 23:38 UTC] rasmus@php.net
Automatic comment on behalf of derick
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4c9fad8b362a7d2b6a94b4961e4b2dc037b2766d
Log: - Fixed bug #53502 (strtotime with timezone memory leak). - Fixed bug #52062 (large timestamps with DateTime::getTimestamp and   DateTime::setTimestamp). - Fixed bug #51994 (date_parse_from_format is parsing invalid date using 'yz'   format). - Fixed bug #51223 (Seg fault while creating (by unserialization)   DatePeriod).
 [2013-11-17 09:34 UTC] laruence@php.net
Automatic comment on behalf of derick
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4c9fad8b362a7d2b6a94b4961e4b2dc037b2766d
Log: - Fixed bug #53502 (strtotime with timezone memory leak). - Fixed bug #52062 (large timestamps with DateTime::getTimestamp and   DateTime::setTimestamp). - Fixed bug #51994 (date_parse_from_format is parsing invalid date using 'yz'   format). - Fixed bug #51223 (Seg fault while creating (by unserialization)   DatePeriod).
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 05:01:29 2024 UTC