]> granicus.if.org Git - php/commitdiff
Fix bug #60611 (Segmentation fault with Cls::{expr}() syntax)
authorXinchen Hui <laruence@php.net>
Tue, 27 Dec 2011 08:38:18 +0000 (08:38 +0000)
committerXinchen Hui <laruence@php.net>
Tue, 27 Dec 2011 08:38:18 +0000 (08:38 +0000)
NEWS
Zend/tests/bug60611.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/NEWS b/NEWS
index 9db648953fbc9e87043ee276b09216b47f4c05ba..8c9bfbc574621ed15bbe611db6fad1ece5b8c597 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,9 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? Jan 2012, PHP 5.4.0 RC5
+- Core:
+  . Fixed bug #60611 (Segmentation fault with Cls::{expr}() syntax). (Laruence)
+
 - CLI SAPI:
   . Fixed bug #60591 (Memory leak when access a non-exists file). (Laruence)
 
diff --git a/Zend/tests/bug60611.phpt b/Zend/tests/bug60611.phpt
new file mode 100644 (file)
index 0000000..bbfb385
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Bug #60611 (Segmentation fault with Cls::{expr}() syntax)
+--FILE--
+<?php
+class Cls {
+       function __call($name, $arg) {
+       }
+       static function __callStatic($name, $arg) {
+       }
+}
+
+Cls::{0}();
+Cls::{1.0}();
+Cls::{true}();
+Cls::{false}();
+Cls::{null}();
+
+$cls = new Cls;
+$cls->{0}();
+$cls->{1.0}();
+$cls->{true}();
+$cls->{false}();
+$cls->{null}();
+
+echo "done";
+?>
+--EXPECT--
+done
index cfd1ce8315856f250cea785fb2c0eaf304b8f244..4a7bd8405e3958a5f24feb9f95a9b5b802a7936a 100644 (file)
@@ -1973,9 +1973,10 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
        if (last_op->opcode == ZEND_FETCH_OBJ_R) {
                if (last_op->op2_type == IS_CONST) {
                        zval name;
-
                        name = CONSTANT(last_op->op2.constant);
-                       if (!IS_INTERNED(Z_STRVAL(name))) {
+                       if (Z_TYPE(name) != IS_STRING) {
+                               convert_to_string(&name);
+                       } else if (!IS_INTERNED(Z_STRVAL(name))) {
                                Z_STRVAL(name) = estrndup(Z_STRVAL(name), Z_STRLEN(name));
                        }
                        FREE_POLYMORPHIC_CACHE_SLOT(last_op->op2.constant);
@@ -2367,7 +2368,11 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na
        zend_op *opline;
 
        if (method_name->op_type == IS_CONST) {
-               char *lcname = zend_str_tolower_dup(Z_STRVAL(method_name->u.constant), Z_STRLEN(method_name->u.constant));
+               char *lcname;
+               if (Z_TYPE(method_name->u.constant) !=  IS_STRING) {
+                       convert_to_string(&method_name->u.constant);
+               }
+               lcname = zend_str_tolower_dup(Z_STRVAL(method_name->u.constant), Z_STRLEN(method_name->u.constant));
                if ((sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == Z_STRLEN(method_name->u.constant) &&
                    memcmp(lcname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == 0) {
                        zval_dtor(&method_name->u.constant);