From f614fc68984b2d7fce3f275b8106955b5d910472 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 11 Apr 2014 10:06:17 +0200 Subject: [PATCH] Fix bug #66015 by reverting "Removed operations on constant arrays." --- Zend/tests/bug66015.phpt | 32 ++++++ Zend/tests/errmsg_040.phpt | 2 + Zend/tests/ns_059.phpt | 2 + Zend/zend.h | 7 +- Zend/zend_API.c | 1 - Zend/zend_ast.c | 63 ++++++++---- Zend/zend_ast.h | 3 + Zend/zend_compile.c | 55 ++-------- Zend/zend_compile.h | 2 +- Zend/zend_execute_API.c | 119 +--------------------- Zend/zend_language_parser.y | 18 ++-- Zend/zend_variables.c | 7 +- Zend/zend_vm_def.h | 3 - ext/com_dotnet/com_variant.c | 2 +- ext/opcache/ZendAccelerator.c | 6 +- ext/opcache/zend_accelerator_util_funcs.c | 36 ++++--- ext/opcache/zend_persist.c | 2 + ext/opcache/zend_persist_calc.c | 2 + ext/pgsql/pgsql.c | 4 +- ext/soap/php_encoding.c | 2 - ext/xmlrpc/xmlrpc-epi-php.c | 1 - 21 files changed, 140 insertions(+), 229 deletions(-) create mode 100644 Zend/tests/bug66015.phpt diff --git a/Zend/tests/bug66015.phpt b/Zend/tests/bug66015.phpt new file mode 100644 index 0000000000..f1cbd37aec --- /dev/null +++ b/Zend/tests/bug66015.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #66015 (wrong array indexing in class's static property) +--FILE-- + 'first', + 'second', + 'third' + ]; + + public function __construct() + { + var_export(self::$array); + } +} + +$test = new Test(); +?> +===DONE=== +--EXPECTF-- +array ( + 1 => 'first', + 2 => 'second', + 3 => 'third', +) +===DONE=== diff --git a/Zend/tests/errmsg_040.phpt b/Zend/tests/errmsg_040.phpt index f3d0afcf0a..2b192d0b83 100644 --- a/Zend/tests/errmsg_040.phpt +++ b/Zend/tests/errmsg_040.phpt @@ -1,5 +1,7 @@ --TEST-- errmsg: arrays are not allowed in class constants +--XFAIL-- +Actually it's hard to test where the array comes from (property, constant, ...) --FILE-- type & ZEND_INTERNAL_CLASS) { switch(Z_TYPE_P(property)) { case IS_ARRAY: - case IS_CONSTANT_ARRAY: case IS_OBJECT: case IS_RESOURCE: zend_error(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources"); diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 9a0808db9d..8a3df98c10 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -63,6 +63,27 @@ ZEND_API zend_ast* zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *o return ast; } +ZEND_API zend_ast* zend_ast_create_dynamic(uint kind) +{ + zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * 3); /* use 4 children as deafult */ + ast->kind = kind; + ast->children = 0; + return ast; +} + +ZEND_API void zend_ast_dynamic_add(zend_ast **ast, zend_ast *op) +{ + if ((*ast)->children >= 4 && (*ast)->children == ((*ast)->children & -(*ast)->children)) { + *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children * 2 + 1)); + } + (&(*ast)->u.child)[(*ast)->children++] = op; +} + +ZEND_API void zend_ast_dynamic_shrink(zend_ast **ast) +{ + *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children - 1)); +} + ZEND_API int zend_ast_is_ct_constant(zend_ast *ast) { int i; @@ -284,6 +305,23 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s sub_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op2); break; + case ZEND_INIT_ARRAY: + INIT_PZVAL(result); + array_init(result); + { + int i; + zend_bool has_key; + for (i = 0; i < ast->children; i+=2) { + zval *expr; + MAKE_STD_ZVAL(expr); + if ((has_key = !!(&ast->u.child)[i])) { + zend_ast_evaluate(&op1, (&ast->u.child)[i], scope TSRMLS_CC); + } + zend_ast_evaluate(expr, (&ast->u.child)[i+1], scope TSRMLS_CC); + zend_do_add_static_array_element(result, has_key?&op1:NULL, expr); + } + } + break; default: zend_error(E_ERROR, "Unsupported constant expression"); } @@ -297,26 +335,15 @@ ZEND_API zend_ast *zend_ast_copy(zend_ast *ast) zend_ast *copy = zend_ast_create_constant(ast->u.val); zval_copy_ctor(copy->u.val); return copy; - } else { - switch (ast->children) { - case 1: - return zend_ast_create_unary( - ast->kind, - zend_ast_copy((&ast->u.child)[0])); - case 2: - return zend_ast_create_binary( - ast->kind, - zend_ast_copy((&ast->u.child)[0]), - zend_ast_copy((&ast->u.child)[1])); - case 3: - return zend_ast_create_ternary( - ast->kind, - zend_ast_copy((&ast->u.child)[0]), - zend_ast_copy((&ast->u.child)[1]), - zend_ast_copy((&ast->u.child)[2])); + } else if (ast->children) { + zend_ast *new = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1)); + int i; + new->kind = ast->kind; + for (i = 0; i < ast->children; i++) { + (&new->u.child)[i] = zend_ast_copy((&ast->u.child)[i]); } } - return NULL; + return zend_ast_create_dynamic(ast->kind); } ZEND_API void zend_ast_destroy(zend_ast *ast) diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 927e99cff8..f8df15c95b 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -50,6 +50,9 @@ ZEND_API zend_ast *zend_ast_create_constant(zval *zv); ZEND_API zend_ast *zend_ast_create_unary(uint kind, zend_ast *op0); ZEND_API zend_ast *zend_ast_create_binary(uint kind, zend_ast *op0, zend_ast *op1); ZEND_API zend_ast *zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *op1, zend_ast *op2); +ZEND_API zend_ast* zend_ast_create_dynamic(uint kind); +ZEND_API void zend_ast_dynamic_add(zend_ast **ast, zend_ast *op); +ZEND_API void zend_ast_dynamic_shrink(zend_ast **ast); ZEND_API int zend_ast_is_ct_constant(zend_ast *ast); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 1bcd430840..099120ae83 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1933,7 +1933,7 @@ void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initializ if (op == ZEND_RECV_INIT) { if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) { cur_arg_info->allow_null = 1; - } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY && Z_TYPE(initialization->u.constant) != IS_CONSTANT_ARRAY) { + } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY) { zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL"); } } @@ -5442,10 +5442,6 @@ void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_D const char *cname = NULL; zend_ulong hash; - if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) { - zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed in class constants"); - return; - } if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants"); return; @@ -5887,57 +5883,30 @@ void zend_do_add_array_element(znode *result, const znode *expr, const znode *of } /* }}} */ -void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr) /* {{{ */ +void zend_do_add_static_array_element(zval *result, zval *offset, const zval *expr) /* {{{ */ { - zval *element; - - ALLOC_ZVAL(element); - *element = expr->u.constant; if (offset) { - switch (Z_TYPE(offset->u.constant) & IS_CONSTANT_TYPE_MASK) { - case IS_CONSTANT: - /* Ugly hack to denote that this value has a constant index */ - Z_TYPE_P(element) |= IS_CONSTANT_INDEX; - Z_STRVAL(offset->u.constant) = erealloc(Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3); - Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+1] = Z_TYPE(offset->u.constant); - Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+2] = 0; - zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3, &element, sizeof(zval *), NULL); - zval_dtor(&offset->u.constant); - break; - case IS_CONSTANT_AST: { - /* Another ugly hack to store the data about the AST in the array */ - char* key; - int len = sizeof(zend_ast *); - Z_TYPE_P(element) |= IS_CONSTANT_INDEX; - - key = emalloc(len + 2); - *(zend_ast **)key = Z_AST(offset->u.constant); - key[len] = Z_TYPE(offset->u.constant); - key[len + 1] = 0; - zend_symtable_update(Z_ARRVAL(result->u.constant), key, len + 2, &element, sizeof(zval *), NULL); - efree(key); - break; - } + switch (Z_TYPE_P(offset)) { case IS_STRING: - zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+1, &element, sizeof(zval *), NULL); - zval_dtor(&offset->u.constant); + zend_symtable_update(Z_ARRVAL_P(result), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr, sizeof(zval *), NULL); + zval_dtor(offset); break; case IS_NULL: - zend_symtable_update(Z_ARRVAL(result->u.constant), "", 1, &element, sizeof(zval *), NULL); + zend_symtable_update(Z_ARRVAL_P(result), "", 1, &expr, sizeof(zval *), NULL); break; case IS_LONG: case IS_BOOL: - zend_hash_index_update(Z_ARRVAL(result->u.constant), Z_LVAL(offset->u.constant), &element, sizeof(zval *), NULL); + zend_hash_index_update(Z_ARRVAL_P(result), Z_LVAL_P(offset), &expr, sizeof(zval *), NULL); break; case IS_DOUBLE: - zend_hash_index_update(Z_ARRVAL(result->u.constant), zend_dval_to_lval(Z_DVAL(offset->u.constant)), &element, sizeof(zval *), NULL); + zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_lval(Z_DVAL_P(offset)), &expr, sizeof(zval *), NULL); break; - case IS_CONSTANT_ARRAY: + case IS_ARRAY: zend_error(E_ERROR, "Illegal offset type"); break; } } else { - zend_hash_next_index_insert(Z_ARRVAL(result->u.constant), &element, sizeof(zval *), NULL); + zend_hash_next_index_insert(Z_ARRVAL_P(result), &expr, sizeof(zval *), NULL); } } /* }}} */ @@ -7318,10 +7287,6 @@ void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */ zend_op *opline; zval **ns_name; - if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) { - zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed as constants"); - } - if (zend_get_ct_const(&name->u.constant, 0 TSRMLS_CC)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", Z_STRVAL(name->u.constant)); } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 5362058fa2..99d3704b76 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -598,7 +598,7 @@ void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC); void zend_do_init_array(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC); void zend_do_add_array_element(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC); -void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr); +void zend_do_add_static_array_element(zval *result, zval *offset, const zval *expr); void zend_do_list_init(TSRMLS_D); void zend_do_list_end(znode *result, znode *expr TSRMLS_DC); void zend_do_add_list_element(const znode *element TSRMLS_DC); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 5d5153dc13..692ec83cc3 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -451,24 +451,11 @@ ZEND_API int zend_is_true(zval *op) /* {{{ */ #include "../TSRM/tsrm_strtok_r.h" -#define IS_VISITED_CONSTANT IS_CONSTANT_INDEX +#define IS_VISITED_CONSTANT 0x80 #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT -static void zval_deep_copy(zval **p) -{ - zval *value; - - ALLOC_ZVAL(value); - *value = **p; - Z_TYPE_P(value) &= ~IS_CONSTANT_INDEX; - zval_copy_ctor(value); - Z_TYPE_P(value) = Z_TYPE_PP(p); - INIT_PZVAL(value); - *p = value; -} - ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { zval *p = *pp; @@ -559,110 +546,6 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco Z_SET_REFCOUNT_P(p, refcount); Z_SET_ISREF_TO_P(p, is_ref); - } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) { - zval **element, *new_val; - char *str_index; - uint str_index_len; - ulong num_index; - int ret; - - SEPARATE_ZVAL_IF_NOT_REF(pp); - p = *pp; - Z_TYPE_P(p) = IS_ARRAY; - - if (!inline_change) { - zval *tmp; - HashTable *tmp_ht = NULL; - - ALLOC_HASHTABLE(tmp_ht); - zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *)); - Z_ARRVAL_P(p) = tmp_ht; - } - - /* First go over the array and see if there are any constant indices */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); - while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) { - if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX; - if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - if (str_index[str_index_len - 2] == IS_CONSTANT_AST) { - 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; - const char *save = str_index; - if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) { - zend_error(E_ERROR, "Undefined class constant '%s'", str_index); - str_index_len -= ((colon - str_index) + 1); - str_index = colon; - } else { - if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) { - if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) { - actual++; - str_index_len -= (actual - str_index); - str_index = actual; - } - } - if (str_index[0] == '\\') { - ++str_index; - --str_index_len; - } - if (save[0] == '\\') { - ++save; - } - if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) { - zend_error(E_ERROR, "Undefined constant '%s'", save); - } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); - } - ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1); - } - - if (Z_REFCOUNT_PP(element) > 1) { - ALLOC_ZVAL(new_val); - *new_val = **element; - zval_copy_ctor(new_val); - Z_SET_REFCOUNT_P(new_val, 1); - Z_UNSET_ISREF_P(new_val); - - /* preserve this bit for inheritance */ - Z_TYPE_PP(element) |= IS_CONSTANT_INDEX; - zval_ptr_dtor(element); - *element = new_val; - } - - switch (Z_TYPE(const_value)) { - case IS_STRING: - ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_BOOL: - case IS_LONG: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - case IS_DOUBLE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - case IS_NULL: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - default: - ret = SUCCESS; - break; - } - if (ret == SUCCESS) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - } - zval_dtor(&const_value); - } - zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { SEPARATE_ZVAL_IF_NOT_REF(pp); p = *pp; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index b7467b7552..40e5c05bce 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -986,9 +986,7 @@ static_class_constant: ; static_scalar: /* compile-time evaluated scalars */ - static_scalar_value { zend_do_constant_expression(&$$, $1.u.ast TSRMLS_CC); } - | T_ARRAY '(' static_array_pair_list ')' { $$ = $3; Z_TYPE($$.u.constant) = IS_CONSTANT_ARRAY; } - | '[' static_array_pair_list ']' { $$ = $2; Z_TYPE($$.u.constant) = IS_CONSTANT_ARRAY; } + static_scalar_value { zend_do_constant_expression(&$$, $1.u.ast TSRMLS_CC); } ; static_scalar_value: @@ -997,6 +995,8 @@ static_scalar_value: | namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } | T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } | T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } + | T_ARRAY '(' static_array_pair_list ')' { $$ = $3; } + | '[' static_array_pair_list ']' { $$ = $2; } | static_class_constant { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } | T_CLASS_C { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } | static_operation { $$ = $1; } @@ -1053,8 +1053,8 @@ scalar: static_array_pair_list: - /* empty */ { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); } - | non_empty_static_array_pair_list possible_comma { $$ = $1; } + /* empty */ { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } + | non_empty_static_array_pair_list possible_comma { zend_ast_dynamic_shrink(&$1.u.ast); $$ = $1; } ; possible_comma: @@ -1063,10 +1063,10 @@ possible_comma: ; non_empty_static_array_pair_list: - non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW static_scalar { zend_do_add_static_array_element(&$$, &$3, &$5); } - | non_empty_static_array_pair_list ',' static_scalar { zend_do_add_static_array_element(&$$, NULL, &$3); } - | static_scalar T_DOUBLE_ARROW static_scalar { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); zend_do_add_static_array_element(&$$, &$1, &$3); } - | static_scalar { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); zend_do_add_static_array_element(&$$, NULL, &$1); } + non_empty_static_array_pair_list ',' static_scalar_value T_DOUBLE_ARROW static_scalar_value { zend_ast_dynamic_add(&$$.u.ast, $3.u.ast); zend_ast_dynamic_add(&$$.u.ast, $5.u.ast); } + | non_empty_static_array_pair_list ',' static_scalar_value { zend_ast_dynamic_add(&$$.u.ast, NULL); zend_ast_dynamic_add(&$$.u.ast, $3.u.ast); } + | static_scalar_value T_DOUBLE_ARROW static_scalar_value { $$.u.ast = zend_ast_create_dynamic(ZEND_INIT_ARRAY); zend_ast_dynamic_add(&$$.u.ast, $1.u.ast); zend_ast_dynamic_add(&$$.u.ast, $3.u.ast); } + | static_scalar_value { $$.u.ast = zend_ast_create_dynamic(ZEND_INIT_ARRAY); zend_ast_dynamic_add(&$$.u.ast, NULL); zend_ast_dynamic_add(&$$.u.ast, $1.u.ast); } ; expr: diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index a18591fdf7..0f9e184b7e 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -36,8 +36,7 @@ ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC) CHECK_ZVAL_STRING_REL(zvalue); str_efree_rel(zvalue->value.str.val); break; - case IS_ARRAY: - case IS_CONSTANT_ARRAY: { + case IS_ARRAY: { TSRMLS_FETCH(); if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) { @@ -86,7 +85,6 @@ ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC) str_free(zvalue->value.str.val); break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: case IS_CONSTANT_AST: case IS_OBJECT: case IS_RESOURCE: @@ -128,8 +126,7 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC) zvalue->value.str.val = (char *) estrndup_rel(zvalue->value.str.val, zvalue->value.str.len); } break; - case IS_ARRAY: - case IS_CONSTANT_ARRAY: { + case IS_ARRAY: { zval *tmp; HashTable *original_ht = zvalue->value.ht; HashTable *tmp_ht = NULL; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index ed353edbac..08eb471d49 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5376,9 +5376,6 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) zval *tmp_ptr = &tmp; ZVAL_COPY_VALUE(&tmp, val); - if (Z_TYPE_P(val) == IS_CONSTANT_ARRAY) { - zval_copy_ctor(&tmp); - } INIT_PZVAL(&tmp); zval_update_constant(&tmp_ptr, NULL TSRMLS_CC); c.value = *tmp_ptr; diff --git a/ext/com_dotnet/com_variant.c b/ext/com_dotnet/com_variant.c index 4e044b20b8..3ddf016efb 100644 --- a/ext/com_dotnet/com_variant.c +++ b/ext/com_dotnet/com_variant.c @@ -160,7 +160,7 @@ PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, int codep case IS_RESOURCE: case IS_CONSTANT: - case IS_CONSTANT_ARRAY: + case IS_CONSTANT_AST: default: V_VT(v) = VT_NULL; break; diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 55f856be5a..faa3641eb1 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2209,8 +2209,10 @@ static void accel_fast_zval_ptr_dtor(zval **zval_ptr) #else switch (Z_TYPE_P(zvalue) & ~IS_CONSTANT_INDEX) { #endif - case IS_ARRAY: - case IS_CONSTANT_ARRAY: { +#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: +#endif + case IS_ARRAY: { TSRMLS_FETCH(); #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 6204290efe..ae33e765ca 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -237,19 +237,21 @@ static zend_ast *zend_ast_clone(zend_ast *ast TSRMLS_DC) if ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) { switch ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK)) { case IS_STRING: - case IS_CONSTANT: + case IS_CONSTANT: Z_STRVAL_P(node->u.val) = (char *) interned_estrndup(Z_STRVAL_P(ast->u.val), Z_STRLEN_P(ast->u.val)); break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: +#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: +#endif if (ast->u.val->value.ht && ast->u.val->value.ht != &EG(symbol_table)) { ALLOC_HASHTABLE(node->u.val->value.ht); zend_hash_clone_zval(node->u.val->value.ht, ast->u.val->value.ht, 0); } break; - case IS_CONSTANT_AST: - Z_AST_P(node->u.val) = zend_ast_clone(Z_AST_P(ast->u.val) TSRMLS_CC); - break; + case IS_CONSTANT_AST: + Z_AST_P(node->u.val) = zend_ast_clone(Z_AST_P(ast->u.val) TSRMLS_CC); + break; } } } else { @@ -295,20 +297,22 @@ static inline zval* zend_clone_zval(zval *src, int bind TSRMLS_DC) switch ((Z_TYPE_P(ret) & ~IS_CONSTANT_INDEX)) { #endif case IS_STRING: - case IS_CONSTANT: + case IS_CONSTANT: Z_STRVAL_P(ret) = (char *) interned_estrndup(Z_STRVAL_P(ret), Z_STRLEN_P(ret)); break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: +#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: +#endif if (ret->value.ht && ret->value.ht != &EG(symbol_table)) { ALLOC_HASHTABLE(ret->value.ht); zend_hash_clone_zval(ret->value.ht, src->value.ht, 0); } break; #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO - case IS_CONSTANT_AST: - Z_AST_P(ret) = zend_ast_clone(Z_AST_P(ret) TSRMLS_CC); - break; + case IS_CONSTANT_AST: + Z_AST_P(ret) = zend_ast_clone(Z_AST_P(ret) TSRMLS_CC); + break; #endif } } @@ -417,20 +421,22 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) switch ((Z_TYPE_P((zval*)p->pDataPtr) & ~IS_CONSTANT_INDEX)) { #endif case IS_STRING: - case IS_CONSTANT: + case IS_CONSTANT: Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->pDataPtr), Z_STRLEN_P((zval*)p->pDataPtr)); break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: +#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: +#endif if (((zval*)p->pDataPtr)->value.ht && ((zval*)p->pDataPtr)->value.ht != &EG(symbol_table)) { ALLOC_HASHTABLE(ppz->value.ht); zend_hash_clone_zval(ppz->value.ht, ((zval*)p->pDataPtr)->value.ht, 0); } break; #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO - case IS_CONSTANT_AST: - Z_AST_P(ppz) = zend_ast_clone(Z_AST_P(ppz) TSRMLS_CC); - break; + case IS_CONSTANT_AST: + Z_AST_P(ppz) = zend_ast_clone(Z_AST_P(ppz) TSRMLS_CC); + break; #endif } } diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 47f8f88312..17f8e8798f 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -174,7 +174,9 @@ static void zend_persist_zval(zval *z TSRMLS_DC) zend_accel_store_interned_string(z->value.str.val, z->value.str.len + 1); break; case IS_ARRAY: +#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO case IS_CONSTANT_ARRAY: +#endif zend_accel_store(z->value.ht, sizeof(HashTable)); zend_hash_persist(z->value.ht, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC); break; diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index c899ec8ac9..a01d834a4e 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -129,7 +129,9 @@ static uint zend_persist_zval_calc(zval *z TSRMLS_DC) ADD_INTERNED_STRING(Z_STRVAL_P(z), Z_STRLEN_P(z) + 1); break; case IS_ARRAY: +#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO case IS_CONSTANT_ARRAY: +#endif ADD_DUP_SIZE(z->value.ht, sizeof(HashTable)); ADD_SIZE(zend_hash_persist_calc(z->value.ht, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC)); break; diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index d36901d8c1..d867f433b2 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -5829,9 +5829,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'is enum'"); err = 1; } - if (!err && (Z_TYPE_PP(val) == IS_ARRAY || - Z_TYPE_PP(val) == IS_OBJECT || - Z_TYPE_PP(val) == IS_CONSTANT_ARRAY)) { + if (!err && (Z_TYPE_PP(val) == IS_ARRAY || Z_TYPE_PP(val) == IS_OBJECT)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects scalar values as field values"); err = 1; } diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 32e88510e7..b225a2d670 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -154,10 +154,8 @@ encode defaultEncoding[] = { {{IS_BOOL, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool}, {{IS_CONSTANT, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string}, {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, guess_array_map}, - {{IS_CONSTANT_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array}, {{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object}, {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, guess_array_map}, - {{IS_CONSTANT_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array}, {{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object}, {{XSD_STRING, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string}, diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c index 799b47b3ef..763ff69404 100644 --- a/ext/xmlrpc/xmlrpc-epi-php.c +++ b/ext/xmlrpc/xmlrpc-epi-php.c @@ -1431,7 +1431,6 @@ XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval** newvalue) /* {{{ */ type = xmlrpc_string; break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: type = xmlrpc_vector; break; case IS_OBJECT: -- 2.40.0