Skip to content

Commit 9fa70db

Browse files
committed
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.
1 parent 257054e commit 9fa70db

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ PHP NEWS
2020
7/8/8.1/10 as "Business"). (Christian Wenz)
2121
. Fixes bug #69835 (phpinfo() does not report many Windows SKUs).
2222
(Christian Wenz)
23+
. Fixed bug #69889 (Null coalesce operator doesn't work for string offsets).
24+
(Nikita)
2325

2426
- DOM:
2527
. Fixed bug #69846 (Segmenation fault (access violation) when iterating over

Zend/tests/bug69889.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Bug #69889: Null coalesce operator doesn't work for string offsets
3+
--FILE--
4+
<?php
5+
6+
$foo = "test";
7+
var_dump($foo[0] ?? "default");
8+
9+
var_dump($foo[5] ?? "default");
10+
var_dump(isset($foo[5]) ? $foo[5] : "default");
11+
12+
var_dump($foo["str"] ?? "default");
13+
var_dump(isset($foo["str"]) ? $foo["str"] : "default");
14+
15+
?>
16+
--EXPECT--
17+
string(1) "t"
18+
string(7) "default"
19+
string(7) "default"
20+
string(7) "default"
21+
string(7) "default"
22+

Zend/zend_execute.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,9 +1781,11 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
17811781
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
17821782
break;
17831783
}
1784-
if (type != BP_VAR_IS) {
1785-
zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
1784+
if (type == BP_VAR_IS) {
1785+
ZVAL_NULL(result);
1786+
return;
17861787
}
1788+
zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
17871789
break;
17881790
case IS_DOUBLE:
17891791
case IS_NULL:
@@ -1809,8 +1811,10 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
18091811
if (UNEXPECTED(offset < 0) || UNEXPECTED(Z_STRLEN_P(container) <= (size_t)offset)) {
18101812
if (type != BP_VAR_IS) {
18111813
zend_error(E_NOTICE, "Uninitialized string offset: %pd", offset);
1814+
ZVAL_EMPTY_STRING(result);
1815+
} else {
1816+
ZVAL_NULL(result);
18121817
}
1813-
ZVAL_EMPTY_STRING(result);
18141818
} else {
18151819
zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[offset];
18161820

0 commit comments

Comments
 (0)