From 5b09e6043c930168cacce3aa37346560be65d8b3 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Sat, 24 Aug 2019 01:52:17 +0200 Subject: [PATCH] Remove memory exhaustion checks in php_chunk_split() --- ext/standard/string.c | 21 +++------------ ext/standard/tests/strings/chunk_split.phpt | 13 ---------- .../strings/chunk_split_variation1_32bit.phpt | 25 ++++++++++++++++++ .../strings/chunk_split_variation2_32bit.phpt | 25 ++++++++++++++++++ .../tests/strings/chunk_split_variation3.phpt | 26 +++++++++++++++++++ 5 files changed, 79 insertions(+), 31 deletions(-) create mode 100644 ext/standard/tests/strings/chunk_split_variation1_32bit.phpt create mode 100644 ext/standard/tests/strings/chunk_split_variation2_32bit.phpt create mode 100644 ext/standard/tests/strings/chunk_split_variation3.phpt diff --git a/ext/standard/string.c b/ext/standard/string.c index 526eb1353a..e9a584aa29 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2105,7 +2105,6 @@ static zend_string *php_chunk_split(const char *src, size_t srclen, const char * const char *p; size_t chunks; size_t restlen; - size_t out_len; zend_string *dest; chunks = srclen / chunklen; @@ -2116,17 +2115,7 @@ static zend_string *php_chunk_split(const char *src, size_t srclen, const char * chunks++; } - out_len = chunks; - if (endlen !=0 && out_len > INT_MAX/endlen) { - return NULL; - } - out_len *= endlen; - if (out_len > INT_MAX - srclen) { - return NULL; - } - out_len += srclen; - - dest = zend_string_alloc(out_len * sizeof(char), 0); + dest = zend_string_safe_alloc(chunks, endlen, srclen, 0); for (p = src, q = ZSTR_VAL(dest); p < (src + srclen - chunklen + 1); ) { memcpy(q, p, chunklen); @@ -2150,7 +2139,7 @@ static zend_string *php_chunk_split(const char *src, size_t srclen, const char * } /* }}} */ -/* {{{ proto string|false chunk_split(string str [, int chunklen [, string ending]]) +/* {{{ proto string chunk_split(string str [, int chunklen [, string ending]]) Returns split line */ PHP_FUNCTION(chunk_split) { @@ -2187,11 +2176,7 @@ PHP_FUNCTION(chunk_split) result = php_chunk_split(ZSTR_VAL(str), ZSTR_LEN(str), end, endlen, (size_t)chunklen); - if (result) { - RETURN_STR(result); - } else { - RETURN_FALSE; - } + RETURN_STR(result); } /* }}} */ diff --git a/ext/standard/tests/strings/chunk_split.phpt b/ext/standard/tests/strings/chunk_split.phpt index 648388f23a..a2696cd26b 100644 --- a/ext/standard/tests/strings/chunk_split.phpt +++ b/ext/standard/tests/strings/chunk_split.phpt @@ -7,17 +7,6 @@ echo chunk_split('foooooooooooooooo', 5)."\n"; echo chunk_split(str_repeat('X', 2*76))."\n"; echo chunk_split("test", 10, "|end") . "\n"; -$a=str_repeat("B", 65535); -$b=1; -$c=str_repeat("B", 65535); -var_dump(chunk_split($a,$b,$c)); - -$a=str_repeat("B", 65537); -$b=1; -$c=str_repeat("B", 65537); -var_dump(chunk_split($a,$b,$c)); - - ?> --EXPECT-- a-b-c- @@ -30,5 +19,3 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX test|end -bool(false) -bool(false) diff --git a/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt b/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt new file mode 100644 index 0000000000..be673dd93a --- /dev/null +++ b/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test chunk_split() function : usage variations - unexpected large '$end' string argument variation 1 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing chunk_split() : unexpected large 'end' string argument variation 1 *** + +Fatal error: Allowed memory size of %d bytes exhausted at %s (tried to allocate %d bytes) in %s on line %d diff --git a/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt b/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt new file mode 100644 index 0000000000..ca0948d999 --- /dev/null +++ b/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test chunk_split() function : usage variations - unexpected large '$end' string argument variation 2 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing chunk_split() : unexpected large 'end' string argument variation 2 *** + +Fatal error: Possible integer overflow in memory allocation (65537 * 65537 + 65556) in %s on line %d diff --git a/ext/standard/tests/strings/chunk_split_variation3.phpt b/ext/standard/tests/strings/chunk_split_variation3.phpt new file mode 100644 index 0000000000..687aa087d6 --- /dev/null +++ b/ext/standard/tests/strings/chunk_split_variation3.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test chunk_split() function : usage variations - unexpected large number of chunks +--FILE-- + +--EXPECTF-- +*** Testing chunk_split() : unexpected large 'end' string argument variation 2 *** +Body generation +Using chunk_split() + +Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d -- 2.50.1