diff options
| author | Zeev Suraski <zeev@php.net> | 2001-07-16 11:41:06 +0000 |
|---|---|---|
| committer | Zeev Suraski <zeev@php.net> | 2001-07-16 11:41:06 +0000 |
| commit | fb532ba52b2f462f3e80f3f21a96044ae29703c5 (patch) | |
| tree | a9a5d1baa5d71fd891d933d446d15d824ddeab16 | |
| parent | f272469b4c1514f6640c73ea012e484e188523ee (diff) | |
| download | php-git-fb532ba52b2f462f3e80f3f21a96044ae29703c5.tar.gz | |
Fix bug #10467
| -rw-r--r-- | Zend/zend.h | 4 | ||||
| -rw-r--r-- | Zend/zend_compile.c | 3 | ||||
| -rw-r--r-- | Zend/zend_execute_API.c | 40 |
3 files changed, 44 insertions, 3 deletions
diff --git a/Zend/zend.h b/Zend/zend.h index 8dddb6486d..590b5167e0 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -285,6 +285,10 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length); /* Special data type to temporarily mark large numbers */ #define FLAG_IS_BC 10 /* for parser internal use only */ +/* Ugly hack to support constants as static array indices */ +#define IS_CONSTANT_INDEX 0x80 + + /* overloaded elements data types */ #define OE_IS_ARRAY (1<<0) #define OE_IS_OBJECT (1<<1) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index d43e64c97a..6514355b66 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1807,6 +1807,9 @@ void zend_do_add_static_array_element(znode *result, znode *offset, znode *expr) if (offset) { switch (offset->u.constant.type) { case IS_CONSTANT: + /* Ugly hack to denote that this value has a constant index */ + element->type |= IS_CONSTANT_INDEX; + /* break missing intentionally */ case IS_STRING: zend_hash_update(result->u.constant.value.ht, offset->u.constant.value.str.val, offset->u.constant.value.str.len+1, &element, sizeof(zval *), NULL); zval_dtor(&offset->u.constant); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 67e2b0f12b..435913a916 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -275,9 +275,9 @@ ZEND_API int zval_update_constant(zval **pp, void *arg) { zval *p = *pp; zend_bool inline_change = (zend_bool) (unsigned long) arg; + zval const_value; if (p->type == IS_CONSTANT) { - zval c; int refcount; SEPARATE_ZVAL(pp); @@ -285,7 +285,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg) refcount = p->refcount; - if (!zend_get_constant(p->value.str.val, p->value.str.len, &c)) { + if (!zend_get_constant(p->value.str.val, p->value.str.len, &const_value)) { zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", p->value.str.val, p->value.str.val); @@ -297,14 +297,48 @@ ZEND_API int zval_update_constant(zval **pp, void *arg) if (inline_change) { STR_FREE(p->value.str.val); } - *p = c; + *p = const_value; } INIT_PZVAL(p); p->refcount = refcount; } else if (p->type == IS_CONSTANT_ARRAY) { + zval **element; + char *str_index; + ulong str_index_len, num_index; + SEPARATE_ZVAL(pp); p = *pp; p->type = IS_ARRAY; + + /* First go over the array and see if there are any constant indices */ + zend_hash_internal_pointer_reset(p->value.ht); + while (zend_hash_get_current_data(p->value.ht, (void **) &element)==SUCCESS) { + if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) { + zend_hash_move_forward(p->value.ht); + continue; + } + Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX; + if (zend_hash_get_current_key_ex(p->value.ht, &str_index, &str_index_len, &num_index, 0, NULL)!=HASH_KEY_IS_STRING) { + zend_hash_move_forward(p->value.ht); + continue; + } + if (!zend_get_constant(str_index, str_index_len-1, &const_value)) { + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); + zend_hash_move_forward(p->value.ht); + continue; + } + switch (const_value.type) { + case IS_STRING: + zend_hash_update(p->value.ht, const_value.value.str.val, const_value.value.str.len+1, element, sizeof(zval *), NULL); + (*element)->refcount++; + break; + case IS_LONG: + zend_hash_index_update(p->value.ht, const_value.value.lval, element, sizeof(zval *), NULL); + (*element)->refcount++; + break; + } + zend_hash_del(p->value.ht, str_index, str_index_len); + } zend_hash_apply_with_argument(p->value.ht, (int (*)(void *,void *)) zval_update_constant, (void *) 1); } return 0; |
