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:
@@ -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
|
||||
Referência em uma Nova Issue
Bloquear um usuário