stas                                     Tue, 18 Aug 2009 20:51:49 +0000

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

Log:
fix crash when unexpectedly passed by-ref parameter is modified

Changed paths:
    A   php/php-src/branches/PHP_5_2/Zend/tests/unexpected_ref_bug.phpt
    U   php/php-src/branches/PHP_5_2/Zend/zend_execute_API.c
    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
    A   
php/php-src/branches/PHP_5_2/ext/standard/tests/array/unexpected_array_mod_bug.phpt
    A   php/php-src/branches/PHP_5_3/Zend/tests/unexpected_ref_bug.phpt
    U   php/php-src/branches/PHP_5_3/Zend/zend_execute_API.c
    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
    A   
php/php-src/branches/PHP_5_3/ext/standard/tests/array/unexpected_array_mod_bug.phpt
    A   php/php-src/trunk/Zend/tests/unexpected_ref_bug.phpt
    U   php/php-src/trunk/Zend/zend_execute_API.c
    U   php/php-src/trunk/Zend/zend_vm_def.h
    U   php/php-src/trunk/Zend/zend_vm_execute.h

Added: php/php-src/branches/PHP_5_2/Zend/tests/unexpected_ref_bug.phpt
===================================================================
--- php/php-src/branches/PHP_5_2/Zend/tests/unexpected_ref_bug.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_2/Zend/tests/unexpected_ref_bug.phpt	2009-08-18 20:51:49 UTC (rev 287466)
@@ -0,0 +1,18 @@
+--TEST--
+Crash when function parameter modified via unexpected reference
+--FILE--
+<?php
+function my_errorhandler($errno,$errormsg) {
+  global $my_var;
+  $my_var = 0;
+  return true;
+}
+set_error_handler("my_errorhandler");
+$my_var = str_repeat("A",64);
+$data = call_user_func_array("explode",array(new StdClass(), &$my_var));
+$my_var=array(1,2,3);
+$data = call_user_func_array("implode",array(&$my_var, new StdClass()));
+echo "Done.\n";
+?>
+--EXPECTF--
+Done.


Property changes on: php/php-src/branches/PHP_5_2/Zend/tests/unexpected_ref_bug.phpt
___________________________________________________________________
Added: svn:executable
   + *

Modified: php/php-src/branches/PHP_5_2/Zend/zend_execute_API.c
===================================================================
--- php/php-src/branches/PHP_5_2/Zend/zend_execute_API.c	2009-08-18 20:49:39 UTC (rev 287465)
+++ php/php-src/branches/PHP_5_2/Zend/zend_execute_API.c	2009-08-18 20:51:49 UTC (rev 287466)
@@ -921,6 +921,12 @@
 	for (i=0; i<fci->param_count; i++) {
 		zval *param;

+		if(EX(function_state).function->type == ZEND_INTERNAL_FUNCTION
+			&& !ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
+			&& PZVAL_IS_REF(*fci->params[i])) {
+			SEPARATE_ZVAL(fci->params[i]);
+		}
+
 		if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i+1)
 			&& !PZVAL_IS_REF(*fci->params[i])) {
 			if ((*fci->params[i])->refcount>1) {

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	2009-08-18 20:49:39 UTC (rev 287465)
+++ php/php-src/branches/PHP_5_2/Zend/zend_vm_def.h	2009-08-18 20:51:49 UTC (rev 287466)
@@ -2371,6 +2371,10 @@
 		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
 	}

+      	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+               ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
+        }
+
 	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
 	varptr = *varptr_ptr;
 	varptr->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	2009-08-18 20:49:39 UTC (rev 287465)
+++ php/php-src/branches/PHP_5_2/Zend/zend_vm_execute.h	2009-08-18 20:51:49 UTC (rev 287466)
@@ -7584,6 +7584,10 @@
 		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
 	}

+      	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+               return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+
 	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
 	varptr = *varptr_ptr;
 	varptr->refcount++;
@@ -20009,6 +20013,10 @@
 		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
 	}

+      	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+               return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+
 	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
 	varptr = *varptr_ptr;
 	varptr->refcount++;

Added: php/php-src/branches/PHP_5_2/ext/standard/tests/array/unexpected_array_mod_bug.phpt
===================================================================
--- php/php-src/branches/PHP_5_2/ext/standard/tests/array/unexpected_array_mod_bug.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_2/ext/standard/tests/array/unexpected_array_mod_bug.phpt	2009-08-18 20:51:49 UTC (rev 287466)
@@ -0,0 +1,21 @@
+--TEST--
+Crash when function parameter modified via reference
+--FILE--
+<?php
+function usercompare($a,$b) {
+  unset($GLOBALS['my_var'][2]);
+  return 0;
+}
+$my_var = array(1 => "entry_1",
+2 => "entry_2",
+3 => "entry_3",
+4 => "entry_4",
+5 => "entry_5");
+usort($my_var, "usercompare");
+
+echo "Done.\n";
+?>
+--EXPECTF--
+
+Warning: usort(): Array was modified by the user comparison function in %s on line %d
+Done.


Property changes on: php/php-src/branches/PHP_5_2/ext/standard/tests/array/unexpected_array_mod_bug.phpt
___________________________________________________________________
Added: svn:executable
   + *

Added: php/php-src/branches/PHP_5_3/Zend/tests/unexpected_ref_bug.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/tests/unexpected_ref_bug.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_3/Zend/tests/unexpected_ref_bug.phpt	2009-08-18 20:51:49 UTC (rev 287466)
@@ -0,0 +1,18 @@
+--TEST--
+Crash when function parameter modified via unexpected reference
+--FILE--
+<?php
+function my_errorhandler($errno,$errormsg) {
+  global $my_var;
+  $my_var = 0;
+  return true;
+}
+set_error_handler("my_errorhandler");
+$my_var = str_repeat("A",64);
+$data = call_user_func_array("explode",array(new StdClass(), &$my_var));
+$my_var=array(1,2,3);
+$data = call_user_func_array("implode",array(&$my_var, new StdClass()));
+echo "Done.\n";
+?>
+--EXPECTF--
+Done.


Property changes on: php/php-src/branches/PHP_5_3/Zend/tests/unexpected_ref_bug.phpt
___________________________________________________________________
Added: svn:executable
   + *

Modified: php/php-src/branches/PHP_5_3/Zend/zend_execute_API.c
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/zend_execute_API.c	2009-08-18 20:49:39 UTC (rev 287465)
+++ php/php-src/branches/PHP_5_3/Zend/zend_execute_API.c	2009-08-18 20:51:49 UTC (rev 287466)
@@ -837,6 +837,12 @@
 	for (i=0; i<fci->param_count; i++) {
 		zval *param;

+        	if(EX(function_state).function->type == ZEND_INTERNAL_FUNCTION
+			&& !ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
+			&& PZVAL_IS_REF(*fci->params[i])) {
+			SEPARATE_ZVAL(fci->params[i]);
+		}
+
 		if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
 			&& !PZVAL_IS_REF(*fci->params[i])) {


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	2009-08-18 20:49:39 UTC (rev 287465)
+++ php/php-src/branches/PHP_5_3/Zend/zend_vm_def.h	2009-08-18 20:51:49 UTC (rev 287466)
@@ -2686,6 +2686,10 @@
 		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
 	}

+      	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+               ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
+        }
+
 	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
 	varptr = *varptr_ptr;
 	Z_ADDREF_P(varptr);

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	2009-08-18 20:49:39 UTC (rev 287465)
+++ php/php-src/branches/PHP_5_3/Zend/zend_vm_execute.h	2009-08-18 20:51:49 UTC (rev 287466)
@@ -8316,6 +8316,10 @@
 		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
 	}

+      	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+               return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+
 	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
 	varptr = *varptr_ptr;
 	Z_ADDREF_P(varptr);
@@ -22173,6 +22177,10 @@
 		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
 	}

+      	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+               return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+
 	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
 	varptr = *varptr_ptr;
 	Z_ADDREF_P(varptr);

Added: php/php-src/branches/PHP_5_3/ext/standard/tests/array/unexpected_array_mod_bug.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/standard/tests/array/unexpected_array_mod_bug.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_3/ext/standard/tests/array/unexpected_array_mod_bug.phpt	2009-08-18 20:51:49 UTC (rev 287466)
@@ -0,0 +1,21 @@
+--TEST--
+Crash when function parameter modified via reference
+--FILE--
+<?php
+function usercompare($a,$b) {
+  unset($GLOBALS['my_var'][2]);
+  return 0;
+}
+$my_var = array(1 => "entry_1",
+2 => "entry_2",
+3 => "entry_3",
+4 => "entry_4",
+5 => "entry_5");
+usort($my_var, "usercompare");
+
+echo "Done.\n";
+?>
+--EXPECTF--
+
+Warning: usort(): Array was modified by the user comparison function in %s on line %d
+Done.


Property changes on: php/php-src/branches/PHP_5_3/ext/standard/tests/array/unexpected_array_mod_bug.phpt
___________________________________________________________________
Added: svn:executable
   + *

Added: php/php-src/trunk/Zend/tests/unexpected_ref_bug.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/unexpected_ref_bug.phpt	                        (rev 0)
+++ php/php-src/trunk/Zend/tests/unexpected_ref_bug.phpt	2009-08-18 20:51:49 UTC (rev 287466)
@@ -0,0 +1,18 @@
+--TEST--
+Crash when function parameter modified via unexpected reference
+--FILE--
+<?php
+function my_errorhandler($errno,$errormsg) {
+  global $my_var;
+  $my_var = 0;
+  return true;
+}
+set_error_handler("my_errorhandler");
+$my_var = str_repeat("A",64);
+$data = call_user_func_array("explode",array(new StdClass(), &$my_var));
+$my_var=array(1,2,3);
+$data = call_user_func_array("implode",array(&$my_var, new StdClass()));
+echo "Done.\n";
+?>
+--EXPECTF--
+Done.


Property changes on: php/php-src/trunk/Zend/tests/unexpected_ref_bug.phpt
___________________________________________________________________
Added: svn:executable
   + *

Modified: php/php-src/trunk/Zend/zend_execute_API.c
===================================================================
--- php/php-src/trunk/Zend/zend_execute_API.c	2009-08-18 20:49:39 UTC (rev 287465)
+++ php/php-src/trunk/Zend/zend_execute_API.c	2009-08-18 20:51:49 UTC (rev 287466)
@@ -872,6 +872,12 @@
 	for (i=0; i<fci->param_count; i++) {
 		zval *param;

+        	if(EX(function_state).function->type == ZEND_INTERNAL_FUNCTION
+			&& !ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
+			&& PZVAL_IS_REF(*fci->params[i])) {
+			SEPARATE_ZVAL(fci->params[i]);
+		}
+
 		if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
 			&& !PZVAL_IS_REF(*fci->params[i])) {
 			if (Z_REFCOUNT_PP(fci->params[i]) > 1) {

Modified: php/php-src/trunk/Zend/zend_vm_def.h
===================================================================
--- php/php-src/trunk/Zend/zend_vm_def.h	2009-08-18 20:49:39 UTC (rev 287465)
+++ php/php-src/trunk/Zend/zend_vm_def.h	2009-08-18 20:51:49 UTC (rev 287466)
@@ -2776,6 +2776,10 @@
 		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
 	}

+      	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+               ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
+        }
+
 	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
 	varptr = *varptr_ptr;
 	Z_ADDREF_P(varptr);

Modified: php/php-src/trunk/Zend/zend_vm_execute.h
===================================================================
--- php/php-src/trunk/Zend/zend_vm_execute.h	2009-08-18 20:49:39 UTC (rev 287465)
+++ php/php-src/trunk/Zend/zend_vm_execute.h	2009-08-18 20:51:49 UTC (rev 287466)
@@ -8618,6 +8618,10 @@
 		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
 	}

+      	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+               return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+
 	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
 	varptr = *varptr_ptr;
 	Z_ADDREF_P(varptr);
@@ -23163,6 +23167,10 @@
 		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
 	}

+      	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+               return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+
 	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
 	varptr = *varptr_ptr;
 	Z_ADDREF_P(varptr);
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to