summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoriyoshi Koizumi <moriyoshi@php.net>2003-10-26 16:10:07 +0000
committerMoriyoshi Koizumi <moriyoshi@php.net>2003-10-26 16:10:07 +0000
commitf22b3a19cff7950cc92c7b56e342f9a64629cb54 (patch)
treee96db32a83bfec25994725d4226af7324de0d452
parent78f795af8085557a5dcaefcddf5fac2d88c5577b (diff)
downloadphp-git-f22b3a19cff7950cc92c7b56e342f9a64629cb54.tar.gz
Prevent leaks in the overload extension that occur in some special cases.
-rw-r--r--ext/overload/overload.c9
-rw-r--r--tests/lang/overload_leak.phpt27
2 files changed, 30 insertions, 6 deletions
diff --git a/ext/overload/overload.c b/ext/overload/overload.c
index ebd38a9b79..343ecfe81f 100644
--- a/ext/overload/overload.c
+++ b/ext/overload/overload.c
@@ -580,18 +580,16 @@ static void overload_call_method(INTERNAL_FUNCTION_PARAMETERS, zend_property_ref
}
if (zval_is_true(retval)) {
- *return_value = *result_ptr;
- INIT_PZVAL(return_value);
+ REPLACE_ZVAL_VALUE(&return_value, result_ptr, 1);
} else {
zval_dtor(result_ptr);
php_error(E_WARNING, "Call to undefined method %s::%s()", Z_OBJCE_P(object)->name, Z_STRVAL(method_name));
}
zval_ptr_dtor(&retval);
} else {
- ZVAL_STRINGL(&call_handler, Z_STRVAL(method->element), Z_STRLEN(method->element), 0);
call_result = call_user_function_ex(NULL,
&object,
- &call_handler,
+ &method->element,
&retval,
ZEND_NUM_ARGS(), args,
0, NULL TSRMLS_CC);
@@ -602,8 +600,7 @@ static void overload_call_method(INTERNAL_FUNCTION_PARAMETERS, zend_property_ref
return;
}
- *return_value = *retval;
- zval_copy_ctor(return_value);
+ REPLACE_ZVAL_VALUE(&return_value, retval, 1);
zval_ptr_dtor(&retval);
}
diff --git a/tests/lang/overload_leak.phpt b/tests/lang/overload_leak.phpt
new file mode 100644
index 0000000000..fbe51573a6
--- /dev/null
+++ b/tests/lang/overload_leak.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Memory leaks occur within an overloaded method that returns a reference
+--FILE--
+<?php
+class foo {
+ function foo() {
+ }
+ function __call($m, $a, &$r) {
+ return true;
+ }
+ function &bar() {
+ global $g;
+ var_dump($g);
+ return $g;
+ }
+}
+
+$g = 456;
+
+overload('foo');
+
+$a = new foo();
+var_dump($a->bar());
+?>
+--EXPECT--
+int(456)
+int(456)