]> granicus.if.org Git - php/commitdiff
Fixed disallowal of array usage in constants at run-time
authorBob Weinand <bobwei9@hotmail.com>
Fri, 11 Apr 2014 16:21:46 +0000 (18:21 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Fri, 11 Apr 2014 16:21:46 +0000 (18:21 +0200)
Added at the same time the possibility of array dereferencing
to complete the set of features (useful application of arrays in constants)

Zend/tests/bug66015.phpt
Zend/tests/errmsg_040.phpt
Zend/tests/ns_059.phpt
Zend/zend_ast.c
Zend/zend_execute.c
Zend/zend_execute.h
Zend/zend_language_parser.y
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index f1cbd37aec4c703b4dd8e71445651b1d3485f941..4f6d51e0dd173957c6020ba9bf5d589965dcf940 100644 (file)
@@ -22,11 +22,9 @@ class Test
 
 $test = new Test();
 ?>
-===DONE===
 --EXPECTF--
 array (
   1 => 'first',
   2 => 'second',
   3 => 'third',
 )
-===DONE===
index 2b192d0b83f2ea326b06390e941f426627196a03..c3a007f8c174edae677f8e5458b185cecc4a95d5 100644 (file)
@@ -1,7 +1,5 @@
 --TEST--
 errmsg: arrays are not allowed in class constants
---XFAIL--
-Actually it's hard to test where the array comes from (property, constant, ...)
 --FILE--
 <?php
 
@@ -9,7 +7,9 @@ class test {
        const TEST = array(1,2,3);
 }
 
+var_dump(test::TEST);
+
 echo "Done\n";
 ?>
 --EXPECTF--    
-Fatal error: Arrays are not allowed in class constants in %s on line %d
+Fatal error: Arrays are not allowed in constants at run-time in %s on line %d
index b9fcfee5c02e262099c23aaa3cefbb6c357df9ef..48da40b3f64bcf9908e6b08ffaa894f96c861176 100644 (file)
@@ -1,10 +1,11 @@
 --TEST--
 059: Constant arrays
---XFAIL--
-Actually it's hard to test where the array comes from (property, constant, ...)
 --FILE--
 <?php
 const C = array();
+
+var_dump(C);
+?>
 --EXPECTF--
-Fatal error: Arrays are not allowed as constants in %sns_059.php on line 2
+Fatal error: Arrays are not allowed in constants at run-time in %sns_059.php on line 4
 
index 8a3df98c1055602202f75cd9d3408c666d62174b..fa322325162f9291ef12640f1de5a589c2158de3 100644 (file)
@@ -322,6 +322,18 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
                                }
                        }
                        break;
+               case ZEND_FETCH_DIM_R:
+                       zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
+                       zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
+                       {
+                               zval *tmp;
+                               zend_fetch_dimension_by_zval(&tmp, &op1, &op2 TSRMLS_CC);
+                               *result = *tmp;
+                               efree(tmp);
+                       }
+                       zval_dtor(&op1);
+                       zval_dtor(&op2);
+                       break;
                default:
                        zend_error(E_ERROR, "Unsupported constant expression");
        }
index 66accd61e970de93497dcb4add83eda3029d3eb6..bdf8b6e70f06465998868751468dd4d565453fb0 100644 (file)
@@ -1352,9 +1352,15 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval *conta
        }
 }
 
+ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC) {
+       temp_variable tmp;
+       zend_fetch_dimension_address_read(&tmp, container, dim, IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+       *result = tmp.var.ptr;
+}
+
 static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, const zend_literal *key, int type TSRMLS_DC)
 {
-       zval *container = *container_ptr;;
+       zval *container = *container_ptr;
 
        if (Z_TYPE_P(container) != IS_OBJECT) {
                if (container == &EG(error_zval)) {
index 0d3a908a1527c8ec2e03a602162b2c82e040c1f3..179eacdf52f624dcab6b65526a98bbc4576810dd 100644 (file)
@@ -362,6 +362,8 @@ ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, uint class_n
 ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC);
 void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);
 
+ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC);
+
 #ifdef ZEND_WIN32
 void zend_init_timeout_thread(void);
 void zend_shutdown_timeout_thread(void);
index 40e5c05bce89ff27c00871eb33e365ef5fac8cc3..56e702e8f9f4e34e31ddd046c41d6cfc2c05c7d1 100644 (file)
@@ -1003,7 +1003,8 @@ static_scalar_value:
 ;
 
 static_operation:
-               static_scalar_value '+' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_ADD, $1.u.ast, $3.u.ast); }
+               static_scalar_value '[' static_scalar_value ']' { $$.u.ast = zend_ast_create_binary(ZEND_FETCH_DIM_R, $1.u.ast, $3.u.ast); }
+       |       static_scalar_value '+' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_ADD, $1.u.ast, $3.u.ast); }
        |       static_scalar_value '-' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_SUB, $1.u.ast, $3.u.ast); }
        |       static_scalar_value '*' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_MUL, $1.u.ast, $3.u.ast); }
        |       static_scalar_value T_POW static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_POW, $1.u.ast, $3.u.ast); }
index 08eb471d49d14b8ef83d271a628bc99b42caf0c1..85e348c9014c1ee3f727b6fa04f19cbecc0637ff 100644 (file)
@@ -3710,8 +3710,6 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
                retval = &EX_T(opline->result.var).tmp_var;
                ZVAL_COPY_VALUE(retval, &c->value);
                zval_copy_ctor(retval);
-               CHECK_EXCEPTION();
-               ZEND_VM_NEXT_OPCODE();
        } else {
                /* class constant */
                zend_class_entry *ce;
@@ -3722,8 +3720,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
                                value = CACHED_PTR(opline->op2.literal->cache_slot);
                                ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
                                zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
-                               CHECK_EXCEPTION();
-                               ZEND_VM_NEXT_OPCODE();
+                               goto constant_fetch_end;
                        } else if (CACHED_PTR(opline->op1.literal->cache_slot)) {
                                ce = CACHED_PTR(opline->op1.literal->cache_slot);
                        } else {
@@ -3741,8 +3738,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
                        if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) {
                                ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
                                zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
-                               CHECK_EXCEPTION();
-                               ZEND_VM_NEXT_OPCODE();
+                               goto constant_fetch_end;
                        }
                }
 
@@ -3767,10 +3763,13 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
                } else {
                        zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
                }
-
-               CHECK_EXCEPTION();
-               ZEND_VM_NEXT_OPCODE();
        }
+constant_fetch_end:
+       if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) {
+               zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time");
+       }
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
 }
 
 ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUSED|CV)
index e0277725d6da0dce676b3e49700fd78a94894340..ec665e75fdc7754fe52c6997fdf9e91a846a2065 100644 (file)
@@ -3971,8 +3971,6 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
                retval = &EX_T(opline->result.var).tmp_var;
                ZVAL_COPY_VALUE(retval, &c->value);
                zval_copy_ctor(retval);
-               CHECK_EXCEPTION();
-               ZEND_VM_NEXT_OPCODE();
        } else {
                /* class constant */
                zend_class_entry *ce;
@@ -3983,8 +3981,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
                                value = CACHED_PTR(opline->op2.literal->cache_slot);
                                ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
                                zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
-                               CHECK_EXCEPTION();
-                               ZEND_VM_NEXT_OPCODE();
+                               goto constant_fetch_end;
                        } else if (CACHED_PTR(opline->op1.literal->cache_slot)) {
                                ce = CACHED_PTR(opline->op1.literal->cache_slot);
                        } else {
@@ -4002,8 +3999,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
                        if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) {
                                ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
                                zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
-                               CHECK_EXCEPTION();
-                               ZEND_VM_NEXT_OPCODE();
+                               goto constant_fetch_end;
                        }
                }
 
@@ -4028,10 +4024,13 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
                } else {
                        zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
                }
-
-               CHECK_EXCEPTION();
-               ZEND_VM_NEXT_OPCODE();
        }
+constant_fetch_end:
+       if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) {
+               zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time");
+       }
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
 }
 
 static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -15921,8 +15920,6 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
                retval = &EX_T(opline->result.var).tmp_var;
                ZVAL_COPY_VALUE(retval, &c->value);
                zval_copy_ctor(retval);
-               CHECK_EXCEPTION();
-               ZEND_VM_NEXT_OPCODE();
        } else {
                /* class constant */
                zend_class_entry *ce;
@@ -15933,8 +15930,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
                                value = CACHED_PTR(opline->op2.literal->cache_slot);
                                ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
                                zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
-                               CHECK_EXCEPTION();
-                               ZEND_VM_NEXT_OPCODE();
+                               goto constant_fetch_end;
                        } else if (CACHED_PTR(opline->op1.literal->cache_slot)) {
                                ce = CACHED_PTR(opline->op1.literal->cache_slot);
                        } else {
@@ -15952,8 +15948,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
                        if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) {
                                ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
                                zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
-                               CHECK_EXCEPTION();
-                               ZEND_VM_NEXT_OPCODE();
+                               goto constant_fetch_end;
                        }
                }
 
@@ -15978,10 +15973,13 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
                } else {
                        zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
                }
-
-               CHECK_EXCEPTION();
-               ZEND_VM_NEXT_OPCODE();
        }
+constant_fetch_end:
+       if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) {
+               zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time");
+       }
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
 }
 
 static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -25534,8 +25532,6 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
                retval = &EX_T(opline->result.var).tmp_var;
                ZVAL_COPY_VALUE(retval, &c->value);
                zval_copy_ctor(retval);
-               CHECK_EXCEPTION();
-               ZEND_VM_NEXT_OPCODE();
        } else {
                /* class constant */
                zend_class_entry *ce;
@@ -25546,8 +25542,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
                                value = CACHED_PTR(opline->op2.literal->cache_slot);
                                ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
                                zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
-                               CHECK_EXCEPTION();
-                               ZEND_VM_NEXT_OPCODE();
+                               goto constant_fetch_end;
                        } else if (CACHED_PTR(opline->op1.literal->cache_slot)) {
                                ce = CACHED_PTR(opline->op1.literal->cache_slot);
                        } else {
@@ -25565,8 +25560,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
                        if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) {
                                ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
                                zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
-                               CHECK_EXCEPTION();
-                               ZEND_VM_NEXT_OPCODE();
+                               goto constant_fetch_end;
                        }
                }
 
@@ -25591,10 +25585,13 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
                } else {
                        zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
                }
-
-               CHECK_EXCEPTION();
-               ZEND_VM_NEXT_OPCODE();
        }
+constant_fetch_end:
+       if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) {
+               zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time");
+       }
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
 }
 
 static int ZEND_FASTCALL  ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)