summaryrefslogtreecommitdiff
path: root/Zend/zend_builtin_functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_builtin_functions.c')
-rw-r--r--Zend/zend_builtin_functions.c75
1 files changed, 47 insertions, 28 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 8d0a41ca73..811ae08ee2 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -256,9 +256,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1)
ZEND_END_ARG_INFO()
#if ZEND_DEBUG
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_zend_test_func, IS_ARRAY, NULL, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_zend_test_func, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_zend_test_func2, IS_ARRAY, NULL, 1)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_zend_test_func2, IS_ARRAY, 1)
ZEND_END_ARG_INFO()
#endif
@@ -836,7 +836,7 @@ static int validate_constant_array(HashTable *ht) /* {{{ */
ZVAL_DEREF(val);
if (Z_REFCOUNTED_P(val)) {
if (Z_TYPE_P(val) == IS_ARRAY) {
- if (!Z_IMMUTABLE_P(val)) {
+ if (Z_REFCOUNTED_P(val)) {
if (Z_ARRVAL_P(val)->u.v.nApplyCount > 0) {
zend_error(E_WARNING, "Constants cannot be recursive arrays");
ret = 0;
@@ -874,7 +874,7 @@ static void copy_constant_array(zval *dst, zval *src) /* {{{ */
new_val = zend_hash_index_add_new(Z_ARRVAL_P(dst), idx, val);
}
if (Z_TYPE_P(val) == IS_ARRAY) {
- if (!Z_IMMUTABLE_P(val)) {
+ if (Z_REFCOUNTED_P(val)) {
copy_constant_array(new_val, val);
}
} else if (Z_REFCOUNTED_P(val)) {
@@ -932,7 +932,7 @@ repeat:
val = &val_free;
break;
case IS_ARRAY:
- if (!Z_IMMUTABLE_P(val)) {
+ if (Z_REFCOUNTED_P(val)) {
if (!validate_constant_array(Z_ARRVAL_P(val))) {
RETURN_FALSE;
} else {
@@ -1001,7 +1001,7 @@ ZEND_FUNCTION(get_class)
{
zval *obj = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|o!", &obj) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|o", &obj) == FAILURE) {
RETURN_FALSE;
}
@@ -1231,6 +1231,7 @@ ZEND_FUNCTION(get_object_vars)
HashTable *properties;
zend_string *key;
zend_object *zobj;
+ zend_ulong num_key;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_OBJECT(obj)
@@ -1251,32 +1252,50 @@ ZEND_FUNCTION(get_object_vars)
if (!zobj->ce->default_properties_count && properties == zobj->properties && !ZEND_HASH_GET_APPLY_COUNT(properties)) {
/* fast copy */
if (EXPECTED(zobj->handlers == &std_object_handlers)) {
- if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
- GC_REFCOUNT(properties)++;
- }
- RETURN_ARR(properties);
+ RETURN_ARR(zend_proptable_to_symtable(properties, 0));
}
- RETURN_ARR(zend_array_dup(properties));
+ RETURN_ARR(zend_proptable_to_symtable(properties, 1));
} else {
array_init_size(return_value, zend_hash_num_elements(properties));
- ZEND_HASH_FOREACH_STR_KEY_VAL_IND(properties, key, value) {
- if (key) {
- if (zend_check_property_access(zobj, key) == SUCCESS) {
- if (Z_ISREF_P(value) && Z_REFCOUNT_P(value) == 1) {
- value = Z_REFVAL_P(value);
- }
- if (Z_REFCOUNTED_P(value)) {
- Z_ADDREF_P(value);
- }
- if (ZSTR_VAL(key)[0] == 0) {
- const char *prop_name, *class_name;
- size_t prop_len;
- zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_len);
- zend_hash_str_add_new(Z_ARRVAL_P(return_value), prop_name, prop_len, value);
- } else {
- zend_hash_add_new(Z_ARRVAL_P(return_value), key, value);
- }
+ ZEND_HASH_FOREACH_KEY_VAL(properties, num_key, key, value) {
+ zend_bool unmangle = 0;
+ if (Z_TYPE_P(value) == IS_INDIRECT) {
+ value = Z_INDIRECT_P(value);
+ if (UNEXPECTED(Z_ISUNDEF_P(value))) {
+ continue;
+ }
+
+ ZEND_ASSERT(key);
+ if (zend_check_property_access(zobj, key) == FAILURE) {
+ continue;
+ }
+ unmangle = 1;
+ }
+
+ if (Z_ISREF_P(value) && Z_REFCOUNT_P(value) == 1) {
+ value = Z_REFVAL_P(value);
+ }
+ Z_TRY_ADDREF_P(value);
+
+ if (UNEXPECTED(!key)) {
+ /* This case is only possible due to loopholes, e.g. ArrayObject */
+ zend_hash_index_add(Z_ARRVAL_P(return_value), num_key, value);
+ } else if (unmangle && ZSTR_VAL(key)[0] == 0) {
+ const char *prop_name, *class_name;
+ size_t prop_len;
+ zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_len);
+ /* We assume here that a mangled property name is never
+ * numeric. This is probably a safe assumption, but
+ * theoretically someone might write an extension with
+ * private, numeric properties. Well, too bad.
+ */
+ zend_hash_str_add_new(Z_ARRVAL_P(return_value), prop_name, prop_len, value);
+ } else {
+ if (ZEND_HANDLE_NUMERIC(key, num_key)) {
+ zend_hash_index_add(Z_ARRVAL_P(return_value), num_key, value);
+ } else {
+ zend_hash_add_new(Z_ARRVAL_P(return_value), key, value);
}
}
} ZEND_HASH_FOREACH_END();