Skip to content

Commit 5b09e60

Browse files
committed
Remove memory exhaustion checks in php_chunk_split()
1 parent 6d57848 commit 5b09e60

File tree

5 files changed

+79
-31
lines changed

5 files changed

+79
-31
lines changed

ext/standard/string.c

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,7 +2105,6 @@ static zend_string *php_chunk_split(const char *src, size_t srclen, const char *
21052105
const char *p;
21062106
size_t chunks;
21072107
size_t restlen;
2108-
size_t out_len;
21092108
zend_string *dest;
21102109

21112110
chunks = srclen / chunklen;
@@ -2116,17 +2115,7 @@ static zend_string *php_chunk_split(const char *src, size_t srclen, const char *
21162115
chunks++;
21172116
}
21182117

2119-
out_len = chunks;
2120-
if (endlen !=0 && out_len > INT_MAX/endlen) {
2121-
return NULL;
2122-
}
2123-
out_len *= endlen;
2124-
if (out_len > INT_MAX - srclen) {
2125-
return NULL;
2126-
}
2127-
out_len += srclen;
2128-
2129-
dest = zend_string_alloc(out_len * sizeof(char), 0);
2118+
dest = zend_string_safe_alloc(chunks, endlen, srclen, 0);
21302119

21312120
for (p = src, q = ZSTR_VAL(dest); p < (src + srclen - chunklen + 1); ) {
21322121
memcpy(q, p, chunklen);
@@ -2150,7 +2139,7 @@ static zend_string *php_chunk_split(const char *src, size_t srclen, const char *
21502139
}
21512140
/* }}} */
21522141

2153-
/* {{{ proto string|false chunk_split(string str [, int chunklen [, string ending]])
2142+
/* {{{ proto string chunk_split(string str [, int chunklen [, string ending]])
21542143
Returns split line */
21552144
PHP_FUNCTION(chunk_split)
21562145
{
@@ -2187,11 +2176,7 @@ PHP_FUNCTION(chunk_split)
21872176

21882177
result = php_chunk_split(ZSTR_VAL(str), ZSTR_LEN(str), end, endlen, (size_t)chunklen);
21892178

2190-
if (result) {
2191-
RETURN_STR(result);
2192-
} else {
2193-
RETURN_FALSE;
2194-
}
2179+
RETURN_STR(result);
21952180
}
21962181
/* }}} */
21972182

ext/standard/tests/strings/chunk_split.phpt

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,6 @@ echo chunk_split('foooooooooooooooo', 5)."\n";
77
echo chunk_split(str_repeat('X', 2*76))."\n";
88
echo chunk_split("test", 10, "|end") . "\n";
99

10-
$a=str_repeat("B", 65535);
11-
$b=1;
12-
$c=str_repeat("B", 65535);
13-
var_dump(chunk_split($a,$b,$c));
14-
15-
$a=str_repeat("B", 65537);
16-
$b=1;
17-
$c=str_repeat("B", 65537);
18-
var_dump(chunk_split($a,$b,$c));
19-
20-
2110
?>
2211
--EXPECT--
2312
a-b-c-
@@ -30,5 +19,3 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3019
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3120

3221
test|end
33-
bool(false)
34-
bool(false)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Test chunk_split() function : usage variations - unexpected large '$end' string argument variation 1
3+
--SKIPIF--
4+
<?php
5+
if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only");
6+
?>
7+
--FILE--
8+
<?php
9+
/* Prototype : string chunk_split(string $str [, int $chunklen [, string $ending]])
10+
* Description: Returns split line
11+
* Source code: ext/standard/string.c
12+
* Alias to functions: none
13+
*/
14+
15+
echo "*** Testing chunk_split() : unexpected large 'end' string argument variation 1 ***\n";
16+
17+
$a=str_repeat("B", 65535);
18+
$b=1;
19+
$c=str_repeat("B", 65535);
20+
var_dump(chunk_split($a,$b,$c));
21+
?>
22+
--EXPECTF--
23+
*** Testing chunk_split() : unexpected large 'end' string argument variation 1 ***
24+
25+
Fatal error: Allowed memory size of %d bytes exhausted at %s (tried to allocate %d bytes) in %s on line %d
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Test chunk_split() function : usage variations - unexpected large '$end' string argument variation 2
3+
--SKIPIF--
4+
<?php
5+
if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only");
6+
?>
7+
--FILE--
8+
<?php
9+
/* Prototype : string chunk_split(string $str [, int $chunklen [, string $ending]])
10+
* Description: Returns split line
11+
* Source code: ext/standard/string.c
12+
* Alias to functions: none
13+
*/
14+
15+
echo "*** Testing chunk_split() : unexpected large 'end' string argument variation 2 ***\n";
16+
17+
$a=str_repeat("B", 65537);
18+
$b=1;
19+
$c=str_repeat("B", 65537);
20+
var_dump(chunk_split($a,$b,$c));
21+
?>
22+
--EXPECTF--
23+
*** Testing chunk_split() : unexpected large 'end' string argument variation 2 ***
24+
25+
Fatal error: Possible integer overflow in memory allocation (65537 * 65537 + 65556) in %s on line %d
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Test chunk_split() function : usage variations - unexpected large number of chunks
3+
--FILE--
4+
<?php
5+
/* Prototype : string chunk_split(string $str [, int $chunklen [, string $ending]])
6+
* Description: Returns split line
7+
* Source code: ext/standard/string.c
8+
* Alias to functions: none
9+
*/
10+
11+
$chunk_length = 1;
12+
13+
echo "*** Testing chunk_split() : unexpected large 'end' string argument variation 2 ***\n";
14+
15+
echo "Body generation\n";
16+
$body = str_repeat("Hello", 10000000);
17+
18+
echo "Using chunk_split()\n";
19+
var_dump(chunk_split($body, $chunk_length));
20+
?>
21+
--EXPECTF--
22+
*** Testing chunk_split() : unexpected large 'end' string argument variation 2 ***
23+
Body generation
24+
Using chunk_split()
25+
26+
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d

0 commit comments

Comments
 (0)