From 418fcd22e835420c2bdaef55c62d8a45101f62b7 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Tue, 20 Apr 2021 19:20:42 +0100 Subject: [PATCH] Fix Bug #80972: Memory exhaustion on invalid string offset Closes GH-6890 --- NEWS | 1 + Zend/tests/bug31098.phpt | 3 ++- Zend/tests/bug53432.phpt | 2 +- Zend/tests/bug80972.phpt | 41 ++++++++++++++++++++++++++++++++++++ Zend/tests/indexing_001.phpt | 6 +----- Zend/zend_execute.c | 8 +++++++ 6 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 Zend/tests/bug80972.phpt diff --git a/NEWS b/NEWS index 1ae96a1e372d3..a9896da34fd18 100644 --- a/NEWS +++ b/NEWS @@ -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) diff --git a/Zend/tests/bug31098.phpt b/Zend/tests/bug31098.phpt index 1cad1108c08da..862fc6fc46dce 100644 --- a/Zend/tests/bug31098.phpt +++ b/Zend/tests/bug31098.phpt @@ -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) diff --git a/Zend/tests/bug53432.phpt b/Zend/tests/bug53432.phpt index fb6b80857aa0d..aa2a6015f51f4 100644 --- a/Zend/tests/bug53432.phpt +++ b/Zend/tests/bug53432.phpt @@ -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 diff --git a/Zend/tests/bug80972.phpt b/Zend/tests/bug80972.phpt new file mode 100644 index 0000000000000..01d1a98952da8 --- /dev/null +++ b/Zend/tests/bug80972.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #80972: Memory exhaustion on invalid string offset +--FILE-- +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" diff --git a/Zend/tests/indexing_001.phpt b/Zend/tests/indexing_001.phpt index c712b09802359..00f98237b595d 100644 --- a/Zend/tests/indexing_001.phpt +++ b/Zend/tests/indexing_001.phpt @@ -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 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 2edc155e9107f..821b9c8ec39fd 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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);