]> granicus.if.org Git - php/commitdiff
Fixed bug #75921
authorDavid Walker <dave@mudsite.com>
Thu, 15 Feb 2018 05:06:34 +0000 (22:06 -0700)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 14 Feb 2019 11:50:25 +0000 (12:50 +0100)
Ensure that the "creating default object from empty value" warning is
always thrown. Previously some cases were missing the warning, in
particular those going through FETCH_OBJ_W rather than a dedicated
opcode (like ASSIGN_OBJ).

One slightly unfortunate side-effect of this change is that something
like $a->b->c = 'd' will now generate two warnings rather than one
when $a is null (one for property b, one for property c).

NEWS
Zend/tests/bug52041.phpt
Zend/tests/bug71539_5.phpt
Zend/tests/bug75921.phpt [new file with mode: 0644]
Zend/tests/objects_020.phpt
Zend/tests/type_declarations/typed_properties_091.phpt
Zend/zend_execute.c
ext/simplexml/tests/bug36611.phpt
tests/lang/engine_assignExecutionOrder_008.phpt
tests/lang/foreachLoop.016.phpt
tests/lang/passByReference_006.phpt

diff --git a/NEWS b/NEWS
index 2902141140a896c414e934dff11e251b4dd2f647..35680aefcf69af8dc01671699c604a99e558ac3e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,8 @@ PHP                                                                        NEWS
     specially compiled functions). (Majkl578)
   . Fixed bug #76430 (__METHOD__ inconsistent outside of method).
     (Ryan McCullagh, Nikita)
+  . Fixed bug #75921 (Inconsistent: No warning in some cases when stdObj is
+    created on the fly). (David Walker)
 
 - CURL:
   . Fixed bug #76480 (Use curl_multi_wait() so that timeouts are respected).
index 7e1f3423a6ee24215d4e74baec6547242169c792..a1eb1f841ba886c66adfa9201ab0ad855226f794 100644 (file)
@@ -31,6 +31,8 @@ Notice: Undefined variable: x in %sbug52041.php on line 3
 
 Warning: Creating default object from empty value in %sbug52041.php on line 7
 
+Warning: Creating default object from empty value in %sbug52041.php on line 7
+
 Notice: Undefined variable: x in %sbug52041.php on line 3
 
 Warning: Creating default object from empty value in %sbug52041.php on line 8
@@ -39,6 +41,8 @@ Notice: Undefined property: stdClass::$a in %sbug52041.php on line 8
 
 Notice: Undefined variable: x in %sbug52041.php on line 3
 
+Warning: Creating default object from empty value in %sbug52041.php on line 9
+
 Notice: Undefined property: stdClass::$a in %sbug52041.php on line 9
 
 Warning: Creating default object from empty value in %sbug52041.php on line 9
@@ -53,6 +57,8 @@ Notice: Undefined property: stdClass::$a in %sbug52041.php on line 10
 
 Notice: Undefined variable: x in %sbug52041.php on line 3
 
+Warning: Creating default object from empty value in %sbug52041.php on line 11
+
 Notice: Undefined property: stdClass::$a in %sbug52041.php on line 11
 
 Warning: Creating default object from empty value in %sbug52041.php on line 11
index 14559bf65e641f02044ad6b316c7d4d59daab8b9..7e89971ec27f1da83567abb85435c97aae0ee351 100644 (file)
@@ -7,7 +7,8 @@ $array['']->prop =& $array[0];
 $array[0] = 42;
 var_dump($array);
 ?>
---EXPECT--
+--EXPECTF--
+Warning: Creating default object from empty value in %sbug71539_5.php on line 3
 array(2) {
   [0]=>
   &int(42)
diff --git a/Zend/tests/bug75921.phpt b/Zend/tests/bug75921.phpt
new file mode 100644 (file)
index 0000000..917dd41
--- /dev/null
@@ -0,0 +1,80 @@
+--TEST--
+Bug #75921: Inconsistent error when creating stdObject from empty variable
+--FILE--
+<?php
+
+$null->a = 42;
+var_dump($null);
+unset($null);
+
+$null->a['hello'] = 42;
+var_dump($null);
+unset($null);
+
+$null->a->b = 42;
+var_dump($null);
+unset($null);
+
+$null->a['hello']->b = 42;
+var_dump($null);
+unset($null);
+
+$null->a->b['hello'] = 42;
+var_dump($null);
+unset($null);
+
+?>
+--EXPECTF--
+Warning: Creating default object from empty value in %sbug75921.php on line 3
+object(stdClass)#1 (1) {
+  ["a"]=>
+  int(42)
+}
+
+Warning: Creating default object from empty value in %sbug75921.php on line 7
+object(stdClass)#1 (1) {
+  ["a"]=>
+  array(1) {
+    ["hello"]=>
+    int(42)
+  }
+}
+
+Warning: Creating default object from empty value in %sbug75921.php on line 11
+
+Warning: Creating default object from empty value in %sbug75921.php on line 11
+object(stdClass)#1 (1) {
+  ["a"]=>
+  object(stdClass)#2 (1) {
+    ["b"]=>
+    int(42)
+  }
+}
+
+Warning: Creating default object from empty value in %sbug75921.php on line 15
+
+Warning: Creating default object from empty value in %sbug75921.php on line 15
+object(stdClass)#1 (1) {
+  ["a"]=>
+  array(1) {
+    ["hello"]=>
+    object(stdClass)#2 (1) {
+      ["b"]=>
+      int(42)
+    }
+  }
+}
+
+Warning: Creating default object from empty value in %sbug75921.php on line 19
+
+Warning: Creating default object from empty value in %sbug75921.php on line 19
+object(stdClass)#1 (1) {
+  ["a"]=>
+  object(stdClass)#2 (1) {
+    ["b"]=>
+    array(1) {
+      ["hello"]=>
+      int(42)
+    }
+  }
+}
index 14e34b91557c3e5bab8a80ad03f2ee2891fd4e15..4b0e0d1ec7be9e91609c23cf6c48c0a8ae80943b 100644 (file)
@@ -14,6 +14,7 @@ var_dump($$test);
 
 ?>
 --EXPECTF--
+Warning: Creating default object from empty value in %sobjects_020.php on line 7
 object(stdClass)#%d (2) {
   ["a"]=>
   *RECURSION*
index 7d6b54ae5956eb4df43b31ef44bd1ad39441808d..2083086086cd59dd7f6cadb3d9b77a6cba8761ae 100644 (file)
@@ -134,6 +134,10 @@ Cannot auto-initialize an stdClass inside a reference held by property Test::$pr
 
 Warning: Creating default object from empty value in %s on line %d
 
+Warning: Creating default object from empty value in %s on line %d
+
+Warning: Creating default object from empty value in %s on line %d
+
 Warning: Creating default object from empty value in %s on line %d
 object(Test)#3 (3) {
   ["prop"]=>
index 2c7a4512a26efe10b264d695fa0624811f464cc8..7fb7e44792c7555c778820c87637b4988d76a9ff 100644 (file)
@@ -709,6 +709,10 @@ static zend_never_inline ZEND_COLD zval* ZEND_FASTCALL make_real_object(zval *ob
                         || opline->opcode == ZEND_POST_INC_OBJ
                         || opline->opcode == ZEND_POST_DEC_OBJ) {
                                zend_error(E_WARNING, "Attempt to increment/decrement property '%s' of non-object", ZSTR_VAL(property_name));
+                       } else if (opline->opcode == ZEND_FETCH_OBJ_W
+                                       || opline->opcode == ZEND_FETCH_OBJ_RW
+                                       || opline->opcode == ZEND_ASSIGN_OBJ_REF) {
+                               zend_error(E_WARNING, "Attempt to modify property '%s' of non-object", ZSTR_VAL(property_name));
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name));
                        }
@@ -748,38 +752,6 @@ static zend_never_inline ZEND_COLD zval* ZEND_FASTCALL make_real_object(zval *ob
        return object;
 }
 
-static zend_never_inline ZEND_COLD zval* ZEND_FASTCALL make_real_object_rw(zval *object, zval *property OPLINE_DC)
-{
-       zval *ref = NULL;
-       if (Z_ISREF_P(object)) {
-               ref = object;
-               object = Z_REFVAL_P(object);
-       }
-
-       if (UNEXPECTED(Z_TYPE_P(object) > IS_FALSE &&
-                       (Z_TYPE_P(object) != IS_STRING || Z_STRLEN_P(object) != 0))) {
-               if (opline->op1_type != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) {
-                       zend_string *tmp_property_name;
-                       zend_string *property_name = zval_get_tmp_string(property, &tmp_property_name);
-                       zend_error(E_WARNING, "Attempt to modify property '%s' of non-object", ZSTR_VAL(property_name));
-                       zend_tmp_string_release(tmp_property_name);
-               }
-               return NULL;
-       }
-
-       if (ref) {
-               zend_property_info *error_prop = i_zend_check_ref_stdClass_assignable(Z_REF_P(ref));
-               if (error_prop) {
-                       zend_throw_auto_init_in_ref_error(error_prop, "stdClass");
-                       return NULL;
-               }
-       }
-
-       zval_ptr_dtor_nogc(object);
-       object_init(object);
-       return object;
-}
-
 static ZEND_COLD void zend_verify_type_error_common(
                const zend_function *zf, const zend_arg_info *arg_info,
                const zend_class_entry *ce, zval *value,
@@ -2736,7 +2708,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
                                return;
                        }
 
-                       container = make_real_object_rw(container, prop_ptr OPLINE_CC);
+                       container = make_real_object(container, prop_ptr OPLINE_CC);
                        if (UNEXPECTED(!container)) {
                                ZVAL_ERROR(result);
                                return;
index eb202671ca1abd4072a7da387d0a527db9655cca..d9c2a049b561e84c46e95e9cbef6b5e2b0c82fcd 100644 (file)
@@ -14,17 +14,19 @@ $xml_str = <<<EOD
 </c_fpobel>
 EOD;
 
-$xml = simplexml_load_string ($xml_str) ;
+$xml = simplexml_load_string($xml_str);
 
 $val = 1;
 
 var_dump($val);
 $zml->pos["act_idx"] = $val;
-var_dump($val) ;
+var_dump($val);
 
 ?>
 ===DONE===
---EXPECT--
+--EXPECTF--
 int(1)
+
+Warning: Creating default object from empty value in %sbug36611.php on line 17
 int(1)
 ===DONE===
index be9b3423c8031d1e97a7ca37ae3ed69bd92b5f82..310e0d99641dbaf0cec4d40726c39190839f1eb6 100644 (file)
@@ -70,9 +70,15 @@ Warning: Creating default object from empty value in %s on line %d
 good
 $i->p->q=f(): 
 Warning: Creating default object from empty value in %s on line %d
+
+Warning: Creating default object from empty value in %s on line %d
+good
+$i->p[0]=f(): 
+Warning: Creating default object from empty value in %s on line %d
 good
-$i->p[0]=f(): good
 $i->p[0]->p=f(): 
+Warning: Creating default object from empty value in %s on line %d
+
 Warning: Creating default object from empty value in %s on line %d
 good
 C::$p=f(): good
index 00deb5f1db4566cbcfb6ca86d6738166fce02472..fa1267fa8dce8d76885265ebaa20c996a5357ea7 100644 (file)
@@ -157,6 +157,8 @@ array(1) {
 
 $a->b->c
 
+Warning: Creating default object from empty value in %s on line %d
+
 Warning: Creating default object from empty value in %s on line %d
 array(1) {
   [0]=>
@@ -164,12 +166,16 @@ array(1) {
 }
 
 $a->b[0]
+
+Warning: Creating default object from empty value in %s on line %d
 array(1) {
   [0]=>
   string(8) "original"
 }
 
 $a->b[0][0]
+
+Warning: Creating default object from empty value in %s on line %d
 array(1) {
   [0]=>
   string(8) "original"
@@ -177,6 +183,8 @@ array(1) {
 
 $a->b[0]->c
 
+Warning: Creating default object from empty value in %s on line %d
+
 Warning: Creating default object from empty value in %s on line %d
 array(1) {
   [0]=>
index 9f5d275333f66ed07181d63f73864d5bdc6c842e..c1478663ca7398b4e753e6fd389a61981a14c1f0 100644 (file)
@@ -55,6 +55,18 @@ var_dump($u1, $u2, $u3, $u4, $u5);
 ?>
 --EXPECTF--
  ---- Pass uninitialised array & object by ref: function call ---
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
 array(1) {
   [0]=>
   string(12) "Ref1 changed"
@@ -91,6 +103,18 @@ object(stdClass)#%d (1) {
  ---- Pass uninitialised arrays & objects by ref: static method call ---
 
 Deprecated: Non-static method C::refs() should not be called statically in %s on line 39
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
 array(1) {
   [0]=>
   string(12) "Ref1 changed"
@@ -126,6 +150,18 @@ object(stdClass)#%d (1) {
 
 
 ---- Pass uninitialised arrays & objects by ref: constructor ---
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
 array(1) {
   [0]=>
   string(12) "Ref1 changed"
@@ -160,6 +196,18 @@ object(stdClass)#%d (1) {
 }
 
  ---- Pass uninitialised arrays & objects by ref: instance method call ---
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
+
+Warning: Creating default object from empty value in %spassByReference_006.php on line %d
 array(1) {
   [0]=>
   string(12) "Ref1 changed"