]> granicus.if.org Git - php/commitdiff
Fixed crash on self-referencing constant expression (part of a constant AST)
authorDmitry Stogov <dmitry@zend.com>
Wed, 23 Jul 2014 20:37:15 +0000 (00:37 +0400)
committerDmitry Stogov <dmitry@zend.com>
Wed, 23 Jul 2014 20:37:15 +0000 (00:37 +0400)
Zend/tests/constant_expressions_self_referencing_array.phpt
Zend/zend_ast.c
ext/reflection/php_reflection.c

index 09f862e0487d5f2a8bf7b08b34242474942c897f..ae76a086022f7902acfd435d1ba6f334171f060f 100644 (file)
@@ -1,7 +1,5 @@
 --TEST--
 Self-referencing constant expression (part of a constant AST)
---XFAIL--
-Not yet fixed, to be fixed for PHP 5.6
 --FILE--
 <?php
 class A {
index 12f94055239a793cbe9b831690e918019c934d2a..a7df0adbab6359ba447e73b1294677636f840ebe 100644 (file)
@@ -251,10 +251,19 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
                        zval_dtor(&op2);
                        break;
                case ZEND_CONST:
-                       *result = *ast->u.val;
-                       zval_copy_ctor(result);
-                       if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) {
-                               zval_update_constant_ex(&result, 1, scope TSRMLS_CC);
+                       /* class constants may be updated in-place */
+                       if (scope) {
+                               if (IS_CONSTANT_TYPE(Z_TYPE_P(ast->u.val))) {
+                                       zval_update_constant_ex(&ast->u.val, 1, scope TSRMLS_CC);
+                               }
+                               *result = *ast->u.val;
+                               zval_copy_ctor(result);
+                       } else {
+                               *result = *ast->u.val;
+                               zval_copy_ctor(result);
+                               if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) {
+                                       zval_update_constant_ex(&result, 1, scope TSRMLS_CC);
+                               }
                        }
                        break;
                case ZEND_BOOL_AND:
index 703e14113f05c361a7257390f119030d32900b40..02a19c0aaabee2af509226d0606143a39bd1c1fe 100644 (file)
@@ -728,12 +728,17 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg
                if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
                        zval *zv, zv_copy;
                        int use_copy;
+                       zend_class_entry *old_scope;
+
                        string_write(str, " = ", sizeof(" = ")-1);
                        ALLOC_ZVAL(zv);
                        *zv = *precv->op2.zv;
                        zval_copy_ctor(zv);
                        INIT_PZVAL(zv);
-                       zval_update_constant_ex(&zv, 1, fptr->common.scope TSRMLS_CC);
+                       old_scope = EG(scope);
+                       EG(scope) = fptr->common.scope;
+                       zval_update_constant_ex(&zv, 1, NULL TSRMLS_CC);
+                       EG(scope) = old_scope;
                        if (Z_TYPE_P(zv) == IS_BOOL) {
                                if (Z_LVAL_P(zv)) {
                                        string_write(str, "true", sizeof("true")-1);
@@ -2579,6 +2584,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
 {
        parameter_reference *param;
        zend_op *precv;
+       zend_class_entry *old_scope;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -2599,7 +2605,10 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
        if (!IS_CONSTANT_TYPE(Z_TYPE_P(return_value))) {
                zval_copy_ctor(return_value);
        }
-       zval_update_constant_ex(&return_value, 0, param->fptr->common.scope TSRMLS_CC);
+       old_scope = EG(scope);
+       EG(scope) = param->fptr->common.scope;
+       zval_update_constant_ex(&return_value, 0, NULL TSRMLS_CC);
+       EG(scope) = old_scope;
 }
 /* }}} */