]> granicus.if.org Git - php/commitdiff
Fixed bug #54305 (Crash in gc_remove_zval_from_buffer)
authorDmitry Stogov <dmitry@php.net>
Mon, 11 Jul 2011 10:31:49 +0000 (10:31 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 11 Jul 2011 10:31:49 +0000 (10:31 +0000)
NEWS
Zend/tests/bug54305.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index b8698162ba05236b3d09e0d3bda70bef496b9c1e..6f1f63a08c927df58b6670604fb315d3fd8c4aa5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ PHP                                                                        NEWS
 
 - Core
   . Fixed bug #54332 (Crash in zend_mm_check_ptr // Heap corruption). (Dmitry)
+  . Fixed bug #54305 (Crash in gc_remove_zval_from_buffer). (Dmitry)
   . Fixed bug #53727 (Inconsistent behavior of is_subclass_of with interfaces)
     (Ralph Schindler, Dmitry)
   . Fixed buffer overflow on overlog salt in crypt(). (ClĂ©ment LECIGNE, Stas)
diff --git a/Zend/tests/bug54305.phpt b/Zend/tests/bug54305.phpt
new file mode 100644 (file)
index 0000000..8e85d2b
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+Bug #54305 (Crash in gc_remove_zval_from_buffer)
+--FILE--
+<?php
+class TestClass {
+    public function methodWithArgs($a, $b) {
+    }
+}
+abstract class AbstractClass {
+}
+$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs');
+echo $methodWithArgs++;
+?>
+--EXPECTF--
+Method [ <user> public method methodWithArgs ] {
+  @@ %sbug54305.php %d - %d
+
+  - Parameters [2] {
+    Parameter #0 [ <required> $a ]
+    Parameter #1 [ <required> $b ]
+  }
+}
index 47b65fbbe8567f506576141c521742185042fb67..05495adc359564ff06a7eeef5f12cc87049d8d54 100644 (file)
@@ -900,10 +900,16 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY)
        zval *z = GET_OP1_ZVAL_PTR(BP_VAR_R);
 
        if (OP1_TYPE != IS_CONST &&
-           Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
-               zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
-               zend_print_variable(&z_copy);
-               zval_dtor(&z_copy);
+           Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL) {
+           if (OP1_TYPE == IS_TMP_VAR) {
+               INIT_PZVAL(z);
+           }
+               if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+                       zend_print_variable(&z_copy);
+                       zval_dtor(&z_copy);
+               } else {
+                       zend_print_variable(z);
+               }
        } else {
                zend_print_variable(z);
        }
index 7ebde2f09246fc44cb8a44969a0537a1fd3ad77b..3892c8a9e9259b5f128a40cf983ec9d086af0c9c 100644 (file)
@@ -1324,10 +1324,16 @@ static int ZEND_FASTCALL  ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval *z = &opline->op1.u.constant;
 
        if (IS_CONST != IS_CONST &&
-           Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
-               zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
-               zend_print_variable(&z_copy);
-               zval_dtor(&z_copy);
+           Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL) {
+           if (IS_CONST == IS_TMP_VAR) {
+               INIT_PZVAL(z);
+           }
+               if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+                       zend_print_variable(&z_copy);
+                       zval_dtor(&z_copy);
+               } else {
+                       zend_print_variable(z);
+               }
        } else {
                zend_print_variable(z);
        }
@@ -4614,10 +4620,16 @@ static int ZEND_FASTCALL  ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval *z = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
        if (IS_TMP_VAR != IS_CONST &&
-           Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
-               zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
-               zend_print_variable(&z_copy);
-               zval_dtor(&z_copy);
+           Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL) {
+           if (IS_TMP_VAR == IS_TMP_VAR) {
+               INIT_PZVAL(z);
+           }
+               if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+                       zend_print_variable(&z_copy);
+                       zval_dtor(&z_copy);
+               } else {
+                       zend_print_variable(z);
+               }
        } else {
                zend_print_variable(z);
        }
@@ -7870,10 +7882,16 @@ static int ZEND_FASTCALL  ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval *z = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
        if (IS_VAR != IS_CONST &&
-           Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
-               zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
-               zend_print_variable(&z_copy);
-               zval_dtor(&z_copy);
+           Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL) {
+           if (IS_VAR == IS_TMP_VAR) {
+               INIT_PZVAL(z);
+           }
+               if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+                       zend_print_variable(&z_copy);
+                       zval_dtor(&z_copy);
+               } else {
+                       zend_print_variable(z);
+               }
        } else {
                zend_print_variable(z);
        }
@@ -21767,10 +21785,16 @@ static int ZEND_FASTCALL  ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval *z = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
 
        if (IS_CV != IS_CONST &&
-           Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
-               zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
-               zend_print_variable(&z_copy);
-               zval_dtor(&z_copy);
+           Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL) {
+           if (IS_CV == IS_TMP_VAR) {
+               INIT_PZVAL(z);
+           }
+               if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+                       zend_print_variable(&z_copy);
+                       zval_dtor(&z_copy);
+               } else {
+                       zend_print_variable(z);
+               }
        } else {
                zend_print_variable(z);
        }