]> granicus.if.org Git - php/commitdiff
Fix magic constants (__LINE__) with ?? for constant scalar exprs
authorBob Weinand <bobwei9@hotmail.com>
Thu, 21 Apr 2016 00:45:09 +0000 (02:45 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Thu, 21 Apr 2016 00:45:09 +0000 (02:45 +0200)
Also fix general memory leak when root ast gets replaced in compile time evaluation

Zend/tests/constant_expressions_coalesce.phpt
Zend/tests/constant_expressions_coalesce_empty_dim.phpt [new file with mode: 0644]
Zend/tests/constant_expressions_dynamic.phpt
Zend/zend_compile.c
Zend/zend_execute.c

index aa40bd68e2b278de7b3af43b00cf58881eb1078f..425aba69c403ee589e5b262311f38f007a95546e 100644 (file)
@@ -9,11 +9,15 @@ const T_1 = null ?? A[1]['undefined']['index'] ?? 1;
 const T_2 = null ?? A['undefined']['index'] ?? 2;
 const T_3 = null ?? A[1][0][2] ?? 3;
 const T_4 = A[1][0][2] ?? 4;
+const T_5 = null ?? __LINE__;
+const T_6 = __LINE__ ?? "bar";
 
 var_dump(T_1);
 var_dump(T_2);
 var_dump(T_3);
 var_dump(T_4);
+var_dump(T_5);
+var_dump(T_6);
 
 var_dump((function(){ static $var = null ?? A[1]['undefined']['index'] ?? 1; return $var; })());
 var_dump((function(){ static $var = null ?? A['undefined']['index'] ?? 2; return $var; })());
@@ -25,14 +29,14 @@ var_dump((new class { public $var = null ?? A['undefined']['index'] ?? 2; })->va
 var_dump((new class { public $var = null ?? A[1][0][2] ?? 3; })->var);
 var_dump((new class { public $var = A[1][0][2] ?? 4; })->var);
 
-const D = [][] ?? 1;
-
 ?>
 --EXPECTF--
 int(1)
 int(2)
 int(3)
 int(4)
+int(%d)
+int(%d)
 int(1)
 int(2)
 int(3)
@@ -41,5 +45,3 @@ int(1)
 int(2)
 int(3)
 int(4)
-
-Fatal error: Cannot use [] for reading in %s.php on line 25
diff --git a/Zend/tests/constant_expressions_coalesce_empty_dim.phpt b/Zend/tests/constant_expressions_coalesce_empty_dim.phpt
new file mode 100644 (file)
index 0000000..56ee43b
--- /dev/null
@@ -0,0 +1,11 @@
+--TEST--
+Constant expressions with empty dimension fetch on coalesce
+--FILE--
+<?php
+
+const A = [][] ?? 1;
+
+?>
+--EXPECTF--
+Fatal error: Cannot use [] for reading in %s.php on line %d
+
index d4e06ee258bcf38373e4f860e500ff6aa1ab6784..d038591036010f89cf17f79f91e8906590014217 100644 (file)
@@ -35,10 +35,12 @@ const T_19 = [
     false => false,
     true => true,
 ];
+eval("const T_20x = 'a';");
+const T_20 = null ?: (T_20x . 'bc');
 
 var_dump(
     T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9, T_10,
-    T_11, T_12, T_13, T_14, T_15, T_16, T_17, T_18, T_19
+    T_11, T_12, T_13, T_14, T_15, T_16, T_17, T_18, T_19, T_20
 );
 
 ?>
@@ -75,3 +77,4 @@ array(6) {
   [1]=>
   bool(true)
 }
+string(3) "abc"
index 18836d6418087de62242bda4b297e77c59b6cf17..20575360c3121b955ddc8412543d4a526fd2aa3f 100644 (file)
@@ -6967,14 +6967,16 @@ void zend_const_expr_to_zval(zval *result, zend_ast *ast) /* {{{ */
        zend_compile_const_expr(&ast);
        if (ast->kind == ZEND_AST_ZVAL) {
                ZVAL_COPY_VALUE(result, zend_ast_get_zval(ast));
-
-               /* Kill this branch of the original AST, as it was already destroyed.
-                * It would be nice to find a better solution to this problem in the
-                * future. */
-               orig_ast->kind = 0;
        } else {
                ZVAL_NEW_AST(result, zend_ast_copy(ast));
+               /* destroy the ast here, it might have been replaced */
+               zend_ast_destroy(ast);
        }
+
+       /* Kill this branch of the original AST, as it was already destroyed.
+        * It would be nice to find a better solution to this problem in the
+        * future. */
+       orig_ast->kind = 0;
 }
 /* }}} */
 
@@ -7385,6 +7387,26 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
 
                        zend_ct_eval_unary_pm(&result, ast->kind, zend_ast_get_zval(ast->child[0]));
                        break;
+               case ZEND_AST_COALESCE:
+                       zend_eval_const_expr(&ast->child[0]);
+
+                       if (ast->child[0]->kind != ZEND_AST_ZVAL) {
+                               /* ensure everything was compile-time evaluated at least once */
+                               zend_eval_const_expr(&ast->child[1]);
+                               return;
+                       }
+
+                       if (Z_TYPE_P(zend_ast_get_zval(ast->child[0])) == IS_NULL) {
+                               zend_eval_const_expr(&ast->child[1]);
+                               *ast_ptr = ast->child[1];
+                               ast->child[1] = NULL;
+                               zend_ast_destroy(ast);
+                       } else {
+                               *ast_ptr = ast->child[0];
+                               ast->child[0] = NULL;
+                               zend_ast_destroy(ast);
+                       }
+                       return;
                case ZEND_AST_CONDITIONAL:
                {
                        zend_ast **child, *child_ast;
index 324cf82e2b443677d2ee605ba6240a7dd46a707a..cda98fd8a489c380483ce9f1e1f1a6acc198dc67 100644 (file)
@@ -1914,7 +1914,7 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *
 
 ZEND_API void zend_fetch_dimension_by_zval_is(zval *result, zval *container, zval *dim, int dim_type)
 {
-       zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 1);
+       zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS);
 }