]> granicus.if.org Git - php/commitdiff
Add case insensitive find_ptr hash functions
authorLevi Morrison <levi.morrison@datadoghq.com>
Fri, 24 Apr 2020 21:00:13 +0000 (15:00 -0600)
committerChristoph M. Becker <cmbecker69@gmx.de>
Sun, 26 Apr 2020 21:29:41 +0000 (23:29 +0200)
 - zend_hash_find_ptr_lc(ht, zend_string *key)
 - zend_hash_str_find_ptr_lc(ht, const char *str, size_t len)

Note that zend_hash_str_find_ptr_lc used to exist in zend_compile.c
as        zend_hash_find_ptr_lc. When exporting this I figured it
was best to use the same conventions as the rest of zend_hash.h.

Zend/zend_compile.c
Zend/zend_hash.c
Zend/zend_hash.h

index 472a402fe6b729446e23d61e38feac154461bc33..381a180f2953c97a0353b5bbbf422154dca6dca3 100644 (file)
@@ -272,23 +272,9 @@ static zend_always_inline zend_bool zend_is_confusable_type(const zend_string *n
 }
 /* }}} */
 
-static void *zend_hash_find_ptr_lc(HashTable *ht, const char *str, size_t len) {
-       void *result;
-       zend_string *lcname;
-       ALLOCA_FLAG(use_heap);
-
-       ZSTR_ALLOCA_ALLOC(lcname, len, use_heap);
-       zend_str_tolower_copy(ZSTR_VAL(lcname), str, len);
-       result = zend_hash_find_ptr(ht, lcname);
-       ZSTR_ALLOCA_FREE(lcname, use_heap);
-
-       return result;
-}
-
 static zend_bool zend_is_not_imported(zend_string *name) {
        /* Assuming "name" is unqualified here. */
-       return !FC(imports)
-               || zend_hash_find_ptr_lc(FC(imports), ZSTR_VAL(name), ZSTR_LEN(name)) == NULL;
+       return !FC(imports) || zend_hash_find_ptr_lc(FC(imports), name) == NULL;
 }
 
 void zend_oparray_context_begin(zend_oparray_context *prev_context) /* {{{ */
@@ -901,7 +887,7 @@ zend_string *zend_resolve_non_class_name(
                if (case_sensitive) {
                        import_name = zend_hash_find_ptr(current_import_sub, name);
                } else {
-                       import_name = zend_hash_find_ptr_lc(current_import_sub, ZSTR_VAL(name), ZSTR_LEN(name));
+                       import_name = zend_hash_find_ptr_lc(current_import_sub, name);
                }
 
                if (import_name) {
@@ -918,7 +904,7 @@ zend_string *zend_resolve_non_class_name(
        if (compound && FC(imports)) {
                /* If the first part of a qualified name is an alias, substitute it. */
                size_t len = compound - ZSTR_VAL(name);
-               zend_string *import_name = zend_hash_find_ptr_lc(FC(imports), ZSTR_VAL(name), len);
+               zend_string *import_name = zend_hash_str_find_ptr_lc(FC(imports), ZSTR_VAL(name), len);
 
                if (import_name) {
                        return zend_concat_names(
@@ -971,7 +957,7 @@ zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* {{{ */
                        /* If the first part of a qualified name is an alias, substitute it. */
                        size_t len = compound - ZSTR_VAL(name);
                        zend_string *import_name =
-                               zend_hash_find_ptr_lc(FC(imports), ZSTR_VAL(name), len);
+                               zend_hash_str_find_ptr_lc(FC(imports), ZSTR_VAL(name), len);
 
                        if (import_name) {
                                return zend_concat_names(
@@ -980,7 +966,7 @@ zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* {{{ */
                } else {
                        /* If an unqualified name is an alias, replace it. */
                        zend_string *import_name
-                               = zend_hash_find_ptr_lc(FC(imports), ZSTR_VAL(name), ZSTR_LEN(name));
+                               = zend_hash_find_ptr_lc(FC(imports), name);
 
                        if (import_name) {
                                return zend_string_copy(import_name);
@@ -1613,7 +1599,7 @@ static zend_bool zend_verify_ct_const_access(zend_class_constant *c, zend_class_
                        if (ce->ce_flags & ZEND_ACC_RESOLVED_PARENT) {
                                ce = ce->parent;
                        } else {
-                               ce = zend_hash_find_ptr_lc(CG(class_table), ZSTR_VAL(ce->parent_name), ZSTR_LEN(ce->parent_name));
+                               ce = zend_hash_find_ptr_lc(CG(class_table), ce->parent_name);
                                if (!ce) {
                                        break;
                                }
@@ -1633,7 +1619,7 @@ static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name,
        if (class_name_refers_to_active_ce(class_name, fetch_type)) {
                cc = zend_hash_find_ptr(&CG(active_class_entry)->constants_table, name);
        } else if (fetch_type == ZEND_FETCH_CLASS_DEFAULT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) {
-               zend_class_entry *ce = zend_hash_find_ptr_lc(CG(class_table), ZSTR_VAL(class_name), ZSTR_LEN(class_name));
+               zend_class_entry *ce = zend_hash_find_ptr_lc(CG(class_table), class_name);
                if (ce) {
                        cc = zend_hash_find_ptr(&ce->constants_table, name);
                } else {
@@ -6191,8 +6177,8 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as
        lcname = zend_string_tolower(name);
 
        if (FC(imports_function)) {
-               zend_string *import_name = zend_hash_find_ptr_lc(
-                       FC(imports_function), ZSTR_VAL(unqualified_name), ZSTR_LEN(unqualified_name));
+               zend_string *import_name =
+                       zend_hash_find_ptr_lc(FC(imports_function), unqualified_name);
                if (import_name && !zend_string_equals_ci(lcname, import_name)) {
                        zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare function %s "
                                "because the name is already in use", ZSTR_VAL(name));
@@ -6657,8 +6643,8 @@ void zend_compile_class_decl(znode *result, zend_ast *ast, zend_bool toplevel) /
                lcname = zend_string_tolower(name);
 
                if (FC(imports)) {
-                       zend_string *import_name = zend_hash_find_ptr_lc(
-                               FC(imports), ZSTR_VAL(unqualified_name), ZSTR_LEN(unqualified_name));
+                       zend_string *import_name =
+                               zend_hash_find_ptr_lc(FC(imports), unqualified_name);
                        if (import_name && !zend_string_equals_ci(lcname, import_name)) {
                                zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s "
                                                "because the name is already in use", ZSTR_VAL(name));
index 872a22822942bbbdbb3f7701a9d512e3b6c0b392..d57c0a69d2e030fc1453fe6c7384c7641908cc89 100644 (file)
@@ -84,6 +84,28 @@ static void _zend_is_inconsistent(const HashTable *ht, const char *file, int lin
                zend_hash_do_resize(ht);                                        \
        }
 
+ZEND_API void *zend_hash_str_find_ptr_lc(const HashTable *ht, const char *str, size_t len) {
+       void *result;
+       char *lc_str;
+
+       /* Stack allocate small strings to improve performance */
+       ALLOCA_FLAG(use_heap)
+
+       lc_str = zend_str_tolower_copy(do_alloca(len + 1, use_heap), str, len);
+       result = zend_hash_str_find_ptr(ht, lc_str, len);
+       free_alloca(lc_str, use_heap);
+
+       return result;
+}
+
+ZEND_API void *zend_hash_find_ptr_lc(const HashTable *ht, zend_string *key) {
+       void *result;
+       zend_string *lc_key = zend_string_tolower(key);
+       result = zend_hash_find_ptr(ht, lc_key);
+       zend_string_release(lc_key);
+       return result;
+}
+
 static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht);
 
 static zend_always_inline uint32_t zend_hash_check_size(uint32_t nSize)
index 289b9a3349d46f679b864ee535808e827da2f827..632658d938772514b63677dc5c82325c0cfe116a 100644 (file)
@@ -847,6 +847,14 @@ static zend_always_inline void *zend_hash_str_find_ptr(const HashTable *ht, cons
        }
 }
 
+/* Will lowercase the str; use only if you don't need the lowercased string for
+ * anything else. If you have a lowered string, use zend_hash_str_find_ptr. */
+ZEND_API void *zend_hash_str_find_ptr_lc(const HashTable *ht, const char *str, size_t len);
+
+/* Will lowercase the str; use only if you don't need the lowercased string for
+ * anything else. If you have a lowered string, use zend_hash_find_ptr. */
+ZEND_API void *zend_hash_find_ptr_lc(const HashTable *ht, zend_string *key);
+
 static zend_always_inline void *zend_hash_index_find_ptr(const HashTable *ht, zend_ulong h)
 {
        zval *zv;