Skip to content

Commit c94cb02

Browse files
committed
ext/pcre: simplify pattern info error handling
- use zend_hash_str_lookup for locale char table management - replace the separate zend_hash_find_ptr + zend_string_init + zend_hash_add_ptr + zend_string_release sequence with a single zend_hash_str_lookup() call which handles find-or-insert in one hash traversal and manages persistent key creation internally. close phpGH-21312
1 parent 8d8f5f7 commit c94cb02

1 file changed

Lines changed: 11 additions & 20 deletions

File tree

ext/pcre/php_pcre.c

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -748,21 +748,23 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo
748748
}
749749

750750
if (key != regex) {
751-
tables = (uint8_t *)zend_hash_find_ptr(&char_tables, BG(ctype_string));
752-
if (!tables) {
753-
zend_string *_k;
751+
zv = zend_hash_str_lookup(&char_tables, ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string)));
752+
if (Z_ISNULL_P(zv)) {
754753
tables = pcre2_maketables(gctx);
755754
if (UNEXPECTED(!tables)) {
755+
/* Remove the placeholder entry created by zend_hash_str_lookup(),
756+
* set ptr to NULL first so the destructor (pefree) is safe. */
757+
ZVAL_PTR(zv, NULL);
758+
zend_hash_str_del(&char_tables, ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string)));
756759
php_error_docref(NULL,E_WARNING, "Failed to generate locale character tables");
757760
pcre_handle_exec_error(PCRE2_ERROR_NOMEMORY);
758761
zend_string_release_ex(key, 0);
759762
efree(pattern);
760763
return NULL;
761764
}
762-
_k = zend_string_init(ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string)), 1);
763-
GC_MAKE_PERSISTENT_LOCAL(_k);
764-
zend_hash_add_ptr(&char_tables, _k, (void *)tables);
765-
zend_string_release(_k);
765+
ZVAL_PTR(zv, (void *)tables);
766+
} else {
767+
tables = Z_PTR_P(zv);
766768
}
767769
}
768770
pcre2_set_character_tables(cctx, tables);
@@ -824,19 +826,8 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo
824826
new_entry.refcount = 0;
825827
new_entry.subpats_table = NULL;
826828

827-
rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &new_entry.capture_count);
828-
if (rc < 0) {
829-
if (key != regex) {
830-
zend_string_release_ex(key, 0);
831-
}
832-
pcre2_code_free(new_entry.re);
833-
php_error_docref(NULL, E_WARNING, "Internal pcre2_pattern_info() error %d", rc);
834-
pcre_handle_exec_error(PCRE2_ERROR_INTERNAL);
835-
return NULL;
836-
}
837-
838-
rc = pcre2_pattern_info(re, PCRE2_INFO_NAMECOUNT, &new_entry.name_count);
839-
if (rc < 0) {
829+
if ((rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &new_entry.capture_count)) < 0 ||
830+
(rc = pcre2_pattern_info(re, PCRE2_INFO_NAMECOUNT, &new_entry.name_count)) < 0) {
840831
if (key != regex) {
841832
zend_string_release_ex(key, 0);
842833
}

0 commit comments

Comments
 (0)