Fix a DateTime leak

D860568 fixed a double free, but introduced a leak. If no
timezone is specified in the input string, timelib_fill_holes
would clone the one from m_time. Since we unconditionally cloned
*that* into m_tz, the clone from timelib_fill_holes was leaked.

The contract seems to be that m_time doesn't own it's tz_info, but
that it should be owned by a smart pointer somewhere. So we can tell
timelib_fill_holes *not* to clone the tz_info from its second parameter,
and at the same time optimize for the usual case where that timezone
is already the current timezone.
Esse commit está contido em:
mwilliams
2013-07-06 10:11:05 -07:00
commit de Sara Golemon
commit bc5778169e
3 arquivos alterados com 39 adições e 3 exclusões
+5 -3
Ver Arquivo
@@ -764,19 +764,21 @@ bool DateTime::fromString(CStrRef input, SmartObject<TimeZone> tz,
}
// needed if any date part is missing
timelib_fill_holes(t, m_time.get(), 0);
timelib_fill_holes(t, m_time.get(), TIMELIB_NO_CLONE);
timelib_update_ts(t, m_tz->get());
int error2;
m_timestamp = timelib_date_to_int(t, &error2);
if (error1 || error2) {
timelib_tzinfo_dtor(t->tz_info);
// Don't free t->tz_info, it belongs to GetTimeZoneInfo
timelib_time_dtor(t);
return false;
}
m_time = TimePtr(t, time_deleter());
m_tz = NEWOBJ(TimeZone)(timelib_tzinfo_clone(t->tz_info));
if (t->tz_info != m_tz->get()) {
m_tz = NEWOBJ(TimeZone)(timelib_tzinfo_clone(t->tz_info));
}
return true;
}
@@ -0,0 +1,31 @@
<?php ;
error_reporting(0);
function test() {
for ($i = 0; $i < 10000; $i++) {
strtotime("10 September 2000");
strtotime("10 September 2000 UTC");
strtotime("null");
}
}
function main() {
$a = memory_get_usage(true);
test();
$b = memory_get_usage(true);
test();
$c = memory_get_usage(true);
$v1 = $b - $a;
$v2 = ($c - $b) * 10;
if ($v2 <= $v1) {
echo "Ok\n";
} else {
echo "strtotime is leaking: $a, $b, $c\n";
}
}
var_dump(strtotime("10 September 2000 UTC"));
var_dump(strtotime("null"));
main();
@@ -0,0 +1,3 @@
int(968544000)
bool(false)
Ok