Skip to content

Commit 0ef5fd3

Browse files
committed
Make name qualifying checks safe
1 parent 865b011 commit 0ef5fd3

File tree

3 files changed

+17
-14
lines changed

3 files changed

+17
-14
lines changed

Zend/zend_ast.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1370,9 +1370,9 @@ static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int
13701370
zval *zv = zend_ast_get_zval(ast);
13711371

13721372
if (Z_TYPE_P(zv) == IS_STRING) {
1373-
if (ast->attr == ZEND_NAME_FQ) {
1373+
if (NAME_QUAL(ast->attr) == ZEND_NAME_FQ) {
13741374
smart_str_appendc(str, '\\');
1375-
} else if (ast->attr == ZEND_NAME_RELATIVE) {
1375+
} else if (NAME_QUAL(ast->attr) == ZEND_NAME_RELATIVE) {
13761376
smart_str_appends(str, "namespace\\");
13771377
}
13781378
smart_str_append(str, Z_STR_P(zv));

Zend/zend_compile.c

+13-12
Original file line numberDiff line numberDiff line change
@@ -1080,12 +1080,12 @@ static zend_string *zend_resolve_non_class_name(
10801080
return zend_string_init(ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1, 0);
10811081
}
10821082

1083-
if (type == ZEND_NAME_FQ) {
1083+
if (NAME_QUAL(type) == ZEND_NAME_FQ) {
10841084
*is_fully_qualified = 1;
10851085
return zend_string_copy(name);
10861086
}
10871087

1088-
if (type == ZEND_NAME_RELATIVE) {
1088+
if (NAME_QUAL(type) == ZEND_NAME_RELATIVE) {
10891089
*is_fully_qualified = 1;
10901090
return zend_prefix_with_ns(name);
10911091
}
@@ -1142,23 +1142,24 @@ static zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /*
11421142
char *compound;
11431143

11441144
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
1145-
if (type == ZEND_NAME_FQ) {
1145+
if (NAME_QUAL(type) == ZEND_NAME_FQ) {
11461146
zend_error_noreturn(E_COMPILE_ERROR,
11471147
"'\\%s' is an invalid class name", ZSTR_VAL(name));
11481148
}
1149-
if (type == ZEND_NAME_RELATIVE) {
1149+
if (NAME_QUAL(type) == ZEND_NAME_RELATIVE) {
11501150
zend_error_noreturn(E_COMPILE_ERROR,
11511151
"'namespace\\%s' is an invalid class name", ZSTR_VAL(name));
11521152
}
1153-
ZEND_ASSERT(type == ZEND_NAME_NOT_FQ);
1153+
1154+
ZEND_ASSERT(NAME_QUAL(type) == ZEND_NAME_NOT_FQ);
11541155
return zend_string_copy(name);
11551156
}
11561157

1157-
if (type == ZEND_NAME_RELATIVE) {
1158+
if (NAME_QUAL(type) == ZEND_NAME_RELATIVE) {
11581159
return zend_prefix_with_ns(name);
11591160
}
11601161

1161-
if (type == ZEND_NAME_FQ) {
1162+
if (NAME_QUAL(type) == ZEND_NAME_FQ) {
11621163
if (ZSTR_VAL(name)[0] == '\\') {
11631164
/* Remove \ prefix (only relevant if this is a string rather than a label) */
11641165
name = zend_string_init(ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1, 0);
@@ -1746,7 +1747,7 @@ uint32_t zend_get_class_fetch_type(const zend_string *name) /* {{{ */
17461747
static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */
17471748
{
17481749
/* Fully qualified names are always default refs */
1749-
if (name_ast->attr == ZEND_NAME_FQ) {
1750+
if (NAME_QUAL(name_ast->attr) == ZEND_NAME_FQ) {
17501751
return ZEND_FETCH_CLASS_DEFAULT;
17511752
}
17521753

@@ -2875,7 +2876,7 @@ static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t f
28752876
}
28762877

28772878
/* Fully qualified names are always default refs */
2878-
if (name_ast->attr == ZEND_NAME_FQ) {
2879+
if (NAME_QUAL(name_ast->attr) == ZEND_NAME_FQ) {
28792880
result->op_type = IS_CONST;
28802881
ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast));
28812882
return;
@@ -6960,7 +6961,7 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
69606961
uint8_t type_code = zend_lookup_builtin_type_by_name(class_name);
69616962

69626963
if (type_code != 0) {
6963-
if ((ast->attr & ZEND_NAME_NOT_FQ) != ZEND_NAME_NOT_FQ) {
6964+
if (NAME_QUAL(ast->attr) != ZEND_NAME_NOT_FQ) {
69646965
zend_error_noreturn(E_COMPILE_ERROR,
69656966
"Type declaration '%s' must be unqualified",
69666967
ZSTR_VAL(zend_string_tolower(class_name)));
@@ -6987,7 +6988,7 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
69876988
zend_string_addref(class_name);
69886989
}
69896990

6990-
if (ast->attr == ZEND_NAME_NOT_FQ
6991+
if (NAME_QUAL(ast->attr) == ZEND_NAME_NOT_FQ
69916992
&& zend_is_confusable_type(orig_name, &correct_name)
69926993
&& zend_is_not_imported(orig_name)) {
69936994
const char *extra =
@@ -10763,7 +10764,7 @@ static void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */
1076310764
zend_string *orig_name = zend_ast_get_str(name_ast);
1076410765
zend_string *resolved_name = zend_resolve_const_name(orig_name, name_ast->attr, &is_fully_qualified);
1076510766

10766-
if (zend_string_equals_literal(resolved_name, "__COMPILER_HALT_OFFSET__") || (name_ast->attr != ZEND_NAME_RELATIVE && zend_string_equals_literal(orig_name, "__COMPILER_HALT_OFFSET__"))) {
10767+
if (zend_string_equals_literal(resolved_name, "__COMPILER_HALT_OFFSET__") || (NAME_QUAL(name_ast->attr) != ZEND_NAME_RELATIVE && zend_string_equals_literal(orig_name, "__COMPILER_HALT_OFFSET__"))) {
1076710768
zend_ast *last = CG(ast);
1076810769

1076910770
while (last && last->kind == ZEND_AST_STMT_LIST) {

Zend/zend_compile.h

+2
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,8 @@ ZEND_API zend_string *zend_type_to_string(zend_type type);
10341034
#define ZEND_NAME_FQ 0
10351035
#define ZEND_NAME_NOT_FQ 1
10361036
#define ZEND_NAME_RELATIVE 2
1037+
#define ZEND_NAME_QUALIFIED_MASK 0x0011
1038+
#define NAME_QUAL(type) (type & ZEND_NAME_QUALIFIED_MASK)
10371039

10381040
#define ZEND_NAME_OPTIONAL 4
10391041

0 commit comments

Comments
 (0)