]> granicus.if.org Git - php/commitdiff
Fixed bug #69889
authorNikita Popov <nikic@php.net>
Sat, 20 Jun 2015 13:09:58 +0000 (15:09 +0200)
committerNikita Popov <nikic@php.net>
Sat, 20 Jun 2015 13:09:58 +0000 (15:09 +0200)
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
Zend/tests/bug69889.phpt [new file with mode: 0644]
Zend/zend_execute.c

diff --git a/NEWS b/NEWS
index c25ce52af26325134344668b5a9d3c2d23db8a10..a3c770923e0c02654dba474edc18d251b7920aa0 100644 (file)
--- 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 (file)
index 0000000..8aae7c1
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+Bug #69889: Null coalesce operator doesn't work for string offsets
+--FILE--
+<?php
+
+$foo = "test";
+var_dump($foo[0] ?? "default");
+
+var_dump($foo[5] ?? "default");
+var_dump(isset($foo[5]) ? $foo[5] : "default");
+
+var_dump($foo["str"] ?? "default");
+var_dump(isset($foo["str"]) ? $foo["str"] : "default");
+
+?>
+--EXPECT--
+string(1) "t"
+string(7) "default"
+string(7) "default"
+string(7) "default"
+string(7) "default"
+
index 9190eff2c346b4d606bba57504486ed82b4b6052..a62ff55c69f90778af5c77116bb3deba0ee8c79d 100644 (file)
@@ -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];