dmitry                                   Tue, 15 Jun 2010 08:22:51 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=300457

Log:
Fixed bug #52041 (Memory leak when writing on uninitialized variable returned 
from function)

Bug: http://bugs.php.net/52041 (Assigned) Memory leak when writing on 
uninitialized variable returned from function
      
Changed paths:
    U   php/php-src/branches/PHP_5_2/NEWS
    A   php/php-src/branches/PHP_5_2/Zend/tests/bug52041.phpt
    U   php/php-src/branches/PHP_5_2/Zend/zend_vm_def.h
    U   php/php-src/branches/PHP_5_2/Zend/zend_vm_execute.h
    U   php/php-src/branches/PHP_5_2/ext/soap/php_encoding.c
    A   php/php-src/branches/PHP_5_3/Zend/tests/bug52041.phpt
    U   php/php-src/branches/PHP_5_3/Zend/zend_vm_def.h
    U   php/php-src/branches/PHP_5_3/Zend/zend_vm_execute.h
    U   php/php-src/branches/PHP_5_3/ext/soap/php_encoding.c
    A   php/php-src/trunk/Zend/tests/bug52041.phpt
    U   php/php-src/trunk/Zend/zend_vm_def.h
    U   php/php-src/trunk/Zend/zend_vm_execute.h
    U   php/php-src/trunk/ext/soap/php_encoding.c

Modified: php/php-src/branches/PHP_5_2/NEWS
===================================================================
--- php/php-src/branches/PHP_5_2/NEWS	2010-06-15 08:19:26 UTC (rev 300456)
+++ php/php-src/branches/PHP_5_2/NEWS	2010-06-15 08:22:51 UTC (rev 300457)
@@ -18,6 +18,8 @@
 - Fixed a possible arbitrary memory access inside sqlite extension. Reported
   by Mateusz Kocielski. (Ilia)

+- Fixed bug #52041 (Memory leak when writing on uninitialized variable returned
+  from function). (Dmitry)
 - Fixed bug #52019 (make lcov doesn't support TESTS variable anymore). (Patrick)
 - Fixed bug #51911 (ReflectionParameter::getDefaultValue() memory leaks with
   constant array). (Felipe)

Added: php/php-src/branches/PHP_5_2/Zend/tests/bug52041.phpt
===================================================================
--- php/php-src/branches/PHP_5_2/Zend/tests/bug52041.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_2/Zend/tests/bug52041.phpt	2010-06-15 08:22:51 UTC (rev 300457)
@@ -0,0 +1,50 @@
+--TEST--
+Bug #52041 (Memory leak when writing on uninitialized variable returned from function)
+--FILE--
+<?php
+function foo() {
+	return $x;
+}
+
+foo()->a = 1;
+foo()->a->b = 2;
+foo()->a++;
+foo()->a->b++;
+foo()->a += 2;
+foo()->a->b += 2;
+
+//foo()[0] = 1;
+//foo()[0][0] = 2;
+//foo()[0]++;
+//foo()[0][0]++;
+//foo()[0] += 2;
+//foo()[0][0] += 2;
+var_dump(foo());
+?>
+--EXPECTF--
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 6
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 7
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 8
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 9
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 10
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 11
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+NULL

Modified: php/php-src/branches/PHP_5_2/Zend/zend_vm_def.h
===================================================================
--- php/php-src/branches/PHP_5_2/Zend/zend_vm_def.h	2010-06-15 08:19:26 UTC (rev 300456)
+++ php/php-src/branches/PHP_5_2/Zend/zend_vm_def.h	2010-06-15 08:22:51 UTC (rev 300457)
@@ -2192,6 +2192,12 @@
 				INIT_PZVAL_COPY(ret, retval_ptr);
 				zval_copy_ctor(ret);
 				*EG(return_value_ptr_ptr) = ret;
+			} else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
+			           retval_ptr == &EG(uninitialized_zval)) {
+				zval *ret;
+
+				ALLOC_INIT_ZVAL(ret);
+				*EG(return_value_ptr_ptr) = ret;
 			} else {
 				*EG(return_value_ptr_ptr) = retval_ptr;
 				retval_ptr->refcount++;

Modified: php/php-src/branches/PHP_5_2/Zend/zend_vm_execute.h
===================================================================
--- php/php-src/branches/PHP_5_2/Zend/zend_vm_execute.h	2010-06-15 08:19:26 UTC (rev 300456)
+++ php/php-src/branches/PHP_5_2/Zend/zend_vm_execute.h	2010-06-15 08:22:51 UTC (rev 300457)
@@ -1809,6 +1809,12 @@
 				INIT_PZVAL_COPY(ret, retval_ptr);
 				zval_copy_ctor(ret);
 				*EG(return_value_ptr_ptr) = ret;
+			} else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) &&
+			           retval_ptr == &EG(uninitialized_zval)) {
+				zval *ret;
+
+				ALLOC_INIT_ZVAL(ret);
+				*EG(return_value_ptr_ptr) = ret;
 			} else {
 				*EG(return_value_ptr_ptr) = retval_ptr;
 				retval_ptr->refcount++;
@@ -4385,6 +4391,12 @@
 				INIT_PZVAL_COPY(ret, retval_ptr);
 				zval_copy_ctor(ret);
 				*EG(return_value_ptr_ptr) = ret;
+			} else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) &&
+			           retval_ptr == &EG(uninitialized_zval)) {
+				zval *ret;
+
+				ALLOC_INIT_ZVAL(ret);
+				*EG(return_value_ptr_ptr) = ret;
 			} else {
 				*EG(return_value_ptr_ptr) = retval_ptr;
 				retval_ptr->refcount++;
@@ -7435,6 +7447,12 @@
 				INIT_PZVAL_COPY(ret, retval_ptr);
 				zval_copy_ctor(ret);
 				*EG(return_value_ptr_ptr) = ret;
+			} else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
+			           retval_ptr == &EG(uninitialized_zval)) {
+				zval *ret;
+
+				ALLOC_INIT_ZVAL(ret);
+				*EG(return_value_ptr_ptr) = ret;
 			} else {
 				*EG(return_value_ptr_ptr) = retval_ptr;
 				retval_ptr->refcount++;
@@ -19865,6 +19883,12 @@
 				INIT_PZVAL_COPY(ret, retval_ptr);
 				zval_copy_ctor(ret);
 				*EG(return_value_ptr_ptr) = ret;
+			} else if ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
+			           retval_ptr == &EG(uninitialized_zval)) {
+				zval *ret;
+
+				ALLOC_INIT_ZVAL(ret);
+				*EG(return_value_ptr_ptr) = ret;
 			} else {
 				*EG(return_value_ptr_ptr) = retval_ptr;
 				retval_ptr->refcount++;

Modified: php/php-src/branches/PHP_5_2/ext/soap/php_encoding.c
===================================================================
--- php/php-src/branches/PHP_5_2/ext/soap/php_encoding.c	2010-06-15 08:19:26 UTC (rev 300456)
+++ php/php-src/branches/PHP_5_2/ext/soap/php_encoding.c	2010-06-15 08:22:51 UTC (rev 300457)
@@ -1523,8 +1523,13 @@
 			}
 			model_to_zval_object(ret, sdlType->model, data, sdl TSRMLS_CC);
 			if (redo_any) {
-				if (get_zval_property(ret, "any" TSRMLS_CC) == NULL) {
+				zval *tmp = get_zval_property(ret, "any" TSRMLS_CC);
+
+				if (tmp == NULL) {
 					model_to_zval_any(ret, data->children TSRMLS_CC);
+				} else if (tmp->refcount == 0) {
+					zval_dtor(tmp);
+					efree(tmp);
 				}
 				zval_ptr_dtor(&redo_any);
 			}

Added: php/php-src/branches/PHP_5_3/Zend/tests/bug52041.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/tests/bug52041.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_3/Zend/tests/bug52041.phpt	2010-06-15 08:22:51 UTC (rev 300457)
@@ -0,0 +1,50 @@
+--TEST--
+Bug #52041 (Memory leak when writing on uninitialized variable returned from function)
+--FILE--
+<?php
+function foo() {
+	return $x;
+}
+
+foo()->a = 1;
+foo()->a->b = 2;
+foo()->a++;
+foo()->a->b++;
+foo()->a += 2;
+foo()->a->b += 2;
+
+//foo()[0] = 1;
+//foo()[0][0] = 2;
+//foo()[0]++;
+//foo()[0][0]++;
+//foo()[0] += 2;
+//foo()[0][0] += 2;
+var_dump(foo());
+?>
+--EXPECTF--
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 6
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 7
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 8
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 9
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 10
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 11
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+NULL

Modified: php/php-src/branches/PHP_5_3/Zend/zend_vm_def.h
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/zend_vm_def.h	2010-06-15 08:19:26 UTC (rev 300456)
+++ php/php-src/branches/PHP_5_3/Zend/zend_vm_def.h	2010-06-15 08:22:51 UTC (rev 300457)
@@ -2493,6 +2493,12 @@
 				INIT_PZVAL_COPY(ret, retval_ptr);
 				zval_copy_ctor(ret);
 				*EG(return_value_ptr_ptr) = ret;
+			} else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
+			           retval_ptr == &EG(uninitialized_zval)) {
+				zval *ret;
+
+				ALLOC_INIT_ZVAL(ret);
+				*EG(return_value_ptr_ptr) = ret;
 			} else {
 				*EG(return_value_ptr_ptr) = retval_ptr;
 				Z_ADDREF_P(retval_ptr);

Modified: php/php-src/branches/PHP_5_3/Zend/zend_vm_execute.h
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/zend_vm_execute.h	2010-06-15 08:19:26 UTC (rev 300456)
+++ php/php-src/branches/PHP_5_3/Zend/zend_vm_execute.h	2010-06-15 08:22:51 UTC (rev 300457)
@@ -1664,6 +1664,12 @@
 				INIT_PZVAL_COPY(ret, retval_ptr);
 				zval_copy_ctor(ret);
 				*EG(return_value_ptr_ptr) = ret;
+			} else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) &&
+			           retval_ptr == &EG(uninitialized_zval)) {
+				zval *ret;
+
+				ALLOC_INIT_ZVAL(ret);
+				*EG(return_value_ptr_ptr) = ret;
 			} else {
 				*EG(return_value_ptr_ptr) = retval_ptr;
 				Z_ADDREF_P(retval_ptr);
@@ -4931,6 +4937,12 @@
 				INIT_PZVAL_COPY(ret, retval_ptr);
 				zval_copy_ctor(ret);
 				*EG(return_value_ptr_ptr) = ret;
+			} else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) &&
+			           retval_ptr == &EG(uninitialized_zval)) {
+				zval *ret;
+
+				ALLOC_INIT_ZVAL(ret);
+				*EG(return_value_ptr_ptr) = ret;
 			} else {
 				*EG(return_value_ptr_ptr) = retval_ptr;
 				Z_ADDREF_P(retval_ptr);
@@ -8167,6 +8179,12 @@
 				INIT_PZVAL_COPY(ret, retval_ptr);
 				zval_copy_ctor(ret);
 				*EG(return_value_ptr_ptr) = ret;
+			} else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
+			           retval_ptr == &EG(uninitialized_zval)) {
+				zval *ret;
+
+				ALLOC_INIT_ZVAL(ret);
+				*EG(return_value_ptr_ptr) = ret;
 			} else {
 				*EG(return_value_ptr_ptr) = retval_ptr;
 				Z_ADDREF_P(retval_ptr);
@@ -22027,6 +22045,12 @@
 				INIT_PZVAL_COPY(ret, retval_ptr);
 				zval_copy_ctor(ret);
 				*EG(return_value_ptr_ptr) = ret;
+			} else if ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
+			           retval_ptr == &EG(uninitialized_zval)) {
+				zval *ret;
+
+				ALLOC_INIT_ZVAL(ret);
+				*EG(return_value_ptr_ptr) = ret;
 			} else {
 				*EG(return_value_ptr_ptr) = retval_ptr;
 				Z_ADDREF_P(retval_ptr);

Modified: php/php-src/branches/PHP_5_3/ext/soap/php_encoding.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/soap/php_encoding.c	2010-06-15 08:19:26 UTC (rev 300456)
+++ php/php-src/branches/PHP_5_3/ext/soap/php_encoding.c	2010-06-15 08:22:51 UTC (rev 300457)
@@ -1562,8 +1562,13 @@
 			}
 			model_to_zval_object(ret, sdlType->model, data, sdl TSRMLS_CC);
 			if (redo_any) {
-				if (get_zval_property(ret, "any" TSRMLS_CC) == NULL) {
+				zval *tmp = get_zval_property(ret, "any" TSRMLS_CC);
+
+				if (tmp == NULL) {
 					model_to_zval_any(ret, data->children TSRMLS_CC);
+				} else if (Z_REFCOUNT_P(tmp) == 0) {
+					zval_dtor(tmp);
+					efree(tmp);
 				}
 				zval_ptr_dtor(&redo_any);
 			}

Added: php/php-src/trunk/Zend/tests/bug52041.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/bug52041.phpt	                        (rev 0)
+++ php/php-src/trunk/Zend/tests/bug52041.phpt	2010-06-15 08:22:51 UTC (rev 300457)
@@ -0,0 +1,75 @@
+--TEST--
+Bug #52041 (Memory leak when writing on uninitialized variable returned from function)
+--FILE--
+<?php
+function foo() {
+	return $x;
+}
+
+foo()->a = 1;
+foo()->a->b = 2;
+foo()->a++;
+foo()->a->b++;
+foo()->a += 2;
+foo()->a->b += 2;
+
+foo()[0] = 1;
+foo()[0][0] = 2;
+foo()[0]++;
+foo()[0][0]++;
+foo()[0] += 2;
+foo()[0][0] += 2;
+
+var_dump(foo());
+?>
+--EXPECTF--
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 6
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 7
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 8
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 9
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 10
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 11
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Notice: Undefined variable: x in %stests/bug52041.php on line 3
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 15
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 16
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 16
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 17
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 18
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 18
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+NULL

Modified: php/php-src/trunk/Zend/zend_vm_def.h
===================================================================
--- php/php-src/trunk/Zend/zend_vm_def.h	2010-06-15 08:19:26 UTC (rev 300456)
+++ php/php-src/trunk/Zend/zend_vm_def.h	2010-06-15 08:22:51 UTC (rev 300457)
@@ -2781,6 +2781,12 @@
 			INIT_PZVAL_COPY(ret, retval_ptr);
 			zval_copy_ctor(ret);
 			*EG(return_value_ptr_ptr) = ret;
+		} else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
+		           retval_ptr == &EG(uninitialized_zval)) {
+			zval *ret;
+
+			ALLOC_INIT_ZVAL(ret);
+			*EG(return_value_ptr_ptr) = ret;
 		} else {
 			*EG(return_value_ptr_ptr) = retval_ptr;
 			Z_ADDREF_P(retval_ptr);

Modified: php/php-src/trunk/Zend/zend_vm_execute.h
===================================================================
--- php/php-src/trunk/Zend/zend_vm_execute.h	2010-06-15 08:19:26 UTC (rev 300456)
+++ php/php-src/trunk/Zend/zend_vm_execute.h	2010-06-15 08:22:51 UTC (rev 300457)
@@ -1742,6 +1742,12 @@
 			INIT_PZVAL_COPY(ret, retval_ptr);
 			zval_copy_ctor(ret);
 			*EG(return_value_ptr_ptr) = ret;
+		} else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) &&
+		           retval_ptr == &EG(uninitialized_zval)) {
+			zval *ret;
+
+			ALLOC_INIT_ZVAL(ret);
+			*EG(return_value_ptr_ptr) = ret;
 		} else {
 			*EG(return_value_ptr_ptr) = retval_ptr;
 			Z_ADDREF_P(retval_ptr);
@@ -6064,6 +6070,12 @@
 			INIT_PZVAL_COPY(ret, retval_ptr);
 			zval_copy_ctor(ret);
 			*EG(return_value_ptr_ptr) = ret;
+		} else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) &&
+		           retval_ptr == &EG(uninitialized_zval)) {
+			zval *ret;
+
+			ALLOC_INIT_ZVAL(ret);
+			*EG(return_value_ptr_ptr) = ret;
 		} else {
 			*EG(return_value_ptr_ptr) = retval_ptr;
 			Z_ADDREF_P(retval_ptr);
@@ -10288,6 +10300,12 @@
 			INIT_PZVAL_COPY(ret, retval_ptr);
 			zval_copy_ctor(ret);
 			*EG(return_value_ptr_ptr) = ret;
+		} else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
+		           retval_ptr == &EG(uninitialized_zval)) {
+			zval *ret;
+
+			ALLOC_INIT_ZVAL(ret);
+			*EG(return_value_ptr_ptr) = ret;
 		} else {
 			*EG(return_value_ptr_ptr) = retval_ptr;
 			Z_ADDREF_P(retval_ptr);
@@ -26267,6 +26285,12 @@
 			INIT_PZVAL_COPY(ret, retval_ptr);
 			zval_copy_ctor(ret);
 			*EG(return_value_ptr_ptr) = ret;
+		} else if ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
+		           retval_ptr == &EG(uninitialized_zval)) {
+			zval *ret;
+
+			ALLOC_INIT_ZVAL(ret);
+			*EG(return_value_ptr_ptr) = ret;
 		} else {
 			*EG(return_value_ptr_ptr) = retval_ptr;
 			Z_ADDREF_P(retval_ptr);

Modified: php/php-src/trunk/ext/soap/php_encoding.c
===================================================================
--- php/php-src/trunk/ext/soap/php_encoding.c	2010-06-15 08:19:26 UTC (rev 300456)
+++ php/php-src/trunk/ext/soap/php_encoding.c	2010-06-15 08:22:51 UTC (rev 300457)
@@ -1548,8 +1548,13 @@
 			}
 			model_to_zval_object(ret, sdlType->model, data, sdl TSRMLS_CC);
 			if (redo_any) {
-				if (get_zval_property(ret, "any" TSRMLS_CC) == NULL) {
+				zval *tmp = get_zval_property(ret, "any" TSRMLS_CC);
+
+				if (tmp == NULL) {
 					model_to_zval_any(ret, data->children TSRMLS_CC);
+				} else if (Z_REFCOUNT_P(tmp) == 0) {
+					zval_dtor(tmp);
+					efree(tmp);
 				}
 				zval_ptr_dtor(&redo_any);
 			}
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to