diff options
Diffstat (limited to 'ext/standard/array.c')
-rw-r--r-- | ext/standard/array.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c index c9a82390a4..a2cc00dc30 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1843,8 +1843,11 @@ PHP_FUNCTION(extract) if (var_exists && ZSTR_LEN(var_name) == sizeof("GLOBALS")-1 && !strcmp(ZSTR_VAL(var_name), "GLOBALS")) { break; } - if (var_exists && ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this") && EG(scope) && ZSTR_LEN(EG(scope)->name) != 0) { - break; + if (var_exists && ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) { + zend_class_entry *scope = zend_get_executed_scope(); + if (scope && ZSTR_LEN(scope->name) != 0) { + break; + } } ZVAL_STR_COPY(&final_name, var_name); break; @@ -2023,6 +2026,7 @@ PHP_FUNCTION(array_fill) Z_ARRVAL_P(return_value)->nNumUsed = start_key + num; Z_ARRVAL_P(return_value)->nNumOfElements = num; Z_ARRVAL_P(return_value)->nInternalPointer = start_key; + Z_ARRVAL_P(return_value)->nNextFreeElement = start_key + num; if (Z_REFCOUNTED_P(val)) { GC_REFCOUNT(Z_COUNTED_P(val)) += num; @@ -3515,15 +3519,20 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) zval *prop = NULL; if (Z_TYPE_P(data) == IS_OBJECT) { - zend_string *key = zval_get_string(name); + if (!Z_OBJ_HANDLER_P(data, has_property) || !Z_OBJ_HANDLER_P(data, read_property)) { + return NULL; + } - if (!Z_OBJ_HANDLER_P(data, has_property) || Z_OBJ_HANDLER_P(data, has_property)(data, name, 1, NULL)) { - prop = zend_read_property(Z_OBJCE_P(data), data, ZSTR_VAL(key), ZSTR_LEN(key), 1, rv); + /* The has_property check is first performed in "exists" mode (which returns true for + * properties that are null but exist) and then in "has" mode to handle objects that + * implement __isset (which is not called in "exists" mode). */ + if (Z_OBJ_HANDLER_P(data, has_property)(data, name, 2, NULL) + || Z_OBJ_HANDLER_P(data, has_property)(data, name, 0, NULL)) { + prop = Z_OBJ_HANDLER_P(data, read_property)(data, name, BP_VAR_R, NULL, rv); } - zend_string_release(key); } else if (Z_TYPE_P(data) == IS_ARRAY) { if (Z_TYPE_P(name) == IS_STRING) { - prop = zend_hash_find(Z_ARRVAL_P(data), Z_STR_P(name)); + prop = zend_symtable_find(Z_ARRVAL_P(data), Z_STR_P(name)); } else if (Z_TYPE_P(name) == IS_LONG) { prop = zend_hash_index_find(Z_ARRVAL_P(data), Z_LVAL_P(name)); } |