Fix Bug #80972: Memory exhaustion on invalid string offset

Closes GH-6890
This commit is contained in:
George Peter Banyard 2021-04-20 19:20:42 +01:00
parent fe219d912e
commit 418fcd22e8
No known key found for this signature in database
GPG Key ID: D49A095D7329F6DC
6 changed files with 54 additions and 7 deletions

1
NEWS
View File

@ -7,6 +7,7 @@ PHP NEWS
(cmb)
. Fixed bug #67792 (HTTP Authorization schemes are treated as case-sensitive).
(cmb)
. Fixed bug Bug #80972 (Memory exhaustion on invalid string offset). (girgias)
- pgsql:
. Fixed php_pgsql_fd_cast() wrt. php_stream_can_cast(). (cmb)

View File

@ -35,11 +35,12 @@ try {
}
echo $simpleString["0"] === "B"?"ok\n":"bug\n";
try {
/* This must not affect the string value */
$simpleString["wrong"] = "f";
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
echo $simpleString["0"] === "f"?"ok\n":"bug\n";
echo $simpleString["0"] === "B"?"ok\n":"bug\n";
?>
--EXPECTF--
bool(false)

View File

@ -58,7 +58,7 @@ Warning: Illegal string offset -1 in %s on line %d
NULL
string(0) ""
Cannot access offset of type string on string
string(1) "a"
string(0) ""
Error: [] operator not supported for strings
string(0) ""
Error: Cannot use assign-op operators with string offsets

41
Zend/tests/bug80972.phpt Normal file
View File

@ -0,0 +1,41 @@
--TEST--
Bug #80972: Memory exhaustion on invalid string offset
--FILE--
<?php
function exceptions_error_handler($severity, $message, $filename, $lineno) {
if (error_reporting() & $severity) {
throw new ErrorException($message, 0, $severity, $filename, $lineno);
}
}
set_error_handler('exceptions_error_handler');
$float = 10e120;
$string_float = (string) $float;
$string = 'Here is some text for good measure';
try {
echo 'Float casted to string compile', \PHP_EOL;
$string[(string) 10e120] = 'E';
var_dump($string);
} catch (\TypeError $e) {
echo $e->getMessage(), \PHP_EOL;
}
/* This same bug also permits to modify the first byte of a string even if
* the offset is invalid */
try {
/* This must not affect the string value */
$string["wrong"] = "f";
} catch (\Throwable $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump($string);
?>
--EXPECT--
Float casted to string compile
Cannot access offset of type string on string
Cannot access offset of type string on string
string(34) "Here is some text for good measure"

View File

@ -52,7 +52,7 @@ foreach ($testvalues as $testvalue) {
}
?>
--EXPECTF--
--EXPECT--
*** Indexing - Testing value assignment with key ***
array(1) {
["foo"]=>
@ -74,12 +74,8 @@ array(1) {
int(1)
}
}
Warning: Array to string conversion in %s on line %d
Cannot access offset of type string on string
string(0) ""
Warning: Array to string conversion in %s on line %d
Cannot access offset of type string on string
string(1) " "
Cannot use a scalar value as an array

View File

@ -1525,6 +1525,14 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
zend_long offset;
offset = zend_check_string_offset(dim, BP_VAR_W EXECUTE_DATA_CC);
/* Illegal offset assignment */
if (UNEXPECTED(EG(exception) != NULL)) {
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
}
return;
}
if (offset < -(zend_long)Z_STRLEN_P(str)) {
/* Error on negative offset */
zend_error(E_WARNING, "Illegal string offset " ZEND_LONG_FMT, offset);