Skip to content

Commit c266670

Browse files
committed
Introduce zend_safe_string_address_guarded()
This is a variant of `zend_safe_address_guarded()` which also caters to `ZSTR_MAX_LEN`. We put it into zend_multiply.h instead of zend_string.h to avoid inclusion issues (zend.h includes zend_string.h and vice versa).
1 parent 58e6299 commit c266670

File tree

2 files changed

+15
-19
lines changed

2 files changed

+15
-19
lines changed

Zend/zend_multiply.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,4 +340,16 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si
340340
return ret;
341341
}
342342

343+
static zend_always_inline size_t zend_safe_string_address_guarded(size_t nmemb, size_t size, size_t offset)
344+
{
345+
int overflow;
346+
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
347+
348+
if (UNEXPECTED(overflow) || ret > ZSTR_MAX_LEN) {
349+
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
350+
return 0;
351+
}
352+
return ret;
353+
}
354+
343355
#endif /* ZEND_MULTIPLY_H */

ext/pcre/php_pcre.c

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,15 +1719,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
17191719
}
17201720

17211721
if (new_len >= alloc_len) {
1722-
alloc_len = zend_safe_address_guarded(2, new_len, 0);
1723-
if (UNEXPECTED(alloc_len > ZSTR_MAX_LEN)) {
1724-
zend_throw_error(NULL, "String size overflow");
1725-
if (result != NULL) {
1726-
zend_string_release_ex(result, 0);
1727-
result = NULL;
1728-
}
1729-
break;
1730-
}
1722+
alloc_len = zend_safe_string_address_guarded(2, new_len, 0);
17311723
if (result == NULL) {
17321724
result = zend_string_alloc(alloc_len, 0);
17331725
} else {
@@ -1963,17 +1955,9 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
19631955
pcre2_get_mark(match_data), flags);
19641956

19651957
ZEND_ASSERT(eval_result);
1966-
new_len = zend_safe_address_guarded(1, ZSTR_LEN(eval_result), new_len);
1958+
new_len = zend_safe_string_address_guarded(1, ZSTR_LEN(eval_result), new_len);
19671959
if (new_len >= alloc_len) {
1968-
alloc_len = zend_safe_address_guarded(2, new_len, 0);
1969-
if (UNEXPECTED(alloc_len > ZSTR_MAX_LEN)) {
1970-
zend_throw_error(NULL, "String size overflow");
1971-
if (result != NULL) {
1972-
zend_string_release_ex(result, 0);
1973-
result = NULL;
1974-
}
1975-
break;
1976-
}
1960+
alloc_len = zend_safe_string_address_guarded(2, new_len, 0);
19771961
if (result == NULL) {
19781962
result = zend_string_alloc(alloc_len, 0);
19791963
} else {

0 commit comments

Comments
 (0)