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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: jsheridan at tenable dot com
New email:
PHP Version: OS:

 

 [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

Pull Requests

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: Sat Dec 21 14:01:32 2024 UTC