Skip to content
Closed
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
36 changes: 36 additions & 0 deletions Zend/zend.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,42 @@ struct _zend_class_entry {
} info;
};

#define CHECK_NAME_CASE(_type,_name,_len,_ref_name,_ref_len) { \
char *_tmp_name=_name; \
size_t _tmp_len=_len; \
if ((*(_tmp_name))=='\\') { \
_tmp_name++; \
_tmp_len--; \
} \
if (((_tmp_len)!=(_ref_len)) \
|| memcmp((_tmp_name),(_ref_name),(_tmp_len))) { \
zend_error(E_STRICT,"Case mismatch in %s name (%s should be %s)" \
,_type,(_tmp_name),(_ref_name)); \
} }

#define CHECK_CLASS_CASE(_name,_len,_ce) { \
if (_ce) CHECK_NAME_CASE("class",(_name),(_len) \
,(_ce)->name->val,(_ce)->name->len); }

#define CHECK_FUNCTION_CASE(_name,_len,_fe) { \
if (_fe) CHECK_NAME_CASE("function",(_name),(_len) \
,(_fe)->common.function_name->val \
,(_fe)->common.function_name->len); }

#define CHECK_METHOD_CASE(_name,_len,_fe) { \
if (_fe) CHECK_NAME_CASE("method",(_name),(_len) \
,(_fe)->common.function_name->val \
,(_fe)->common.function_name->len); }

#define CHECK_CLASS_CASE_ZSTR(_zstr,_ce) \
CHECK_CLASS_CASE((_zstr)->val,(_zstr)->len,(_ce))

#define CHECK_FUNCTION_CASE_ZSTR(_zstr,_fe) \
CHECK_FUNCTION_CASE((_zstr)->val,(_zstr)->len,(_fe))

#define CHECK_METHOD_CASE_ZSTR(_zstr,_fe) \
CHECK_METHOD_CASE((_zstr)->val,(_zstr)->len,(_fe))

typedef struct _zend_utility_functions {
void (*error_function)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
size_t (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
Expand Down
4 changes: 4 additions & 0 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -2751,6 +2751,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
/* Check if function with given name exists.
* This may be a compound name that includes namespace name */
if (EXPECTED((fcc->function_handler = zend_hash_find_ptr(EG(function_table), lmname)) != NULL)) {
CHECK_FUNCTION_CASE_ZSTR(Z_STR_P(callable),fcc->function_handler);
if (lmname != Z_STR_P(callable)) {
STR_ALLOCA_FREE(lmname, use_heap);
}
Expand All @@ -2763,6 +2764,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
}
zend_str_tolower(lmname->val, lmname->len);
if ((fcc->function_handler = zend_hash_find_ptr(EG(function_table), lmname)) != NULL) {
CHECK_FUNCTION_CASE_ZSTR(Z_STR_P(callable),fcc->function_handler);
STR_ALLOCA_FREE(lmname, use_heap);
return 1;
}
Expand Down Expand Up @@ -2832,6 +2834,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
retval = 1;
}
} else if ((fcc->function_handler = zend_hash_find_ptr(ftable, lmname)) != NULL) {
CHECK_METHOD_CASE_ZSTR(mname,fcc->function_handler);
retval = 1;
if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) &&
!strict_class && EG(scope) &&
Expand Down Expand Up @@ -3942,6 +3945,7 @@ ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_functi
}
if (name->len == f->common.function_name->len &&
!strncasecmp(name->val, f->common.function_name->val, f->common.function_name->len)) {
CHECK_METHOD_CASE_ZSTR(name,f);
return f->common.function_name;
}
return zend_find_alias_name(f->common.scope, name);
Expand Down
4 changes: 4 additions & 0 deletions Zend/zend_builtin_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,7 @@ ZEND_FUNCTION(class_exists)
}
ce = zend_hash_find_ptr(EG(class_table), lc_name);
zend_string_release(lc_name);
CHECK_CLASS_CASE_ZSTR(class_name,ce);
RETURN_BOOL(ce && !((ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
}

Expand Down Expand Up @@ -1393,6 +1394,7 @@ ZEND_FUNCTION(interface_exists)
}
ce = zend_hash_find_ptr(EG(class_table), lc_name);
zend_string_release(lc_name);
CHECK_CLASS_CASE_ZSTR(iface_name,ce);
RETURN_BOOL(ce && ce->ce_flags & ZEND_ACC_INTERFACE);
}

Expand Down Expand Up @@ -1435,6 +1437,7 @@ ZEND_FUNCTION(trait_exists)
}
ce = zend_hash_find_ptr(EG(class_table), lc_name);
zend_string_release(lc_name);
CHECK_CLASS_CASE_ZSTR(trait_name,ce);
RETURN_BOOL(ce && ((ce->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
}

Expand Down Expand Up @@ -1475,6 +1478,7 @@ ZEND_FUNCTION(function_exists)

func = zend_hash_find_ptr(EG(function_table), lcname);
zend_string_release(lcname);
CHECK_FUNCTION_CASE(name,name_len,func);

/*
* A bit of a hack, but not a bad one: we see if the handler of the function
Expand Down
3 changes: 3 additions & 0 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -2652,6 +2652,7 @@ static int zend_try_compile_ct_bound_init_user_func(zend_ast *name_ast, uint32_t
lcname = zend_string_tolower(name);

fbc = zend_hash_find_ptr(CG(function_table), lcname);
CHECK_FUNCTION_CASE_ZSTR(name,fbc);
if (!fbc || (fbc->type == ZEND_INTERNAL_FUNCTION &&
(CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS))
) {
Expand Down Expand Up @@ -2815,6 +2816,7 @@ void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
lcname = zend_string_tolower(Z_STR_P(name));

fbc = zend_hash_find_ptr(CG(function_table), lcname);
CHECK_FUNCTION_CASE_ZSTR(Z_STR_P(name),fbc);
if (!fbc || (fbc->type == ZEND_INTERNAL_FUNCTION &&
(CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS))
) {
Expand Down Expand Up @@ -4757,6 +4759,7 @@ void zend_compile_use(zend_ast *ast) /* {{{ */
case T_FUNCTION:
{
zend_function *fn = zend_hash_find_ptr(CG(function_table), lookup_name);
CHECK_FUNCTION_CASE_ZSTR(new_name,fn);
if (fn && fn->type == ZEND_USER_FUNCTION
&& fn->op_array.filename == CG(compiled_filename)
) {
Expand Down
2 changes: 2 additions & 0 deletions Zend/zend_execute_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k
if (!key) {
zend_string_release(lc_name);
}
CHECK_CLASS_CASE_ZSTR(name,ce);
return ce;
}

Expand Down Expand Up @@ -1030,6 +1031,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k
if (!key) {
zend_string_release(lc_name);
}
CHECK_CLASS_CASE_ZSTR(name,ce);
return ce;
}
/* }}} */
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
lc_parent_class_name = zend_string_tolower(ce->parent->name);
if (!zend_hash_exists(&ce->function_table, lc_parent_class_name) &&
(function = zend_hash_find_ptr(&ce->parent->function_table, lc_parent_class_name)) != NULL) {
CHECK_CLASS_CASE_ZSTR(ce->parent->name,ce->parent);
if (function->common.fn_flags & ZEND_ACC_CTOR) {
/* inherit parent's constructor */
if (function->type == ZEND_INTERNAL_FUNCTION) {
Expand Down
4 changes: 4 additions & 0 deletions Zend/zend_object_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,7 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
}

fbc = Z_FUNC_P(func);
CHECK_METHOD_CASE_ZSTR(method_name,fbc);
/* Check access level */
if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) {
zend_function *updated_fbc;
Expand All @@ -1004,6 +1005,7 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
updated_fbc = zend_check_private_int(fbc, zobj->ce, lc_method_name);
if (EXPECTED(updated_fbc != NULL)) {
fbc = updated_fbc;
CHECK_METHOD_CASE_ZSTR(method_name,fbc);
} else {
if (zobj->ce->__call) {
fbc = zend_get_user_call_function(zobj->ce, method_name);
Expand All @@ -1023,6 +1025,7 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
if (priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
&& priv_fbc->common.scope == EG(scope)) {
fbc = priv_fbc;
CHECK_METHOD_CASE_ZSTR(method_name,fbc);
}
}
}
Expand Down Expand Up @@ -1135,6 +1138,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
zval *func = zend_hash_find(&ce->function_table, lc_function_name);
if (EXPECTED(func != NULL)) {
fbc = Z_FUNC_P(func);
CHECK_METHOD_CASE_ZSTR(function_name,fbc);
} else {
if (UNEXPECTED(!key)) {
zend_string_release(lc_function_name);
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -2528,6 +2528,7 @@ ZEND_VM_C_LABEL(try_function_name):
FREE_OP2();

fbc = Z_FUNC_P(func);
CHECK_FUNCTION_CASE_ZSTR(Z_STR_P(function_name),fbc);
called_scope = NULL;
object = NULL;
} else if (OP2_TYPE != IS_CONST &&
Expand Down
3 changes: 3 additions & 0 deletions Zend/zend_vm_execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -1585,6 +1585,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
zend_string_release(lcname);

fbc = Z_FUNC_P(func);
CHECK_FUNCTION_CASE_ZSTR(Z_STR_P(function_name),fbc);
called_scope = NULL;
object = NULL;
} else if (IS_CONST != IS_CONST &&
Expand Down Expand Up @@ -1968,6 +1969,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
zend_string_release(lcname);

fbc = Z_FUNC_P(func);
CHECK_FUNCTION_CASE_ZSTR(Z_STR_P(function_name),fbc);
called_scope = NULL;
object = NULL;
} else if (IS_CV != IS_CONST &&
Expand Down Expand Up @@ -2158,6 +2160,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER(ZEND_OPCOD
zval_ptr_dtor_nogc(free_op2);

fbc = Z_FUNC_P(func);
CHECK_FUNCTION_CASE_ZSTR(Z_STR_P(function_name),fbc);
called_scope = NULL;
object = NULL;
} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
Expand Down