diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-01-30 17:16:09 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-01-31 13:52:06 +0100 |
commit | 3d39479f4d7c86c66aa92fc5d0d97fb660109ee9 (patch) | |
tree | bb64e4169942e0e8707ae4260b912e8e5a55aa7d /Zend/zend_constants.c | |
parent | 3d478e5cc34a1dbdc00733e4ab684a2509dc71e5 (diff) | |
download | php-git-3d39479f4d7c86c66aa92fc5d0d97fb660109ee9.tar.gz |
Remove support for case-insensitive constants
The only remaining case-insensitive constants are null, true and
false, which are handled explicitly.
In the future we may convert them from constants to reserved keywords.
Diffstat (limited to 'Zend/zend_constants.c')
-rw-r--r-- | Zend/zend_constants.c | 214 |
1 files changed, 87 insertions, 127 deletions
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 0f3fb9cfa0..6371492dc0 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -33,6 +33,9 @@ #define MARK_CONSTANT_VISITED(zv) Z_ACCESS_FLAGS_P(zv) |= IS_CONSTANT_VISITED_MARK #define RESET_CONSTANT_VISITED(zv) Z_ACCESS_FLAGS_P(zv) &= ~IS_CONSTANT_VISITED_MARK +/* Use for special null/true/false constants. */ +static zval null_value, true_value, false_value; + void free_zend_constant(zval *zv) { zend_constant *c = Z_PTR_P(zv); @@ -99,7 +102,6 @@ void clean_module_constants(int module_number) int zend_startup_constants(void) { EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable)); - zend_hash_init(EG(zend_constants), 128, NULL, ZEND_CONSTANT_DTOR, 1); return SUCCESS; } @@ -128,14 +130,17 @@ void zend_register_standard_constants(void) REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS); - /* true/false constants */ - { - REGISTER_MAIN_BOOL_CONSTANT("TRUE", 1, CONST_PERSISTENT | CONST_CT_SUBST); - REGISTER_MAIN_BOOL_CONSTANT("FALSE", 0, CONST_PERSISTENT | CONST_CT_SUBST); - REGISTER_MAIN_BOOL_CONSTANT("ZEND_THREAD_SAFE", ZTS_V, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_BOOL_CONSTANT("ZEND_DEBUG_BUILD", ZEND_DEBUG, CONST_PERSISTENT | CONST_CS); - } - REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT | CONST_CT_SUBST); + REGISTER_MAIN_BOOL_CONSTANT("ZEND_THREAD_SAFE", ZTS_V, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_BOOL_CONSTANT("ZEND_DEBUG_BUILD", ZEND_DEBUG, CONST_PERSISTENT | CONST_CS); + + /* Special constants true/false/null. */ + REGISTER_MAIN_BOOL_CONSTANT("TRUE", 1, CONST_PERSISTENT); + REGISTER_MAIN_BOOL_CONSTANT("FALSE", 0, CONST_PERSISTENT); + REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT); + + ZVAL_NULL(&null_value); + ZVAL_TRUE(&true_value); + ZVAL_FALSE(&false_value); } @@ -204,7 +209,7 @@ ZEND_API void zend_register_string_constant(const char *name, size_t name_len, c zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number); } -static zend_constant *zend_get_special_constant(const char *name, size_t name_len) +static zend_constant *zend_get_halt_offset_constant(const char *name, size_t name_len) { zend_constant *c; static const char haltoff[] = "__COMPILER_HALT_OFFSET__"; @@ -230,6 +235,37 @@ static zend_constant *zend_get_special_constant(const char *name, size_t name_le } } +ZEND_API zval *_zend_get_special_const(const char *name, size_t len) /* {{{ */ +{ + if (len == 4) { + if ((name[0] == 'n' || name[0] == 'N') && + (name[1] == 'u' || name[1] == 'U') && + (name[2] == 'l' || name[2] == 'L') && + (name[3] == 'l' || name[3] == 'L') + ) { + return &null_value; + } + if ((name[0] == 't' || name[0] == 'T') && + (name[1] == 'r' || name[1] == 'R') && + (name[2] == 'u' || name[2] == 'U') && + (name[3] == 'e' || name[3] == 'E') + ) { + return &true_value; + } + } else { + if ((name[0] == 'f' || name[0] == 'F') && + (name[1] == 'a' || name[1] == 'A') && + (name[2] == 'l' || name[2] == 'L') && + (name[3] == 's' || name[3] == 'S') && + (name[4] == 'e' || name[4] == 'E') + ) { + return &false_value; + } + } + return 0; +} +/* }}} */ + ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry *scope) /* {{{ */ { if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PUBLIC) { @@ -243,80 +279,34 @@ ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry * } /* }}} */ -static inline zend_constant *zend_get_constant_str_impl(const char *name, size_t name_len) -{ - zend_constant *c; - ALLOCA_FLAG(use_heap) - - if ((c = zend_hash_str_find_ptr(EG(zend_constants), name, name_len)) == NULL) { - char *lcname = do_alloca(name_len + 1, use_heap); - zend_str_tolower_copy(lcname, name, name_len); - if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, name_len)) != NULL) { - if (ZEND_CONSTANT_FLAGS(c) & CONST_CS) { - c = NULL; - } - } else { - c = zend_get_special_constant(name, name_len); - } - free_alloca(lcname, use_heap); - } - - return c; -} - ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len) { - zend_constant *c = zend_get_constant_str_impl(name, name_len); - return c ? &c->value : NULL; -} + zend_constant *c = zend_hash_str_find_ptr(EG(zend_constants), name, name_len); + if (c) { + return &c->value; + } -static inline zend_constant *zend_get_constant_impl(zend_string *name) -{ - zval *zv; - zend_constant *c; - ALLOCA_FLAG(use_heap) - - zv = zend_hash_find(EG(zend_constants), name); - if (zv == NULL) { - char *lcname = do_alloca(ZSTR_LEN(name) + 1, use_heap); - zend_str_tolower_copy(lcname, ZSTR_VAL(name), ZSTR_LEN(name)); - zv = zend_hash_str_find(EG(zend_constants), lcname, ZSTR_LEN(name)); - if (zv != NULL) { - c = Z_PTR_P(zv); - if (ZEND_CONSTANT_FLAGS(c) & CONST_CS) { - c = NULL; - } - } else { - c = zend_get_special_constant(ZSTR_VAL(name), ZSTR_LEN(name)); - } - free_alloca(lcname, use_heap); - return c; - } else { - return (zend_constant *) Z_PTR_P(zv); + c = zend_get_halt_offset_constant(name, name_len); + if (c) { + return &c->value; } + + return zend_get_special_const(name, name_len); } ZEND_API zval *zend_get_constant(zend_string *name) { - zend_constant *c = zend_get_constant_impl(name); - return c ? &c->value : NULL; -} + zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name); + if (c) { + return &c->value; + } -static zend_bool is_access_deprecated(const zend_constant *c, const char *access_name) { - const char *ns_sep = zend_memrchr(ZSTR_VAL(c->name), '\\', ZSTR_LEN(c->name)); - if (ns_sep) { - /* Namespaces are always case-insensitive. Only compare shortname. */ - size_t shortname_offset = ns_sep - ZSTR_VAL(c->name) + 1; - size_t shortname_len = ZSTR_LEN(c->name) - shortname_offset; - return memcmp( - access_name + shortname_offset, - ZSTR_VAL(c->name) + shortname_offset, - shortname_len - ) != 0; - } else { - /* No namespace, compare whole name */ - return memcmp(access_name, ZSTR_VAL(c->name), ZSTR_LEN(c->name)) != 0; + c = zend_get_halt_offset_constant(ZSTR_VAL(name), ZSTR_LEN(name)); + if (c) { + return &c->value; } + + return zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name)); } ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags) @@ -419,56 +409,34 @@ failure: size_t lcname_len; ALLOCA_FLAG(use_heap) + /* Lowercase the namespace portion */ lcname_len = prefix_len + 1 + const_name_len; lcname = do_alloca(lcname_len + 1, use_heap); zend_str_tolower_copy(lcname, name, prefix_len); - /* Check for namespace constant */ lcname[prefix_len] = '\\'; memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1); - if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) == NULL) { - /* try lowercase */ - zend_str_tolower(lcname + prefix_len + 1, const_name_len); - if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) != NULL) { - if ((ZEND_CONSTANT_FLAGS(c) & CONST_CS) != 0) { - c = NULL; - } - } - } + c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len); free_alloca(lcname, use_heap); - if (!c) { - if (!(flags & IS_CONSTANT_UNQUALIFIED)) { - return NULL; - } + if (c) { + return &c->value; + } - /* name requires runtime resolution, need to check non-namespaced name */ - c = zend_get_constant_str_impl(constant_name, const_name_len); - name = constant_name; + if (!(flags & IS_CONSTANT_UNQUALIFIED)) { + return NULL; } + + /* name requires runtime resolution, need to check non-namespaced name */ + return zend_get_constant_str(constant_name, const_name_len); } else { if (cname) { - c = zend_get_constant_impl(cname); + return zend_get_constant(cname); } else { - c = zend_get_constant_str_impl(name, name_len); - } - } - - if (!c) { - return NULL; - } - - if (!(flags & ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK)) { - if (!(ZEND_CONSTANT_FLAGS(c) & (CONST_CS|CONST_CT_SUBST)) && is_access_deprecated(c, name)) { - zend_error(E_DEPRECATED, - "Case-insensitive constants are deprecated. " - "The correct casing for this constant is \"%s\"", - ZSTR_VAL(c->name)); + return zend_get_constant_str(name, name_len); } } - - return &c->value; } static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_constant *c) @@ -489,38 +457,30 @@ ZEND_API int zend_register_constant(zend_constant *c) zend_string *lowercase_name = NULL; zend_string *name; int ret = SUCCESS; + zend_bool persistent = (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) != 0; #if 0 printf("Registering constant for module %d\n", c->module_number); #endif - if (!(ZEND_CONSTANT_FLAGS(c) & CONST_CS)) { - lowercase_name = zend_string_tolower_ex(c->name, ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT); + char *slash = strrchr(ZSTR_VAL(c->name), '\\'); + if (slash) { + lowercase_name = zend_string_init(ZSTR_VAL(c->name), ZSTR_LEN(c->name), persistent); + zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(c->name)); lowercase_name = zend_new_interned_string(lowercase_name); name = lowercase_name; } else { - char *slash = strrchr(ZSTR_VAL(c->name), '\\'); - if (slash) { - lowercase_name = zend_string_init(ZSTR_VAL(c->name), ZSTR_LEN(c->name), ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT); - zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(c->name)); - lowercase_name = zend_new_interned_string(lowercase_name); - name = lowercase_name; - } else { - name = c->name; - } + name = c->name; } - /* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */ + /* Check if the user is trying to define any special constant */ if (zend_string_equals_literal(name, "__COMPILER_HALT_OFFSET__") - || zend_hash_add_constant(EG(zend_constants), name, c) == NULL) { - - /* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */ - if (ZSTR_VAL(c->name)[0] == '\0' && ZSTR_LEN(c->name) > sizeof("\0__COMPILER_HALT_OFFSET__")-1 - && memcmp(ZSTR_VAL(name), "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) { - } + || (!persistent && zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name))) + || zend_hash_add_constant(EG(zend_constants), name, c) == NULL + ) { zend_error(E_NOTICE,"Constant %s already defined", ZSTR_VAL(name)); zend_string_release(c->name); - if (!(ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)) { + if (!persistent) { zval_ptr_dtor_nogc(&c->value); } ret = FAILURE; |