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
2 changes: 1 addition & 1 deletion Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -3825,7 +3825,7 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc
*strict_class = true;
ret = true;
} else {
if (error) zend_spprintf(error, 0, "class \"%.*s\" not found", (int)name_len, ZSTR_VAL(name));
if (error) zend_spprintf(error, 0, "class \"%pS\" not found", name);
}
ZSTR_ALLOCA_FREE(lcname, use_heap);
/* User error handlers may throw from deprecations above; do not report callable as valid. */
Expand Down
40 changes: 18 additions & 22 deletions Zend/zend_execute_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -1241,10 +1241,12 @@ 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) /* {{{ */
Expand All @@ -1263,17 +1265,11 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *
}

if (key) {
ZEND_ASSERT(ZSTR_LEN(name) != 0 && "Must not be an empty class name");
ZEND_ASSERT((ZSTR_VAL(name)[0] != '\\' || ZSTR_LEN(name) > 1) && "Class name must not be \"\\\"");
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 {
Expand Down Expand Up @@ -1308,27 +1304,27 @@ 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 (
(flags & ZEND_FETCH_CLASS_NO_AUTOLOAD)
|| !zend_autoload
/* The compiler is not-reentrant. Make sure we autoload only during run-time. */
|| zend_is_compiling()
) {
if (!key) {
zend_string_release_ex(lc_name, 0);
}
return NULL;
}

if (!zend_autoload) {
if (!key) {
zend_string_release_ex(lc_name, 0);
}
return NULL;
}

/* Verify class name before passing it to the autoloader. */
if (!key && !ZSTR_HAS_CE_CACHE(name) && !zend_is_valid_class_name(name)) {
/* Verify class name before passing it to the autoloader.
* We check for the lowercase name as it already in canonical form without leading \ */
if (!key && !ZSTR_HAS_CE_CACHE(name) && !zend_is_valid_class_name(lc_name)) {
zend_string_release_ex(lc_name, 0);
return NULL;
}

#if ZEND_DEBUG
ZEND_ASSERT(zend_is_valid_class_name(name) && "If lowercase name is valid the name must also be so");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if the compiler is smart enough to avoid this call in release builds

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry this took a while and it's now done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with debug build I get the assertion fired with just this (there are probably other cases)

''::foo();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, nice find, that should be fixed first.

#endif
if (zend_hash_add_empty_element(&EG(autoload_current_classnames), lc_name) == NULL) {
if (!key) {
zend_string_release_ex(lc_name, 0);
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