Browse Source

- MFH: Fix #43450 (Memory leak on some functions with implicit object

__toString() call) (Davic C.)
PECL
Johannes Schlüter 19 years ago
parent
commit
1b6100f4c1
  1. 35
      Zend/tests/bug43450.phpt
  2. 14
      Zend/zend_object_handlers.c

35
Zend/tests/bug43450.phpt

@ -0,0 +1,35 @@
--TEST--
Bug #43450 (Memory leak on some functions with implicit object __toString() call)
--SKIPIF--
<?php if (!function_exists('memory_get_usage')) die('memory_get_usage() not installed'); ?>
--FILE--
<?php
error_reporting(E_ALL|E_STRICT);
class Foo
{
public function __toString()
{
return __CLASS__;
}
}
$num_repeats = 100000;
$start = (memory_get_usage() / 1024) + 16;
for ($i=1;$i<$num_repeats;$i++)
{
$foo = new Foo();
md5($foo);
}
$end = memory_get_peak_usage() / 1024;
if ($start < $end) {
echo 'FAIL';
} else {
echo 'PASS';
}
?>
--EXPECT--
PASS

14
Zend/zend_object_handlers.c

@ -1191,6 +1191,9 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
}
if (Z_TYPE_P(retval) == IS_STRING) {
INIT_PZVAL(writeobj);
if (readobj == writeobj) {
zval_dtor(readobj);
}
ZVAL_ZVAL(writeobj, retval, 1, 1);
if (Z_TYPE_P(writeobj) != type) {
convert_to_explicit_type(writeobj, type);
@ -1199,6 +1202,9 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
} else {
zval_ptr_dtor(&retval);
INIT_PZVAL(writeobj);
if (readobj == writeobj) {
zval_dtor(readobj);
}
ZVAL_EMPTY_STRING(writeobj);
zend_error(E_RECOVERABLE_ERROR, "Method %s::__toString() must return a string value", ce->name);
return SUCCESS;
@ -1213,15 +1219,23 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
ce = Z_OBJCE_P(readobj);
zend_error(E_NOTICE, "Object of class %s could not be converted to int", ce->name);
INIT_PZVAL(writeobj);
if (readobj == writeobj) {
zval_dtor(readobj);
}
ZVAL_LONG(writeobj, 1);
return SUCCESS;
case IS_DOUBLE:
ce = Z_OBJCE_P(readobj);
zend_error(E_NOTICE, "Object of class %s could not be converted to double", ce->name);
INIT_PZVAL(writeobj);
if (readobj == writeobj) {
zval_dtor(readobj);
}
ZVAL_DOUBLE(writeobj, 1);
return SUCCESS;
default:
INIT_PZVAL(writeobj);
Z_TYPE_P(writeobj) = IS_NULL;
break;
}
return FAILURE;

Loading…
Cancel
Save