Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Zend/zend_builtin_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, bool only_subclass) /* {{{ *
RETURN_TRUE;
}

const zend_class_entry *ce = zend_lookup_class_ex(class_name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
const zend_class_entry *ce = zend_lookup_class_with_flags(class_name, ZEND_FETCH_CLASS_NO_AUTOLOAD);
if (!ce) {
RETURN_FALSE;
}
Expand Down Expand Up @@ -1227,7 +1227,7 @@ ZEND_FUNCTION(class_alias)
Z_PARAM_BOOL(autoload)
ZEND_PARSE_PARAMETERS_END();

ce = zend_lookup_class_ex(class_name, NULL, !autoload ? ZEND_FETCH_CLASS_NO_AUTOLOAD : 0);
ce = zend_lookup_class_with_flags(class_name, !autoload ? ZEND_FETCH_CLASS_NO_AUTOLOAD : 0);

if (ce) {
if (zend_register_class_alias_ex(ZSTR_VAL(alias_name), ZSTR_LEN(alias_name), ce, false) == SUCCESS) {
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -10059,8 +10059,8 @@ static void zend_compile_class_decl(znode *result, const zend_ast *ast, bool top
&& !(CG(compiler_options) & ZEND_COMPILE_WITHOUT_EXECUTION)) {
if (toplevel) {
if (extends_ast) {
zend_class_entry *parent_ce = zend_lookup_class_ex(
ce->parent_name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
zend_class_entry *parent_ce = zend_lookup_class_with_flags(
ce->parent_name, ZEND_FETCH_CLASS_NO_AUTOLOAD);

if (parent_ce
&& !zend_compile_ignore_class(parent_ce, ce->info.user.filename)) {
Expand Down
10 changes: 5 additions & 5 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,7 @@ static const zend_class_entry *resolve_single_class_type(zend_string *name, cons
} else if (zend_string_equals_ci(name, ZSTR_KNOWN(ZEND_STR_PARENT))) {
return self_ce->parent;
} else {
return zend_lookup_class_ex(name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
return zend_lookup_class_with_flags(name, ZEND_FETCH_CLASS_NO_AUTOLOAD);
}
}

Expand All @@ -1003,7 +1003,7 @@ static zend_always_inline const zend_class_entry *zend_ce_from_type(
if (ZSTR_HAS_CE_CACHE(name)) {
zend_class_entry *ce = ZSTR_GET_CE_CACHE(name);
if (!ce) {
ce = zend_lookup_class_ex(name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
ce = zend_lookup_class_with_flags(name, ZEND_FETCH_CLASS_NO_AUTOLOAD);
}
return ce;
}
Expand Down Expand Up @@ -1142,7 +1142,7 @@ static zend_always_inline zend_class_entry *zend_fetch_ce_from_type(
if (ZSTR_HAS_CE_CACHE(name)) {
ce = ZSTR_GET_CE_CACHE(name);
if (!ce) {
ce = zend_lookup_class_ex(name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
ce = zend_lookup_class_with_flags(name, ZEND_FETCH_CLASS_NO_AUTOLOAD);
if (UNEXPECTED(!ce)) {
/* Cannot resolve */
return NULL;
Expand Down Expand Up @@ -5146,7 +5146,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s

lcname = zend_string_init(ZSTR_VAL(function), cname_length, 0);

called_scope = zend_fetch_class_by_name(lcname, NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
called_scope = zend_fetch_class(lcname, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
if (UNEXPECTED(called_scope == NULL)) {
zend_string_release_ex(lcname, 0);
return NULL;
Expand Down Expand Up @@ -5270,7 +5270,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(const z
}

if (Z_TYPE_P(obj) == IS_STRING) {
zend_class_entry *called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
zend_class_entry *called_scope = zend_fetch_class(Z_STR_P(obj), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);

if (UNEXPECTED(called_scope == NULL)) {
return NULL;
Expand Down
13 changes: 10 additions & 3 deletions Zend/zend_execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,16 @@ ZEND_API void zend_init_code_execute_data(zend_execute_data *execute_data, zend_
ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value);
ZEND_API void execute_ex(zend_execute_data *execute_data);
ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value);

ZEND_API bool zend_is_valid_class_name(const zend_string *name);
ZEND_API zend_class_entry *zend_lookup_class(zend_string *name);
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *lcname, uint32_t flags);
ZEND_API zend_class_entry *zend_lookup_class_with_flags(zend_string *name, uint32_t flags);
ZEND_ATTRIBUTE_NONNULL ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *lc_name, uint32_t flags);

static zend_always_inline zend_class_entry *zend_lookup_class(zend_string *name) /* {{{ */
{
return zend_lookup_class_with_flags(name, 0);
}

ZEND_API zend_class_entry *zend_get_called_scope(const zend_execute_data *ex);
ZEND_API zend_object *zend_get_this_object(const zend_execute_data *ex);
ZEND_API zend_result zend_eval_string(const char *str, zval *retval_ptr, const char *string_name);
Expand Down Expand Up @@ -529,7 +536,7 @@ ZEND_API void zend_unset_timeout(void);
ZEND_NORETURN ZEND_API void ZEND_FASTCALL zend_timeout(void);
ZEND_API zend_class_entry *zend_fetch_class(zend_string *class_name, uint32_t fetch_type);
ZEND_API zend_class_entry *zend_fetch_class_with_scope(zend_string *class_name, uint32_t fetch_type, zend_class_entry *scope);
ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *lcname, uint32_t fetch_type);
ZEND_ATTRIBUTE_NONNULL ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *lcname, uint32_t fetch_type);

ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name);
ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len);
Expand Down
80 changes: 29 additions & 51 deletions Zend/zend_execute_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -1220,19 +1220,22 @@ ZEND_API bool zend_is_valid_class_name(const zend_string *name) {
for (size_t i = 0; i < ZSTR_LEN(name); i++) {
unsigned char c = ZSTR_VAL(name)[i];
if (!ZEND_BIT_TEST(valid_chars, c)) {
return 0;
return false;
}
}
return 1;

/* An empty string is *not* a valid class name */
return ZSTR_LEN(name);
}

ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *key, uint32_t flags) /* {{{ */
ZEND_ATTRIBUTE_NONNULL ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *lc_name, uint32_t flags) /* {{{ */
{
zend_class_entry *ce = NULL;
zend_string *lc_name;
zend_string *autoload_name;
uint32_t ce_cache = 0;

ZEND_ASSERT(ZSTR_VAL(lc_name)[0] != '\\' && "lowercase name must not start with \\");

if (ZSTR_HAS_CE_CACHE(name) && ZSTR_VALID_CE_CACHE(name)) {
ce_cache = GC_REFCOUNT(name);
ce = GET_CE_CACHE(ce_cache);
Expand All @@ -1241,30 +1244,10 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *
}
}

if (key) {
lc_name = key;
} else {
if (!ZSTR_LEN(name)) {
return NULL;
}

if (ZSTR_VAL(name)[0] == '\\') {
if (ZSTR_LEN(name) == 1) {
/* A lone namespace separator names no class, e.g. is_callable('\::method'). */
return NULL;
}
lc_name = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
} else {
lc_name = zend_string_tolower(name);
}
}

/* Note: we do not validate the class name because of anonymous classes
* having a name that is not compatible by the rules of zend_is_valid_class_name() */
ce = zend_hash_find_ptr(EG(class_table), lc_name);
if (ce) {
if (!key) {
zend_string_release_ex(lc_name, 0);
}
if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_LINKED))) {
if ((flags & ZEND_FETCH_CLASS_ALLOW_UNLINKED) ||
((flags & ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED) &&
Expand All @@ -1287,31 +1270,21 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *
return ce;
}

/* The compiler is not-reentrant. Make sure we autoload only during run-time. */
if ((flags & ZEND_FETCH_CLASS_NO_AUTOLOAD) || zend_is_compiling()) {
if (!key) {
zend_string_release_ex(lc_name, 0);
}
if (UNEXPECTED(!zend_is_valid_class_name(lc_name))) {
return NULL;
}
ZEND_ASSERT(zend_is_valid_class_name(name) && "If lowercase name is valid the name must also be so");

if (!zend_autoload) {
if (!key) {
zend_string_release_ex(lc_name, 0);
}
/* The compiler is not-reentrant. Make sure we autoload only during run-time. */
if ((flags & ZEND_FETCH_CLASS_NO_AUTOLOAD) || zend_is_compiling()) {
return NULL;
}

/* Verify class name before passing it to the autoloader. */
if (!key && !ZSTR_HAS_CE_CACHE(name) && !zend_is_valid_class_name(name)) {
zend_string_release_ex(lc_name, 0);
if (!zend_autoload) {
return NULL;
}

if (zend_hash_add_empty_element(&EG(autoload_current_classnames), lc_name) == NULL) {
if (!key) {
zend_string_release_ex(lc_name, 0);
}
return NULL;
}

Expand All @@ -1332,9 +1305,6 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *
zend_string_release_ex(autoload_name, 0);
zend_hash_del(&EG(autoload_current_classnames), lc_name);

if (!key) {
zend_string_release_ex(lc_name, 0);
}
if (ce) {
ZEND_ASSERT(!CG(in_compilation));
if (ce_cache) {
Expand All @@ -1345,11 +1315,19 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *
}
/* }}} */

ZEND_API zend_class_entry *zend_lookup_class(zend_string *name) /* {{{ */
ZEND_API zend_class_entry *zend_lookup_class_with_flags(zend_string *name, uint32_t flags)
{
return zend_lookup_class_ex(name, NULL, 0);
zend_string *lc_name;
if (ZSTR_VAL(name)[0] == '\\') {
lc_name = zend_string_alloc(ZSTR_LEN(name) - 1, false);
zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
} else {
lc_name = zend_string_tolower(name);
}
zend_class_entry *ce = zend_lookup_class_ex(name, lc_name, flags);
zend_string_release_ex(lc_name, false);
return ce;
}
/* }}} */

ZEND_API zend_class_entry *zend_get_called_scope(const zend_execute_data *ex) /* {{{ */
{
Expand Down Expand Up @@ -1800,7 +1778,7 @@ zend_class_entry *zend_fetch_class(zend_string *class_name, uint32_t fetch_type)
break;
}

ce = zend_lookup_class_ex(class_name, NULL, fetch_type);
ce = zend_lookup_class_with_flags(class_name, fetch_type);
if (!ce) {
report_class_fetch_error(class_name, fetch_type);
return NULL;
Expand Down Expand Up @@ -1834,17 +1812,17 @@ zend_class_entry *zend_fetch_class_with_scope(
default: ZEND_UNREACHABLE();
}

ce = zend_lookup_class_ex(class_name, NULL, fetch_type);
ce = zend_lookup_class_with_flags(class_name, fetch_type);
if (!ce) {
report_class_fetch_error(class_name, fetch_type);
return NULL;
}
return ce;
}

zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *key, uint32_t fetch_type) /* {{{ */
ZEND_ATTRIBUTE_NONNULL ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *lcname, uint32_t fetch_type) /* {{{ */
{
zend_class_entry *ce = zend_lookup_class_ex(class_name, key, fetch_type);
zend_class_entry *ce = zend_lookup_class_ex(class_name, lcname, fetch_type);
if (!ce) {
report_class_fetch_error(class_name, fetch_type);
return NULL;
Expand Down
10 changes: 6 additions & 4 deletions Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ static zend_class_entry *lookup_class_ex(
return ce;
}

ce = zend_lookup_class_ex(
name, NULL, ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD);
ce = zend_lookup_class_with_flags(
name, ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD);

if (!CG(in_compilation) || in_preload) {
if (ce) {
Expand Down Expand Up @@ -319,7 +319,7 @@ static bool unlinked_instanceof(const zend_class_entry *ce1, const zend_class_en
if (ce1->ce_flags & ZEND_ACC_RESOLVED_PARENT) {
parent_ce = ce1->parent;
} else {
parent_ce = zend_lookup_class_ex(ce1->parent_name, NULL,
parent_ce = zend_lookup_class_with_flags(ce1->parent_name,
ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD);
}

Expand Down Expand Up @@ -3555,9 +3555,11 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));

if (ce->parent_name) {
zend_string *lc_name = lc_parent_name ? zend_string_copy(lc_parent_name) : zend_string_tolower(ce->parent_name);
parent = zend_fetch_class_by_name(
ce->parent_name, lc_parent_name,
ce->parent_name, lc_name,
ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED | ZEND_FETCH_CLASS_EXCEPTION);
zend_string_release(lc_name);
if (!parent) {
check_unrecoverable_load_failure(ce);
return NULL;
Expand Down
4 changes: 2 additions & 2 deletions ext/opcache/ZendAccelerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -2512,7 +2512,7 @@ static zend_always_inline zend_inheritance_cache_entry* zend_accel_inheritance_c
}
if (found && entry->dependencies) {
for (i = 0; i < entry->dependencies_count; i++) {
const zend_class_entry *dependency_ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
const zend_class_entry *dependency_ce = zend_lookup_class_with_flags(entry->dependencies[i].name, ZEND_FETCH_CLASS_NO_AUTOLOAD);

if (dependency_ce != entry->dependencies[i].ce) {
if (!dependency_ce) {
Expand Down Expand Up @@ -2560,7 +2560,7 @@ static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce,
}

for (uint32_t i = 0; i < entry->dependencies_count; i++) {
const zend_class_entry *dependency_ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, 0);
const zend_class_entry *dependency_ce = zend_lookup_class(entry->dependencies[i].name);

if (dependency_ce == NULL) {
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion ext/opcache/jit/zend_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ static zend_class_entry* zend_get_known_class(const zend_op_array *op_array, con

ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
class_name = Z_STR_P(zv);
ce = zend_lookup_class_ex(class_name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
ce = zend_lookup_class_with_flags(class_name, ZEND_FETCH_CLASS_NO_AUTOLOAD);
if (ce && (ce->type == ZEND_INTERNAL_CLASS || ce->info.user.filename != op_array->filename)) {
ce = NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion ext/spl/php_spl.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ ZEND_TLS zend_string *spl_autoload_extensions;

static zend_class_entry * spl_find_ce_by_name(zend_string *name, bool autoload)
{
zend_class_entry *ce = zend_lookup_class_ex(name, NULL, autoload ? 0 : ZEND_FETCH_CLASS_NO_AUTOLOAD);
zend_class_entry *ce = zend_lookup_class_with_flags(name, autoload ? 0 : ZEND_FETCH_CLASS_NO_AUTOLOAD);
if (ce == NULL) {
php_error_docref(NULL, E_WARNING, "Class %s does not exist%s", ZSTR_VAL(name), autoload ? " and could not be loaded" : "");
return NULL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ try {

?>
--EXPECT--
ValueError: unserialize(): Option "allowed_classes" must be an array of class names, "" given
ValueError: unserialize(): Option "allowed_classes" must be an array of class names, " whitespace " given
ValueError: unserialize(): Option "allowed_classes" must be an array of class names, "name
with whitespace" given
Expand Down
Loading