Browse Source

Fix bug #10467

experimental/zts_stdc_scanners
Zeev Suraski 25 years ago
parent
commit
fb532ba52b
  1. 4
      Zend/zend.h
  2. 3
      Zend/zend_compile.c
  3. 40
      Zend/zend_execute_API.c

4
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)

3
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);

40
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;

Loading…
Cancel
Save