diff --git a/NEWS b/NEWS index 1878134bbf8..560ac396d6c 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,9 @@ PHP NEWS - OpenSSL: . Fixed bug #75725 (./configure: detecting RAND_egd). (Dilyan Palauzov) +- PCRE: + . Fixed bug #74604 (Out of bounds in php_pcre_replace_impl). (cmb, Dmitry) + - SPL: . Fixed bug #81587 (MultipleIterator Segmentation fault w/ SimpleXMLElement attached). (Nikita) diff --git a/Zend/zend_string.h b/Zend/zend_string.h index dc319fcba6c..ad46230c1d3 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -83,7 +83,8 @@ END_EXTERN_C() #define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1) -#define ZSTR_MAX_LEN (SIZE_MAX - ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1)) +#define ZSTR_MAX_OVERHEAD (ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1)) +#define ZSTR_MAX_LEN (SIZE_MAX - ZSTR_MAX_OVERHEAD) #define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \ (str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \ diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 340e103857f..d9b9d94c6f4 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1725,7 +1725,7 @@ matched: } if (new_len >= alloc_len) { - alloc_len = zend_safe_address_guarded(2, new_len, 0); + alloc_len = zend_safe_address_guarded(2, new_len, ZSTR_MAX_OVERHEAD) - ZSTR_MAX_OVERHEAD; if (result == NULL) { result = zend_string_alloc(alloc_len, 0); } else { @@ -1961,9 +1961,9 @@ matched: pcre2_get_mark(match_data), flags); ZEND_ASSERT(eval_result); - new_len = zend_safe_address_guarded(1, ZSTR_LEN(eval_result), new_len); + new_len = zend_safe_address_guarded(1, ZSTR_LEN(eval_result) + ZSTR_MAX_OVERHEAD, new_len) -ZSTR_MAX_OVERHEAD; if (new_len >= alloc_len) { - alloc_len = zend_safe_address_guarded(2, new_len, 0); + alloc_len = zend_safe_address_guarded(2, new_len, ZSTR_MAX_OVERHEAD) - ZSTR_MAX_OVERHEAD; if (result == NULL) { result = zend_string_alloc(alloc_len, 0); } else {