diff options
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/reflection/php_reflection.c | 39 | ||||
| -rw-r--r-- | ext/spl/spl_array.c | 102 | ||||
| -rw-r--r-- | ext/standard/array.c | 75 | ||||
| -rw-r--r-- | ext/standard/basic_functions.c | 9 | ||||
| -rw-r--r-- | ext/standard/http.c | 6 | ||||
| -rw-r--r-- | ext/standard/http_fopen_wrapper.c | 2 | ||||
| -rw-r--r-- | ext/standard/var.c | 114 | ||||
| -rw-r--r-- | ext/standard/var_unserializer.c | 78 | ||||
| -rw-r--r-- | ext/standard/var_unserializer.re | 18 |
9 files changed, 321 insertions, 122 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 148dae4378..53101b4623 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -223,14 +223,23 @@ static inline reflection_object *reflection_object_from_obj(zend_object *obj) /* static zend_object_handlers reflection_object_handlers; +static zval *_default_load_entry(zval *object, char *name, int name_len TSRMLS_DC) /* {{{ */ +{ + zval *value; + + if ((value = zend_hash_str_find_ind(Z_OBJPROP_P(object), name, name_len)) == NULL) { + return NULL; + } + return value; +} + static void _default_get_entry(zval *object, char *name, int name_len, zval *return_value TSRMLS_DC) /* {{{ */ { zval *value; - if ((value = zend_hash_str_find(Z_OBJPROP_P(object), name, name_len)) == NULL) { + if ((value = _default_load_entry(object, name, name_len TSRMLS_CC)) == NULL) { RETURN_FALSE; } - ZVAL_DUP(return_value, value); } /* }}} */ @@ -3102,7 +3111,7 @@ ZEND_METHOD(reflection_function, inNamespace) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) { + if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -3125,7 +3134,7 @@ ZEND_METHOD(reflection_function, getNamespaceName) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) { + if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -3148,7 +3157,7 @@ ZEND_METHOD(reflection_function, getShortName) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) { + if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -4654,7 +4663,7 @@ ZEND_METHOD(reflection_class, inNamespace) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) { + if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -4677,7 +4686,7 @@ ZEND_METHOD(reflection_class, getNamespaceName) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) { + if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -4700,7 +4709,7 @@ ZEND_METHOD(reflection_class, getShortName) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) { + if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -4937,17 +4946,16 @@ ZEND_METHOD(reflection_property, getValue) { reflection_object *intern; property_reference *ref; - zval *object, name; + zval *object, *name; zval *member_p = NULL; METHOD_NOTSTATIC(reflection_property_ptr); GET_REFLECTION_OBJECT_PTR(ref); if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && intern->ignore_visibility == 0) { - _default_get_entry(getThis(), "name", sizeof("name")-1, &name TSRMLS_CC); + name = _default_load_entry(getThis(), "name", sizeof("name")-1 TSRMLS_CC); zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, - "Cannot access non-public member %s::%s", intern->ce->name->val, Z_STRVAL(name)); - zval_dtor(&name); + "Cannot access non-public member %s::%s", intern->ce->name->val, Z_STRVAL_P(name)); return; } @@ -4984,7 +4992,7 @@ ZEND_METHOD(reflection_property, setValue) reflection_object *intern; property_reference *ref; zval *variable_ptr; - zval *object, name; + zval *object, *name; zval *value; zval *tmp; @@ -4992,10 +5000,9 @@ ZEND_METHOD(reflection_property, setValue) GET_REFLECTION_OBJECT_PTR(ref); if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) { - _default_get_entry(getThis(), "name", sizeof("name")-1, &name TSRMLS_CC); + name = _default_load_entry(getThis(), "name", sizeof("name")-1 TSRMLS_CC); zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, - "Cannot access non-public member %s::%s", intern->ce->name->val, Z_STRVAL(name)); - zval_dtor(&name); + "Cannot access non-public member %s::%s", intern->ce->name->val, Z_STRVAL_P(name)); return; } diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index c6634ecf8a..47f5fa2402 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -324,7 +324,27 @@ static zval *spl_array_get_dimension_ptr(int check_inherited, zval *object, zval case IS_STRING: offset_key = Z_STR_P(offset); fetch_dim_string: - if ((retval = (zend_symtable_find(ht, offset_key))) == NULL) { + retval = zend_symtable_find(ht, offset_key); + if (retval) { + if (Z_TYPE_P(retval) == IS_INDIRECT) { + retval = Z_INDIRECT_P(retval); + if (Z_TYPE_P(retval) == IS_UNDEF) { + switch (type) { + case BP_VAR_R: + zend_error(E_NOTICE, "Undefined index: %s", offset_key->val); + case BP_VAR_UNSET: + case BP_VAR_IS: + retval = &EG(uninitialized_zval); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined index: %s", offset_key->val); + case BP_VAR_W: { + ZVAL_NULL(retval); + } + } + } + } + } else { switch (type) { case BP_VAR_R: zend_error(E_NOTICE, "Undefined index: %s", offset_key->val); @@ -430,6 +450,7 @@ static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval if (check_inherited && intern->fptr_offset_set) { zval tmp; + if (!offset) { ZVAL_NULL(&tmp); offset = &tmp; @@ -464,7 +485,7 @@ static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited"); return; } - zend_symtable_update(ht, Z_STR_P(offset), value); + zend_symtable_update_ind(ht, Z_STR_P(offset), value); return; case IS_DOUBLE: case IS_RESOURCE: @@ -526,36 +547,29 @@ static void spl_array_unset_dimension_ex(int check_inherited, zval *object, zval zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset)); } } else { - if (zend_symtable_del(ht, Z_STR_P(offset)) == FAILURE) { - zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset)); - } else { - spl_array_object *obj = intern; - - while (1) { - if ((obj->ar_flags & SPL_ARRAY_IS_SELF) != 0) { - break; - } else if (Z_TYPE(obj->array) == IS_OBJECT) { - if ((obj->ar_flags & SPL_ARRAY_USE_OTHER) == 0) { - obj = Z_SPLARRAY_P(&obj->array); - break; - } else { - obj = Z_SPLARRAY_P(&obj->array); - } +//??? see below +#if 0 + if (zend_symtable_del_ind(ht, Z_STR_P(offset)) == FAILURE) { +#else + zval *data = zend_symtable_find(ht, Z_STR_P(offset)); + + if (data) { + if (Z_TYPE_P(data) == IS_INDIRECT) { + data = Z_INDIRECT_P(data); + if (Z_TYPE_P(data) == IS_UNDEF) { + zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset)); } else { - obj = NULL; - break; - } - } - if (obj) { - zend_property_info *property_info = zend_get_property_info(obj->std.ce, offset, 1 TSRMLS_CC); - - if (property_info && - (property_info->flags & ZEND_ACC_STATIC) == 0 && - property_info->offset >= 0) { - zval_ptr_dtor(&obj->std.properties_table[property_info->offset]); - ZVAL_UNDEF(&obj->std.properties_table[property_info->offset]); + zval_ptr_dtor(data); + ZVAL_UNDEF(data); } +//??? fix for ext/spl/tests/bug45614.phpt (may be fix is wrong) + spl_array_rewind(intern TSRMLS_CC); + } else if (zend_symtable_del(ht, Z_STR_P(offset)) == FAILURE) { + zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset)); } + } else { +#endif + zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset)); } } break; @@ -610,7 +624,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o case IS_STRING: { HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); - if ((tmp = zend_symtable_find(ht, Z_STR_P(offset))) != NULL) { + if ((tmp = zend_symtable_find_ind(ht, Z_STR_P(offset))) != NULL) { switch (check_empty) { case 0: return Z_TYPE_P(tmp) != IS_NULL; @@ -919,11 +933,16 @@ static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht TSR { zend_string *string_key; ulong num_key; + zval *data; if (Z_TYPE(intern->array) == IS_OBJECT) { do { if (zend_hash_get_current_key_ex(aht, &string_key, &num_key, 0, &intern->pos) == HASH_KEY_IS_STRING) { - if (!string_key->len || string_key->val[0]) { + data = zend_hash_get_current_data_ex(aht, &intern->pos); + if (data && Z_TYPE_P(data) == IS_INDIRECT && + Z_TYPE_P(data = Z_INDIRECT_P(data)) == IS_UNDEF) { + /* skip */ + } else if (!string_key->len || string_key->val[0]) { return SUCCESS; } } else { @@ -1002,7 +1021,11 @@ static zval *spl_array_it_get_current_data(zend_object_iterator *iter TSRMLS_DC) if (object->ar_flags & SPL_ARRAY_OVERLOADED_CURRENT) { return zend_user_it_get_current_data(iter TSRMLS_CC); } else { - return zend_hash_get_current_data_ex(aht, &object->pos); + zval *data = zend_hash_get_current_data_ex(aht, &object->pos); + if (Z_TYPE_P(data) == IS_INDIRECT) { + data = Z_INDIRECT_P(data); + } + return data; } } /* }}} */ @@ -1096,14 +1119,14 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK; } ar_flags |= SPL_ARRAY_USE_OTHER; - intern->array = *array; + ZVAL_COPY_VALUE(&intern->array, array); } else { if (Z_TYPE_P(array) != IS_OBJECT && Z_TYPE_P(array) != IS_ARRAY) { zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object, using empty array instead", 0 TSRMLS_CC); return; } zval_ptr_dtor(&intern->array); - intern->array = *array; + ZVAL_COPY_VALUE(&intern->array, array); } if (Z_TYPE_P(array) == IS_OBJECT && Z_OBJ_P(object) == Z_OBJ_P(array)) { intern->ar_flags |= SPL_ARRAY_IS_SELF; @@ -1507,6 +1530,12 @@ SPL_METHOD(Array, current) if ((entry = zend_hash_get_current_data_ex(aht, &intern->pos)) == NULL) { return; } + if (Z_TYPE_P(entry) == IS_INDIRECT) { + entry = Z_INDIRECT_P(entry); + if (Z_TYPE_P(entry) == IS_UNDEF) { + return; + } + } RETVAL_ZVAL(entry, 1, 0); } /* }}} */ @@ -1765,10 +1794,7 @@ SPL_METHOD(Array, unserialize) } /* copy members */ - if (!intern->std.properties) { - rebuild_object_properties(&intern->std); - } - zend_hash_copy(intern->std.properties, Z_ARRVAL(members), (copy_ctor_func_t) zval_add_ref); + object_properties_load(&intern->std, Z_ARRVAL(members)); zval_ptr_dtor(&members); /* done reading $serialized */ diff --git a/ext/standard/array.c b/ext/standard/array.c index 84c5f87a43..e2a2f02332 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -370,6 +370,12 @@ static int php_array_data_compare(const void *a, const void *b TSRMLS_DC) /* {{{ first = &f->val; second = &s->val; + if (Z_TYPE_P(first) == IS_INDIRECT) { + first = Z_INDIRECT_P(first); + } + if (Z_TYPE_P(second) == IS_INDIRECT) { + second = Z_INDIRECT_P(second); + } if (ARRAYG(compare_func)(&result, first, second TSRMLS_CC) == FAILURE) { return 0; } @@ -1056,6 +1062,13 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive /* Iterate through hash */ zend_hash_internal_pointer_reset(target_hash); while (!EG(exception) && (zv = zend_hash_get_current_data(target_hash)) != NULL) { + if (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + if (Z_TYPE_P(zv) == IS_UNDEF) { + zend_hash_move_forward(target_hash); + continue; + } + } ZVAL_COPY(&args[0], zv); if (recursive && (Z_TYPE(args[0]) == IS_ARRAY || @@ -1332,6 +1345,14 @@ PHP_FUNCTION(extract) while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), &pos)) != NULL) { zval final_name; + if (Z_TYPE_P(entry) == IS_INDIRECT) { + entry = Z_INDIRECT_P(entry); + if (Z_TYPE_P(entry) == IS_UNDEF) { + zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); + continue; + } + } + ZVAL_NULL(&final_name); key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &var_name, &num_key, 0, &pos); @@ -1410,6 +1431,9 @@ PHP_FUNCTION(extract) Z_ADDREF_P(entry); if ((orig_var = zend_hash_find(&EG(active_symbol_table)->ht, Z_STR(final_name))) != NULL) { + if (Z_TYPE_P(orig_var) == IS_INDIRECT) { + orig_var = Z_INDIRECT_P(orig_var); + } zval_ptr_dtor(orig_var); ZVAL_COPY_VALUE(orig_var, entry); } else { @@ -1417,7 +1441,7 @@ PHP_FUNCTION(extract) } } else { ZVAL_DUP(&data, entry); - ZEND_SET_SYMBOL_WITH_LENGTH(&EG(active_symbol_table)->ht, Z_STRVAL(final_name), Z_STRLEN(final_name), &data, 1, 0); + zend_set_local_var(Z_STRVAL(final_name), Z_STRLEN(final_name), &data, 1 TSRMLS_CC); } count++; } @@ -1442,12 +1466,11 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu entry = Z_REFVAL_P(entry); } if (Z_TYPE_P(entry) == IS_STRING) { - if ((value_ptr = zend_hash_find(eg_active_symbol_table, Z_STR_P(entry))) != NULL) { + if ((value_ptr = zend_hash_find_ind(eg_active_symbol_table, Z_STR_P(entry))) != NULL) { ZVAL_DUP(&data, value_ptr); zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); } - } - else if (Z_TYPE_P(entry) == IS_ARRAY) { + } else if (Z_TYPE_P(entry) == IS_ARRAY) { HashPosition pos; if ((Z_ARRVAL_P(entry)->nApplyCount > 1)) { @@ -1459,6 +1482,13 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(entry), &pos); while ((value_ptr = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) != NULL) { + if (Z_TYPE_P(value_ptr) == IS_INDIRECT) { + value_ptr = Z_INDIRECT_P(value_ptr); + if (Z_TYPE_P(value_ptr) == IS_UNDEF) { + zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos); + continue; + } + } php_compact_var(eg_active_symbol_table, return_value, value_ptr TSRMLS_CC); zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos); } @@ -1963,7 +1993,19 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end) } else { zend_hash_internal_pointer_reset(Z_ARRVAL_P(stack)); } - val = zend_hash_get_current_data(Z_ARRVAL_P(stack)); + while (1) { + val = zend_hash_get_current_data(Z_ARRVAL_P(stack)); + if (!val) { + return; + } else if (Z_TYPE_P(val) == IS_INDIRECT) { + val = Z_INDIRECT_P(val); + if (Z_TYPE_P(val) == IS_UNDEF) { + zend_hash_move_forward(Z_ARRVAL_P(stack)); + continue; + } + } + break; + } RETVAL_ZVAL_FAST(val); /* Delete the first or last value */ @@ -2045,9 +2087,6 @@ PHP_FUNCTION(array_unshift) * hashtable and replace it with new one */ new_hash = php_splice(Z_ARRVAL_P(stack), 0, 0, &args[0], argc, NULL); old_hash = *Z_ARRVAL_P(stack); - if (Z_ARRVAL_P(stack) == &EG(symbol_table).ht) { - zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC); - } *Z_ARRVAL_P(stack) = *new_hash; FREE_HASHTABLE(new_hash); zend_hash_destroy(&old_hash); @@ -2128,9 +2167,6 @@ PHP_FUNCTION(array_splice) /* Replace input array's hashtable with the new one */ old_hash = *Z_ARRVAL_P(array); - if (Z_ARRVAL_P(array) == &EG(symbol_table).ht) { - zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC); - } *Z_ARRVAL_P(array) = *new_hash; FREE_HASHTABLE(new_hash); zend_hash_destroy(&old_hash); @@ -2789,9 +2825,6 @@ PHP_FUNCTION(array_pad) /* Copy the result hash into return value */ old_hash = *Z_ARRVAL_P(return_value); - if (Z_ARRVAL_P(return_value) == &EG(symbol_table).ht) { - zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC); - } *Z_ARRVAL_P(return_value) = *new_hash; FREE_HASHTABLE(new_hash); zend_hash_destroy(&old_hash); @@ -2911,6 +2944,7 @@ PHP_FUNCTION(array_unique) for (i = 0, idx = 0; idx < Z_ARRVAL_P(array)->nNumUsed; idx++) { p = Z_ARRVAL_P(array)->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; + if (Z_TYPE(p->val) == IS_INDIRECT && Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF) continue; arTmp[i].b = *p; arTmp[i].i = i; i++; @@ -2954,6 +2988,12 @@ static int zval_compare(zval *a, zval *b TSRMLS_DC) /* {{{ */ first = a; second = b; + if (Z_TYPE_P(first) == IS_INDIRECT) { + first = Z_INDIRECT_P(first); + } + if (Z_TYPE_P(second) == IS_INDIRECT) { + second = Z_INDIRECT_P(second); + } if (string_compare_function(&result, first, second TSRMLS_CC) == FAILURE) { return 0; } @@ -2985,6 +3025,13 @@ static int zval_user_compare(zval *a, zval *b TSRMLS_DC) /* {{{ */ zval args[2]; zval retval; + if (Z_TYPE_P(a) == IS_INDIRECT) { + a = Z_INDIRECT_P(a); + } + if (Z_TYPE_P(b) == IS_INDIRECT) { + b = Z_INDIRECT_P(b); + } + ZVAL_COPY_VALUE(&args[0], a); ZVAL_COPY_VALUE(&args[1], b); diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index d666c025bb..2018c90b92 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -4265,13 +4265,16 @@ PHP_FUNCTION(getopt) * in order to be on the safe side, even though it is also available * from the symbol table. */ if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF && - ((args = zend_hash_str_find(HASH_OF(&PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv")-1)) != NULL || - (args = zend_hash_str_find(&EG(symbol_table).ht, "argv", sizeof("argv")-1)) != NULL) && Z_TYPE_P(args) == IS_ARRAY + ((args = zend_hash_str_find_ind(HASH_OF(&PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv")-1)) != NULL || + (args = zend_hash_str_find_ind(&EG(symbol_table).ht, "argv", sizeof("argv")-1)) != NULL) ) { int pos = 0; zval *entry; - argc = zend_hash_num_elements(Z_ARRVAL_P(args)); + if (Z_TYPE_P(args) != IS_ARRAY) { + RETURN_FALSE; + } + argc = zend_hash_num_elements(Z_ARRVAL_P(args)); /* Attempt to allocate enough memory to hold all of the arguments * and a trailing NULL */ diff --git a/ext/standard/http.c b/ext/standard/http.c index 62437f82d6..fc5727d7ce 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -82,6 +82,12 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error traversing form data array"); return FAILURE; } + if (Z_TYPE_P(zdata) == IS_INDIRECT) { + zdata = Z_INDIRECT_P(zdata); + if (Z_TYPE_P(zdata) == IS_UNDEF) { + continue; + } + } if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) { if (key_type == HASH_KEY_IS_STRING) { zend_string *ekey; diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 29e5db0ebf..0fdba30559 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -659,7 +659,7 @@ finish: if (header_init) { zval ztmp; array_init(&ztmp); - ZEND_SET_SYMBOL(&EG(active_symbol_table)->ht, "http_response_header", &ztmp); + zend_set_local_var("http_response_header", sizeof("http_response_header")-1, &ztmp, 0 TSRMLS_CC); } response_header = zend_hash_str_find(&EG(active_symbol_table)->ht, "http_response_header", sizeof("http_response_header")-1); diff --git a/ext/standard/var.c b/ext/standard/var.c index 8c2694bef7..9ea1119cea 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -35,12 +35,37 @@ #define COMMON (is_ref ? "&" : "") /* }}} */ +static uint zend_obj_num_elements(HashTable *ht) +{ + Bucket *p; + uint idx; + uint num; + + num = ht->nNumOfElements; + for (idx = 0; idx < ht->nNumUsed; idx++) { + p = ht->arData + idx; + if (Z_TYPE(p->val) == IS_UNDEF) continue; + if (Z_TYPE(p->val) == IS_INDIRECT) { + if (Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF) { + num--; + } + } + } + return num; +} + static int php_array_element_dump(zval *zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ { int level; level = va_arg(args, int); + if (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + if (Z_TYPE_P(zv) == IS_UNDEF) { + return 0; + } + } if (hash_key->key == NULL) { /* numeric key */ php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h); } else { /* string key */ @@ -60,6 +85,12 @@ static int php_object_property_dump(zval *zv TSRMLS_DC, int num_args, va_list ar level = va_arg(args, int); + if (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + if (Z_TYPE_P(zv) == IS_UNDEF) { + return 0; + } + } if (hash_key->key == NULL) { /* numeric key */ php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h); } else { /* string key */ @@ -136,10 +167,10 @@ again: if (Z_OBJ_HANDLER_P(struc, get_class_name)) { class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(struc, 0 TSRMLS_CC); - php_printf("%sobject(%s)#%d (%d) {\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_hash_num_elements(myht) : 0); + php_printf("%sobject(%s)#%d (%d) {\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0); STR_RELEASE(class_name); } else { - php_printf("%sobject(unknown class)#%d (%d) {\n", COMMON, Z_OBJ_HANDLE_P(struc), myht ? zend_hash_num_elements(myht) : 0); + php_printf("%sobject(unknown class)#%d (%d) {\n", COMMON, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0); } php_element_dump_func = php_object_property_dump; head_done: @@ -162,7 +193,7 @@ again: break; } case IS_REFERENCE: - //??? hide references with refcount==1 (for compatibility) +//??? hide references with refcount==1 (for compatibility) if (Z_REFCOUNT_P(struc) > 1) { is_ref = 1; } @@ -200,6 +231,12 @@ static int zval_array_element_dump(zval *zv TSRMLS_DC, int num_args, va_list arg level = va_arg(args, int); + if (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + if (Z_TYPE_P(zv) == IS_UNDEF) { + return 0; + } + } if (hash_key->key == NULL) { /* numeric key */ php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h); } else { /* string key */ @@ -225,6 +262,12 @@ static int zval_object_property_dump(zval *zv TSRMLS_DC, int num_args, va_list a level = va_arg(args, int); + if (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + if (Z_TYPE_P(zv) == IS_UNDEF) { + return 0; + } + } if (hash_key->key == NULL) { /* numeric key */ php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h); } else { /* string key */ @@ -259,14 +302,7 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level TSRMLS_DC) /* {{{ */ php_printf("%*c", level - 1, ' '); } - if (Z_TYPE_P(struc) == IS_REFERENCE) { -//??? hide references with refcount==1 (for compatibility) - if (Z_REFCOUNT_P(struc) > 1) { - is_ref = 1; - } - struc = Z_REFVAL_P(struc); - } - +again: switch (Z_TYPE_P(struc)) { case IS_BOOL: php_printf("%sbool(%s)\n", COMMON, Z_LVAL_P(struc)?"true":"false"); @@ -301,7 +337,7 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level TSRMLS_DC) /* {{{ */ return; } class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(struc, 0 TSRMLS_CC); - php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_hash_num_elements(myht) : 0, Z_REFCOUNT_P(struc)); + php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0, Z_REFCOUNT_P(struc)); STR_RELEASE(class_name); zval_element_dump_func = zval_object_property_dump; head_done: @@ -322,6 +358,13 @@ head_done: php_printf("%sresource(%ld) of type (%s) refcount(%u)\n", COMMON, Z_RES_P(struc)->handle, type_name ? type_name : "Unknown", Z_REFCOUNT_P(struc)); break; } + case IS_REFERENCE: +//??? hide references with refcount==1 (for compatibility) + if (Z_REFCOUNT_P(struc) > 1) { + is_ref = 1; + } + struc = Z_REFVAL_P(struc); + goto again; default: php_printf("%sUNKNOWN:0\n", COMMON); break; @@ -364,6 +407,12 @@ static int php_array_element_export(zval *zv TSRMLS_DC, int num_args, va_list ar level = va_arg(args, int); buf = va_arg(args, smart_str *); + if (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + if (Z_TYPE_P(zv) == IS_UNDEF) { + return 0; + } + } if (hash_key->key == NULL) { /* numeric key */ buffer_append_spaces(buf, level+1); smart_str_append_long(buf, (long) hash_key->h); @@ -400,6 +449,13 @@ static int php_object_element_export(zval *zv TSRMLS_DC, int num_args, va_list a level = va_arg(args, int); buf = va_arg(args, smart_str *); + if (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + if (Z_TYPE_P(zv) == IS_UNDEF) { + return 0; + } + } + buffer_append_spaces(buf, level + 2); if (hash_key->key != NULL) { const char *class_name; /* ignored, but must be passed to unmangle */ @@ -683,6 +739,12 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt } propers = Z_OBJPROP_P(struc); if ((d = zend_hash_find(propers, Z_STR_P(name))) != NULL) { + if (Z_TYPE_P(d) == IS_INDIRECT) { + d = Z_INDIRECT_P(d); + if (Z_TYPE_P(d) == IS_UNDEF) { + continue; + } + } php_var_serialize_string(buf, Z_STRVAL_P(name), Z_STRLEN_P(name)); php_var_serialize_intern(buf, d, var_hash TSRMLS_CC); } else { @@ -694,6 +756,13 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt do { priv_name = zend_mangle_property_name(ce->name->val, ce->name->len, Z_STRVAL_P(name), Z_STRLEN_P(name), ce->type & ZEND_INTERNAL_CLASS); if ((d = zend_hash_find(propers, priv_name)) != NULL) { + if (Z_TYPE_P(d) == IS_INDIRECT) { + d = Z_INDIRECT_P(d); + if (Z_TYPE_P(d) == IS_UNDEF) { + STR_FREE(prot_name); + break; + } + } php_var_serialize_string(buf, priv_name->val, priv_name->len); STR_FREE(priv_name); php_var_serialize_intern(buf, d, var_hash TSRMLS_CC); @@ -702,6 +771,13 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt STR_FREE(priv_name); prot_name = zend_mangle_property_name("*", 1, Z_STRVAL_P(name), Z_STRLEN_P(name), ce->type & ZEND_INTERNAL_CLASS); if ((d = zend_hash_find(propers, prot_name)) != NULL) { + if (Z_TYPE_P(d) == IS_INDIRECT) { + d = Z_INDIRECT_P(d); + if (Z_TYPE_P(d) == IS_UNDEF) { + STR_FREE(prot_name); + break; + } + } php_var_serialize_string(buf, prot_name->val, prot_name->len); STR_FREE(prot_name); php_var_serialize_intern(buf, d, var_hash TSRMLS_CC); @@ -873,10 +949,17 @@ again: zend_hash_internal_pointer_reset_ex(myht, &pos); for (;; zend_hash_move_forward_ex(myht, &pos)) { - i = zend_hash_get_current_key_ex(myht, &key, &index, 0, &pos); - if (i == HASH_KEY_NON_EXISTENT) { + data = zend_hash_get_current_data_ex(myht, &pos); + if (!data) { break; + } else if (Z_TYPE_P(data) == IS_INDIRECT) { + data = Z_INDIRECT_P(data); + if (Z_TYPE_P(data) == IS_UNDEF) { + continue; + } } + + i = zend_hash_get_current_key_ex(myht, &key, &index, 0, &pos); if (incomplete_class && strcmp(key->val, MAGIC_MEMBER) == 0) { continue; } @@ -892,8 +975,7 @@ again: /* we should still add element even if it's not OK, * since we already wrote the length of the array before */ - if ((data = zend_hash_get_current_data_ex(myht, &pos)) == NULL - || (Z_TYPE_P(data) == IS_ARRAY && Z_TYPE_P(struc) == IS_ARRAY && Z_ARR_P(data) == Z_ARR_P(struc)) + if ((Z_TYPE_P(data) == IS_ARRAY && Z_TYPE_P(struc) == IS_ARRAY && Z_ARR_P(data) == Z_ARR_P(struc)) || (Z_TYPE_P(data) == IS_ARRAY && Z_ARRVAL_P(data)->nApplyCount > 1) ) { smart_str_appendl(buf, "N;", 2); diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index 8e69338b02..13f645b58e 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -79,7 +79,7 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval *rval) (*var_hashx)->last_dtor = var_hash; } - Z_ADDREF_P(rval); + if (Z_REFCOUNTED_P(rval)) Z_ADDREF_P(rval); var_hash->data[var_hash->used_slots++] = rval; } @@ -306,7 +306,21 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long } else { /* object properties should include no integers */ convert_to_string(&key); - data = zend_hash_update(ht, Z_STR(key), &d); +//??? +#if 1 + data = zend_hash_update_ind(ht, Z_STR(key), &d); +#else + if ((data = zend_hash_find(ht, Z_STR(key))) != NULL) { + if (Z_TYPE_P(data) == IS_INDIRECT) { + data = Z_INDIRECT_P(data); + } + zval_ptr_dtor(data); +//??? var_push_dtor(var_hash, data); + ZVAL_UNDEF(data); + } else { + data = zend_hash_update(ht, Z_STR(key), &d); + } +#endif } zval_dtor(&key); @@ -428,7 +442,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) start = cursor; -#line 432 "ext/standard/var_unserializer.c" +#line 446 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -488,9 +502,9 @@ yy2: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: -#line 778 "ext/standard/var_unserializer.re" +#line 792 "ext/standard/var_unserializer.re" { return 0; } -#line 494 "ext/standard/var_unserializer.c" +#line 508 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; @@ -533,13 +547,13 @@ yy13: goto yy3; yy14: ++YYCURSOR; -#line 772 "ext/standard/var_unserializer.re" +#line 786 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } -#line 543 "ext/standard/var_unserializer.c" +#line 557 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; @@ -569,7 +583,7 @@ yy20: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 633 "ext/standard/var_unserializer.re" +#line 647 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; long elements; @@ -708,7 +722,7 @@ yy20: return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 712 "ext/standard/var_unserializer.c" +#line 726 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { @@ -733,7 +747,7 @@ yy27: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 625 "ext/standard/var_unserializer.re" +#line 639 "ext/standard/var_unserializer.re" { //??? INIT_PZVAL(rval); @@ -741,7 +755,7 @@ yy27: return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 745 "ext/standard/var_unserializer.c" +#line 759 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; @@ -762,7 +776,7 @@ yy34: yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; -#line 604 "ext/standard/var_unserializer.re" +#line 618 "ext/standard/var_unserializer.re" { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ @@ -783,7 +797,7 @@ yy34: return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 787 "ext/standard/var_unserializer.c" +#line 801 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; @@ -804,7 +818,7 @@ yy41: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 574 "ext/standard/var_unserializer.re" +#line 588 "ext/standard/var_unserializer.re" { size_t len, maxlen; //??? TODO: use zend_string* instead of char* @@ -834,7 +848,7 @@ yy41: efree(str); return 1; } -#line 838 "ext/standard/var_unserializer.c" +#line 852 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; @@ -855,7 +869,7 @@ yy48: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 547 "ext/standard/var_unserializer.re" +#line 561 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -882,7 +896,7 @@ yy48: ZVAL_STRINGL(rval, str, len); return 1; } -#line 886 "ext/standard/var_unserializer.c" +#line 900 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { @@ -970,7 +984,7 @@ yy61: } yy63: ++YYCURSOR; -#line 538 "ext/standard/var_unserializer.re" +#line 552 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 use_double: @@ -979,7 +993,7 @@ use_double: ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 983 "ext/standard/var_unserializer.c" +#line 997 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { @@ -1038,7 +1052,7 @@ yy73: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 522 "ext/standard/var_unserializer.re" +#line 536 "ext/standard/var_unserializer.re" { *p = YYCURSOR; @@ -1054,7 +1068,7 @@ yy73: return 1; } -#line 1058 "ext/standard/var_unserializer.c" +#line 1072 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; @@ -1081,7 +1095,7 @@ yy79: if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; -#line 496 "ext/standard/var_unserializer.re" +#line 510 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 int digits = YYCURSOR - start - 3; @@ -1107,7 +1121,7 @@ yy79: ZVAL_LONG(rval, parse_iv(start + 2)); return 1; } -#line 1111 "ext/standard/var_unserializer.c" +#line 1125 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; @@ -1115,22 +1129,22 @@ yy83: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 490 "ext/standard/var_unserializer.re" +#line 504 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_BOOL(rval, parse_iv(start + 2)); return 1; } -#line 1125 "ext/standard/var_unserializer.c" +#line 1139 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; -#line 484 "ext/standard/var_unserializer.re" +#line 498 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_NULL(rval); return 1; } -#line 1134 "ext/standard/var_unserializer.c" +#line 1148 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { @@ -1153,7 +1167,7 @@ yy91: if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; -#line 461 "ext/standard/var_unserializer.re" +#line 475 "ext/standard/var_unserializer.re" { long id; @@ -1176,7 +1190,7 @@ yy91: return 1; } -#line 1180 "ext/standard/var_unserializer.c" +#line 1194 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { @@ -1199,7 +1213,7 @@ yy97: if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; -#line 436 "ext/standard/var_unserializer.re" +#line 450 "ext/standard/var_unserializer.re" { long id; @@ -1224,9 +1238,9 @@ yy97: return 1; } -#line 1228 "ext/standard/var_unserializer.c" +#line 1242 "ext/standard/var_unserializer.c" } -#line 780 "ext/standard/var_unserializer.re" +#line 794 "ext/standard/var_unserializer.re" return 0; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index ae195ae88b..cda2dcd452 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -77,7 +77,7 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval *rval) (*var_hashx)->last_dtor = var_hash; } - Z_ADDREF_P(rval); + if (Z_REFCOUNTED_P(rval)) Z_ADDREF_P(rval); var_hash->data[var_hash->used_slots++] = rval; } @@ -310,7 +310,21 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long } else { /* object properties should include no integers */ convert_to_string(&key); - data = zend_hash_update(ht, Z_STR(key), &d); +//??? +#if 1 + data = zend_hash_update_ind(ht, Z_STR(key), &d); +#else + if ((data = zend_hash_find(ht, Z_STR(key))) != NULL) { + if (Z_TYPE_P(data) == IS_INDIRECT) { + data = Z_INDIRECT_P(data); + } + zval_ptr_dtor(data); +//??? var_push_dtor(var_hash, data); + ZVAL_UNDEF(data); + } else { + data = zend_hash_update(ht, Z_STR(key), &d); + } +#endif } zval_dtor(&key); |
