diff --git a/NEWS b/NEWS index 6fba1e4e64a..1a4b588aa1e 100644 --- a/NEWS +++ b/NEWS @@ -60,6 +60,9 @@ PHP NEWS - PCRE: . Fixed preg_match memory leak with invalid regexes. (David Carlier) + . Fixed pcre2_code leak when pcre2_pattern_info() fails after a + successful pcre2_compile(), and match_sets/match_data/marks leaks + in php_pcre_match_impl(). (David Carlier) - PDO_PGSQL: . Fixed bug GH-21055 (connection attribute status typo for GSS negotiation). diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 24931466199..ff53380afae 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -840,6 +840,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo if (key != regex) { zend_string_release_ex(key, 0); } + pcre2_code_free(new_entry.re); php_error_docref(NULL, E_WARNING, "Internal pcre2_pattern_info() error %d", rc); pcre_handle_exec_error(PCRE2_ERROR_INTERNAL); return NULL; @@ -850,6 +851,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo if (key != regex) { zend_string_release_ex(key, 0); } + pcre2_code_free(new_entry.re); php_error_docref(NULL, E_WARNING, "Internal pcre_pattern_info() error %d", rc); pcre_handle_exec_error(PCRE2_ERROR_INTERNAL); return NULL; @@ -1294,7 +1296,18 @@ matched: if (subpats != NULL) { /* Try to get the list of substrings and display a warning if failed. */ if (UNEXPECTED(offsets[1] < offsets[0])) { - if (match_sets) efree(match_sets); + if (match_sets) { + for (i = 0; i < num_subpats; i++) { + zend_array_destroy(match_sets[i]); + } + efree(match_sets); + } + if (marks) { + zend_array_destroy(marks); + } + if (match_data != mdata) { + pcre2_match_data_free(match_data); + } php_error_docref(NULL, E_WARNING, "Get subpatterns list failed"); RETURN_FALSE; } diff --git a/ext/pcre/tests/preg_match_all_negative_length_match.phpt b/ext/pcre/tests/preg_match_all_negative_length_match.phpt new file mode 100644 index 00000000000..0deb27749e1 --- /dev/null +++ b/ext/pcre/tests/preg_match_all_negative_length_match.phpt @@ -0,0 +1,10 @@ +--TEST-- +preg_match_all() resource cleanup when \K in lookahead causes negative-length match +--FILE-- + +--EXPECTF-- +Warning: preg_match_all(): Get subpatterns list failed in %s on line %d +bool(false) diff --git a/ext/pcre/tests/preg_match_negative_length_match.phpt b/ext/pcre/tests/preg_match_negative_length_match.phpt new file mode 100644 index 00000000000..f321cb20b9c --- /dev/null +++ b/ext/pcre/tests/preg_match_negative_length_match.phpt @@ -0,0 +1,10 @@ +--TEST-- +preg_match() resource cleanup when \K in lookahead causes negative-length match +--FILE-- + +--EXPECTF-- +Warning: preg_match(): Get subpatterns list failed in %s on line %d +bool(false)