From 9fa70dbd29f91c9ae9360f19c63ada18268f5b17 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 20 Jun 2015 15:09:58 +0200 Subject: [PATCH] Fixed bug #69889 There is one case that requires further discussion: $foo = "test"; var_dump($foo[0.0] ?? "default"); var_dump(isset($foo[0.0]) ? $foo[0.0] : "default"); Here the former will currently return "t", while the latter also returns "t" and additionally throws a notice. I think we need to revisit the behavior of invalid types for string offset access in PHP 7, as currently there is some mismatch between what isset() does and what the access itself supports. --- NEWS | 2 ++ Zend/tests/bug69889.phpt | 22 ++++++++++++++++++++++ Zend/zend_execute.c | 10 +++++++--- 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 Zend/tests/bug69889.phpt diff --git a/NEWS b/NEWS index c25ce52af2..a3c770923e 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,8 @@ PHP NEWS 7/8/8.1/10 as "Business"). (Christian Wenz) . Fixes bug #69835 (phpinfo() does not report many Windows SKUs). (Christian Wenz) + . Fixed bug #69889 (Null coalesce operator doesn't work for string offsets). + (Nikita) - DOM: . Fixed bug #69846 (Segmenation fault (access violation) when iterating over diff --git a/Zend/tests/bug69889.phpt b/Zend/tests/bug69889.phpt new file mode 100644 index 0000000000..8aae7c16f7 --- /dev/null +++ b/Zend/tests/bug69889.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #69889: Null coalesce operator doesn't work for string offsets +--FILE-- + +--EXPECT-- +string(1) "t" +string(7) "default" +string(7) "default" +string(7) "default" +string(7) "default" + diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 9190eff2c3..a62ff55c69 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1781,9 +1781,11 @@ try_string_offset: if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) { break; } - if (type != BP_VAR_IS) { - zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim)); + if (type == BP_VAR_IS) { + ZVAL_NULL(result); + return; } + zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim)); break; case IS_DOUBLE: case IS_NULL: @@ -1809,8 +1811,10 @@ try_string_offset: if (UNEXPECTED(offset < 0) || UNEXPECTED(Z_STRLEN_P(container) <= (size_t)offset)) { if (type != BP_VAR_IS) { zend_error(E_NOTICE, "Uninitialized string offset: %pd", offset); + ZVAL_EMPTY_STRING(result); + } else { + ZVAL_NULL(result); } - ZVAL_EMPTY_STRING(result); } else { zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[offset]; -- 2.50.1