diff --git a/Zend/tests/bug60611.phpt b/Zend/tests/bug60611.phpt new file mode 100644 index 00000000000..bbfb385ff25 --- /dev/null +++ b/Zend/tests/bug60611.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #60611 (Segmentation fault with Cls::{expr}() syntax) +--FILE-- +{0}(); +$cls->{1.0}(); +$cls->{true}(); +$cls->{false}(); +$cls->{null}(); + +echo "done"; +?> +--EXPECT-- +done diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index cfd1ce83158..4a7bd8405e3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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);