diff --git a/Zend/tests/class_alias_003.phpt b/Zend/tests/class_alias_003.phpt deleted file mode 100644 index 57e2fd572e6..00000000000 --- a/Zend/tests/class_alias_003.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -Testing declaration of alias to 'static' ---FILE-- -test()); - -?> ---EXPECTF-- -object(foo)#%d (0) { -} diff --git a/Zend/tests/typehints/scalar_relative_typehint_disallowed.phpt b/Zend/tests/typehints/scalar_relative_typehint_disallowed.phpt index 30d2bd8b745..d85091253c0 100644 --- a/Zend/tests/typehints/scalar_relative_typehint_disallowed.phpt +++ b/Zend/tests/typehints/scalar_relative_typehint_disallowed.phpt @@ -11,4 +11,4 @@ foo(10); ?> --EXPECTF-- -Fatal error: "bar\int" cannot be used as a type declaration in %s on line %d \ No newline at end of file +Fatal error: Cannot use 'bar\int' as class name as it is reserved in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved2.phpt b/Zend/tests/typehints/scalar_reserved2.phpt index 8ed41024974..01f36fd1543 100644 --- a/Zend/tests/typehints/scalar_reserved2.phpt +++ b/Zend/tests/typehints/scalar_reserved2.phpt @@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (2) class int {} --EXPECTF-- -Fatal error: "int" cannot be used as a class name in %s on line %d +Fatal error: Cannot use 'int' as class name as it is reserved in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved2_class_alias.phpt b/Zend/tests/typehints/scalar_reserved2_class_alias.phpt index 2348f76df8f..02d6bb4a832 100644 --- a/Zend/tests/typehints/scalar_reserved2_class_alias.phpt +++ b/Zend/tests/typehints/scalar_reserved2_class_alias.phpt @@ -6,4 +6,4 @@ Scalar type hint names cannot be used as class, trait or interface names (2) - c class foobar {} class_alias("foobar", "int"); --EXPECTF-- -Fatal error: "int" cannot be used as a class name in %s on line %d +Fatal error: Cannot use 'int' as class name as it is reserved in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved2_use.phpt b/Zend/tests/typehints/scalar_reserved2_use.phpt index b7a1baed36b..e61db5c87a8 100644 --- a/Zend/tests/typehints/scalar_reserved2_use.phpt +++ b/Zend/tests/typehints/scalar_reserved2_use.phpt @@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (2) - u use foobar as int; --EXPECTF-- -Fatal error: "int" cannot be used as a class name in %s on line %d +Fatal error: Cannot use foobar as int because 'int' is a special class name in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved3.phpt b/Zend/tests/typehints/scalar_reserved3.phpt index 00750955b72..425365bc65a 100644 --- a/Zend/tests/typehints/scalar_reserved3.phpt +++ b/Zend/tests/typehints/scalar_reserved3.phpt @@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (3) class float {} --EXPECTF-- -Fatal error: "float" cannot be used as a class name in %s on line %d +Fatal error: Cannot use 'float' as class name as it is reserved in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved3_class_alias.phpt b/Zend/tests/typehints/scalar_reserved3_class_alias.phpt index 05438b579cf..39c2e2a62c1 100644 --- a/Zend/tests/typehints/scalar_reserved3_class_alias.phpt +++ b/Zend/tests/typehints/scalar_reserved3_class_alias.phpt @@ -6,4 +6,4 @@ Scalar type hint names cannot be used as class, trait or interface names (3) - c class foobar {} class_alias("foobar", "float"); --EXPECTF-- -Fatal error: "float" cannot be used as a class name in %s on line %d +Fatal error: Cannot use 'float' as class name as it is reserved in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved3_use.phpt b/Zend/tests/typehints/scalar_reserved3_use.phpt index 6f52e060fff..23be15e1a3b 100644 --- a/Zend/tests/typehints/scalar_reserved3_use.phpt +++ b/Zend/tests/typehints/scalar_reserved3_use.phpt @@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (3) - u use foobar as float; --EXPECTF-- -Fatal error: "float" cannot be used as a class name in %s on line %d +Fatal error: Cannot use foobar as float because 'float' is a special class name in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved4.phpt b/Zend/tests/typehints/scalar_reserved4.phpt index 2e92514b8bb..5a190ce51a9 100644 --- a/Zend/tests/typehints/scalar_reserved4.phpt +++ b/Zend/tests/typehints/scalar_reserved4.phpt @@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (4) class string {} --EXPECTF-- -Fatal error: "string" cannot be used as a class name in %s on line %d +Fatal error: Cannot use 'string' as class name as it is reserved in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved4_class_alias.phpt b/Zend/tests/typehints/scalar_reserved4_class_alias.phpt index ff7c6adc79b..ffaf934a012 100644 --- a/Zend/tests/typehints/scalar_reserved4_class_alias.phpt +++ b/Zend/tests/typehints/scalar_reserved4_class_alias.phpt @@ -6,4 +6,4 @@ Scalar type hint names cannot be used as class, trait or interface names (4) - c class foobar {} class_alias("foobar", "string"); --EXPECTF-- -Fatal error: "string" cannot be used as a class name in %s on line %d +Fatal error: Cannot use 'string' as class name as it is reserved in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved4_use.phpt b/Zend/tests/typehints/scalar_reserved4_use.phpt index 1d7e4039d8c..05a2ea1069a 100644 --- a/Zend/tests/typehints/scalar_reserved4_use.phpt +++ b/Zend/tests/typehints/scalar_reserved4_use.phpt @@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (4) - u use foobar as string; --EXPECTF-- -Fatal error: "string" cannot be used as a class name in %s on line %d +Fatal error: Cannot use foobar as string because 'string' is a special class name in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved6.phpt b/Zend/tests/typehints/scalar_reserved6.phpt index 46b8c730e9e..1dee41ff584 100644 --- a/Zend/tests/typehints/scalar_reserved6.phpt +++ b/Zend/tests/typehints/scalar_reserved6.phpt @@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (6) class bool {} --EXPECTF-- -Fatal error: "bool" cannot be used as a class name in %s on line %d +Fatal error: Cannot use 'bool' as class name as it is reserved in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved6_class_alias.phpt b/Zend/tests/typehints/scalar_reserved6_class_alias.phpt index 4a4c824eb63..fd3c328504d 100644 --- a/Zend/tests/typehints/scalar_reserved6_class_alias.phpt +++ b/Zend/tests/typehints/scalar_reserved6_class_alias.phpt @@ -6,4 +6,4 @@ Scalar type hint names cannot be used as class, trait or interface names (6) - c class foobar {} class_alias("foobar", "bool"); --EXPECTF-- -Fatal error: "bool" cannot be used as a class name in %s on line %d +Fatal error: Cannot use 'bool' as class name as it is reserved in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved6_use.phpt b/Zend/tests/typehints/scalar_reserved6_use.phpt index 6a6cb7a34c2..9cb7857a50b 100644 --- a/Zend/tests/typehints/scalar_reserved6_use.phpt +++ b/Zend/tests/typehints/scalar_reserved6_use.phpt @@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (6) - u use foobar as bool; --EXPECTF-- -Fatal error: "bool" cannot be used as a class name in %s on line %d +Fatal error: Cannot use foobar as bool because 'bool' is a special class name in %s on line %d diff --git a/Zend/tests/typehints/scalar_reserved7.phpt b/Zend/tests/typehints/scalar_reserved7.phpt index 330235d9dbc..d641d178d16 100644 --- a/Zend/tests/typehints/scalar_reserved7.phpt +++ b/Zend/tests/typehints/scalar_reserved7.phpt @@ -6,4 +6,4 @@ namespace foo; class int {} --EXPECTF-- -Fatal error: "int" cannot be used as a class name in %s on line %d +Fatal error: Cannot use 'int' as class name as it is reserved in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 9d5bd0f1f15..2a76ff39e66 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -129,6 +129,53 @@ static zend_bool zend_get_unqualified_name(const zend_string *name, const char * } /* }}} */ +struct reserved_class_name { + const char *name; + size_t len; +}; +static const struct reserved_class_name reserved_class_names[] = { + {ZEND_STRL("bool")}, + {ZEND_STRL("false")}, + {ZEND_STRL("float")}, + {ZEND_STRL("int")}, + {ZEND_STRL("null")}, + {ZEND_STRL("parent")}, + {ZEND_STRL("self")}, + {ZEND_STRL("static")}, + {ZEND_STRL("string")}, + {ZEND_STRL("true")}, + {NULL, 0} +}; + +static zend_bool zend_is_reserved_class_name(const zend_string *name) /* {{{ */ +{ + const struct reserved_class_name *reserved = reserved_class_names; + + const char *uqname = name->val; + size_t uqname_len = name->len; + zend_get_unqualified_name(name, &uqname, &uqname_len); + + for (; reserved->name; ++reserved) { + if (uqname_len == reserved->len + && zend_binary_strcasecmp(uqname, uqname_len, reserved->name, reserved->len) == 0 + ) { + return 1; + } + } + + return 0; +} +/* }}} */ + +ZEND_API void zend_assert_valid_class_name(const zend_string *name) /* {{{ */ +{ + if (zend_is_reserved_class_name(name)) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot use '%s' as class name as it is reserved", name->val); + } +} +/* }}} */ + typedef struct _scalar_typehint_info { const char* name; const size_t name_len; @@ -143,39 +190,19 @@ static const scalar_typehint_info scalar_typehints[] = { {NULL, 0, IS_UNDEF} }; -static zend_always_inline const scalar_typehint_info* zend_find_scalar_typehint(const zend_string *const_name) /* {{{ */ +static zend_always_inline const scalar_typehint_info* zend_find_scalar_typehint(const zend_string *name) /* {{{ */ { const scalar_typehint_info *info = &scalar_typehints[0]; - const char *uqname; - size_t uqname_len; - if (!zend_get_unqualified_name(const_name, &uqname, &uqname_len)) { - uqname = const_name->val; - uqname_len = const_name->len; - } - - while (info->name) { - if (uqname_len == info->name_len && zend_binary_strcasecmp(uqname, uqname_len, info->name, info->name_len) == 0) { - break; + for (; info->name; ++info) { + if (name->len == info->name_len + && zend_binary_strcasecmp(name->val, name->len, info->name, info->name_len) == 0 + ) { + return info; } - info++; } - if (info->name) { - return info; - } else { - return NULL; - } -} -/* }}} */ - -ZEND_API void zend_assert_valid_class_name(const zend_string *const_name) /* {{{ */ -{ - const scalar_typehint_info *info = zend_find_scalar_typehint(const_name); - - if (info) { - zend_error_noreturn(E_COMPILE_ERROR, "\"%s\" cannot be used as a class name", info->name); - } + return NULL; } /* }}} */ @@ -184,9 +211,6 @@ static zend_always_inline zend_uchar zend_lookup_scalar_typehint_by_name(const z const scalar_typehint_info *info = zend_find_scalar_typehint(const_name); if (info) { - if (const_name->len != info->name_len) { - zend_error_noreturn(E_COMPILE_ERROR, "\"%s\" cannot be used as a type declaration", const_name->val); - } return info->type; } else { return 0; @@ -4099,6 +4123,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, zend_bool is_ } else { if (zend_is_const_default_class_ref(return_type_ast)) { class_name = zend_resolve_class_name_ast(return_type_ast); + zend_assert_valid_class_name(class_name); } else { zend_string_addref(class_name); if (!is_method) { @@ -4225,9 +4250,9 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, zend_bool is_ if (type != 0) { arg_info->type_hint = type; } else { - if (zend_is_const_default_class_ref(type_ast)) { class_name = zend_resolve_class_name_ast(type_ast); + zend_assert_valid_class_name(class_name); } else { zend_string_addref(class_name); } @@ -4846,10 +4871,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ return; } - if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved", - name->val); - } + zend_assert_valid_class_name(name); lcname = zend_string_tolower(name); @@ -4857,8 +4879,6 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ import_name = zend_hash_find_ptr(CG(current_import), lcname); } - zend_assert_valid_class_name(name); - if (CG(current_namespace)) { name = zend_prefix_with_ns(name); @@ -5094,19 +5114,13 @@ void zend_compile_use(zend_ast *ast) /* {{{ */ } } - if (type == T_CLASS) { - zend_assert_valid_class_name(new_name); - } - if (case_sensitive) { lookup_name = zend_string_copy(new_name); } else { lookup_name = zend_string_tolower(new_name); } - if (type == T_CLASS && (zend_string_equals_literal(lookup_name, "self") - || zend_string_equals_literal(lookup_name, "parent")) - ) { + if (type == T_CLASS && zend_is_reserved_class_name(new_name)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' " "is a special class name", old_name->val, new_name->val, new_name->val); }