8000 Merge branch 'PHP-8.0' · nikic/php-src@e80dbd5 · GitHub
[go: up one dir, main page]

Skip to content

Commit e80dbd5

Browse files
committed
Merge branch 'PHP-8.0'
* PHP-8.0: Fix #81243: Too much memory is allocated for preg_replace()
2 parents 989205e + 5fb5a73 commit e80dbd5

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

ext/pcre/php_pcre.c

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,7 +1716,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
17161716
}
17171717

17181718
if (new_len >= alloc_len) {
1719-
alloc_len = zend_safe_address_guarded(2, new_len, alloc_len);
1719+
alloc_len = zend_safe_address_guarded(2, new_len, 0);
17201720
if (result == NULL) {
17211721
result = zend_string_alloc(alloc_len, 0);
17221722
} else {
@@ -1802,14 +1802,12 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
18021802
result = zend_string_copy(subject_str);
18031803
break;
18041804
}
1805-
new_len = result_len + subject_len - last_end_offset;
1806-
if (new_len >= alloc_len) {
1807-
alloc_len = new_len; /* now we know exactly how long it is */
1808-
if (NULL != result) {
1809-
result = zend_string_realloc(result, alloc_len, 0);
1810-
} else {
1811-
result = zend_string_alloc(alloc_len, 0);
1812-
}
1805+
/* now we know exactly how long it is */
1806+
alloc_len = result_len + subject_len - last_end_offset;
1807+
if (NULL != result) {
1808+
result = zend_string_realloc(result, alloc_len, 0);
1809+
} else {
1810+
result = zend_string_alloc(alloc_len, 0);
18131811
}
18141812
/* stick that last bit of string on our output */
18151813
memcpy(ZSTR_VAL(result) + result_len, piece, subject_len - last_end_offset);
@@ -1956,7 +1954,7 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
19561954
ZEND_ASSERT(eval_result);
19571955
new_len = zend_safe_address_guarded(1, ZSTR_LEN(eval_result), new_len);
19581956
if (new_len >= alloc_len) {
1959-
alloc_len = zend_safe_address_guarded(2, new_len, alloc_len);
1957+
alloc_len = zend_safe_address_guarded(2, new_len, 0);
19601958
if (result == NULL) {
19611959
result = zend_string_alloc(alloc_len, 0);
19621960
} else {
@@ -2013,14 +2011,12 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
20132011
result = zend_string_copy(subject_str);
20142012
break;
20152013
}
2016-
new_len = result_len + subject_len - last_end_offset;
2017-
if (new_len >= alloc_len) {
2018-
alloc_len = new_len; /* now we know exactly how long it is */
2019-
if (NULL != result) {
2020-
result = zend_string_realloc(result, alloc_len, 0);
2021-
} else {
2022-
result = zend_string_alloc(alloc_len, 0);
2023-
}
2014+
/* now we know exactly how long it is */
2015+
alloc_len = result_len + subject_len - last_end_offset;
2016+
if (NULL != result) {
2017+
result = zend_string_realloc(result, alloc_len, 0);
2018+
} else {
2019+
result = zend_string_alloc(alloc_len, 0);
20242020
}
20252021
/* stick that last bit of string on our output */
20262022
memcpy(ZSTR_VAL(result) + result_len, piece, subject_len - last_end_offset);

ext/pcre/tests/bug81243.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Bug #81243 (Too much memory is allocated for preg_replace())
3+
--FILE--
4+
<?php
5+
$test_string = str_repeat('Eins zwei drei', 2000);
6+
7+
$replaced = preg_replace('/\s/', '-', $test_string);
8+
$mem0 = memory_get_usage();
9+
$replaced = str_repeat($replaced, 1);
10+
$mem1 = memory_get_usage();
11+
var_dump($mem0 == $mem1);
12+
13+
$replaced = preg_replace_callback('/\s/', function ($_) {return '-';}, $test_string);
14+
$mem0 = memory_get_usage();
15+
$replaced = str_repeat($replaced, 1);
16+
$mem1 = memory_get_usage();
17+
var_dump($mem0 == $mem1);
18+
?>
19+
--EXPECT--
20+
bool(true)
21+
bool(true)

0 commit comments

Comments
 (0)
0