Commit:    5a87b7ff39bbf427807c46d1e51e2654259ad394
Author:    Dmitry Stogov <dmi...@zend.com>         Tue, 10 Dec 2013 14:19:17 
+0400
Parents:   5ad11174196760ad9aa4c94c08e0e58c72eb9cb9
Branches:  PHP-5.6 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=5a87b7ff39bbf427807c46d1e51e2654259ad394

Log:
Fixed bug #66252 (Problems in AST evaluation invalidating valid parent:: 
reference. Constant expessions have to be evaluated in context of defining 
class).

Bugs:
https://bugs.php.net/66252

Changed paths:
  A  Zend/tests/bug66252.phpt
  M  Zend/zend_ast.c
  M  Zend/zend_ast.h
  M  Zend/zend_compile.c
  M  Zend/zend_execute_API.c

diff --git a/Zend/tests/bug66252.phpt b/Zend/tests/bug66252.phpt
new file mode 100644
index 0000000..e692a8e
--- /dev/null
+++ b/Zend/tests/bug66252.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Bug #66252 (Problems in AST evaluation invalidating valid parent:: reference)
+--FILE--
+<?php
+class A {
+       const HW = "this is A";
+}
+class B extends A {
+       const BHW = parent::HW . " extended by B";
+}
+const C = B::BHW; 
+echo C, "\n";
+--EXPECT--
+this is A extended by B
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index fb5a7eb..66330d5 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -81,143 +81,143 @@ ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
        }
 }
 
-ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast TSRMLS_DC)
+ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry 
*scope TSRMLS_DC)
 {
        zval op1, op2;
 
        switch (ast->kind) {
                case ZEND_ADD:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        add_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_SUB:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        sub_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_MUL:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        mul_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_DIV:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        div_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_MOD:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        mod_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_SL:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        shift_left_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_SR:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        shift_right_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_CONCAT:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        concat_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_BW_OR:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        bitwise_or_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_BW_AND:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        bitwise_and_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_BW_XOR:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        bitwise_xor_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_BW_NOT:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
                        bitwise_not_function(result, &op1 TSRMLS_CC);
                        zval_dtor(&op1);
                        break;
                case ZEND_BOOL_NOT:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
                        boolean_not_function(result, &op1 TSRMLS_CC);
                        zval_dtor(&op1);
                        break;
                case ZEND_BOOL_XOR:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        boolean_xor_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_IS_IDENTICAL:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        is_identical_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_IS_NOT_IDENTICAL:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        is_not_identical_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_IS_EQUAL:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        is_equal_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_IS_NOT_EQUAL:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        is_not_equal_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_IS_SMALLER:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        is_smaller_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
                        break;
                case ZEND_IS_SMALLER_OR_EQUAL:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[1] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope 
TSRMLS_CC);
                        is_smaller_or_equal_function(result, &op1, &op2 
TSRMLS_CC);
                        zval_dtor(&op1);
                        zval_dtor(&op2);
@@ -226,13 +226,13 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast 
*ast TSRMLS_DC)
                        *result = *ast->u.val;
                        zval_copy_ctor(result);
                        if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) {
-                               zval_update_constant(&result, (void *) 1 
TSRMLS_CC);
+                               zval_update_constant_ex(&result, (void *) 1, 
scope TSRMLS_CC);
                        }
                        break;
                case ZEND_BOOL_AND:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
                        if (zend_is_true(&op1)) {
-                               zend_ast_evaluate(&op2, (&ast->u.child)[1] 
TSRMLS_CC);
+                               zend_ast_evaluate(&op2, (&ast->u.child)[1], 
scope TSRMLS_CC);
                                ZVAL_BOOL(result, zend_is_true(&op2));
                                zval_dtor(&op2);
                        } else {
@@ -241,39 +241,39 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast 
*ast TSRMLS_DC)
                        zval_dtor(&op1);
                        break;
                case ZEND_BOOL_OR:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
                        if (zend_is_true(&op1)) {
                                ZVAL_BOOL(result, 1);
                        } else {
-                               zend_ast_evaluate(&op2, (&ast->u.child)[1] 
TSRMLS_CC);
+                               zend_ast_evaluate(&op2, (&ast->u.child)[1], 
scope TSRMLS_CC);
                                ZVAL_BOOL(result, zend_is_true(&op2));
                                zval_dtor(&op2);
                        }
                        zval_dtor(&op1);
                        break;
                case ZEND_SELECT:
-                       zend_ast_evaluate(&op1, (&ast->u.child)[0] TSRMLS_CC);
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope 
TSRMLS_CC);
                        if (zend_is_true(&op1)) {
                                if (!(&ast->u.child)[1]) {
                                        *result = op1;
                                } else {
-                                       zend_ast_evaluate(result, 
(&ast->u.child)[1] TSRMLS_CC);
+                                       zend_ast_evaluate(result, 
(&ast->u.child)[1], scope TSRMLS_CC);
                                        zval_dtor(&op1);
                                }
                        } else {
-                               zend_ast_evaluate(result, (&ast->u.child)[2] 
TSRMLS_CC);
+                               zend_ast_evaluate(result, (&ast->u.child)[2], 
scope TSRMLS_CC);
                                zval_dtor(&op1);
                        }
                        break;
                case ZEND_UNARY_PLUS:
                        ZVAL_LONG(&op1, 0);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[0] TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[0], scope 
TSRMLS_CC);
                        add_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op2);
                        break;
                case ZEND_UNARY_MINUS:
                        ZVAL_LONG(&op1, 0);
-                       zend_ast_evaluate(&op2, (&ast->u.child)[0] TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[0], scope 
TSRMLS_CC);
                        sub_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op2);
                        break;
diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h
index 27d595e..49908ce 100644
--- a/Zend/zend_ast.h
+++ b/Zend/zend_ast.h
@@ -53,7 +53,7 @@ ZEND_API zend_ast *zend_ast_create_ternary(uint kind, 
zend_ast *op0, zend_ast *o
 
 ZEND_API int zend_ast_is_ct_constant(zend_ast *ast);
 
-ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast TSRMLS_DC);
+ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry 
*scope TSRMLS_DC);
 
 ZEND_API zend_ast *zend_ast_copy(zend_ast *ast);
 ZEND_API void zend_ast_destroy(zend_ast *ast);
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 35f5f30..ab8609e 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -7341,7 +7341,7 @@ void zend_do_constant_expression(znode *result, zend_ast 
*ast TSRMLS_DC) /* {{{
                result->u.constant = *ast->u.val;
                efree(ast);
        } else if (zend_ast_is_ct_constant(ast)) {
-               zend_ast_evaluate(&result->u.constant, ast TSRMLS_CC);
+               zend_ast_evaluate(&result->u.constant, ast, NULL TSRMLS_CC);
                zend_ast_destroy(ast);
        } else {
                Z_TYPE(result->u.constant) = IS_CONSTANT_AST;
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index bcce741..82689ed 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -593,7 +593,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, 
zend_class_entry *sco
                                continue;
                        }
                        if (str_index[str_index_len - 2] == IS_CONSTANT_AST) {
-                               zend_ast_evaluate(&const_value, *(zend_ast 
**)str_index TSRMLS_CC);
+                               zend_ast_evaluate(&const_value, *(zend_ast 
**)str_index, scope TSRMLS_CC);
                                zend_ast_destroy(*(zend_ast **)str_index);
                        } else if (!zend_get_constant_ex(str_index, 
str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] 
TSRMLS_CC)) {
                                char *actual;
@@ -667,7 +667,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, 
zend_class_entry *sco
                SEPARATE_ZVAL_IF_NOT_REF(pp);
                p = *pp;
 
-               zend_ast_evaluate(&const_value, Z_AST_P(p) TSRMLS_CC);
+               zend_ast_evaluate(&const_value, Z_AST_P(p), scope TSRMLS_CC);
                if (inline_change) {
                        zend_ast_destroy(Z_AST_P(p));
                }
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to