summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Walker <dave@mudsite.com>2018-02-14 22:06:34 -0700
committerNikita Popov <nikita.ppv@gmail.com>2019-02-14 12:50:25 +0100
commite63febb1c772e15c1da891f00e3a343090e43c67 (patch)
tree995c82b1627d266332e6cf1dfa8eca8cfce7c2a2
parentdab54624842e76350bb6f5e71a8ef0f53ed34630 (diff)
downloadphp-git-e63febb1c772e15c1da891f00e3a343090e43c67.tar.gz
Fixed bug #75921
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).
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug52041.phpt6
-rw-r--r--Zend/tests/bug71539_5.phpt3
-rw-r--r--Zend/tests/bug75921.phpt80
-rw-r--r--Zend/tests/objects_020.phpt1
-rw-r--r--Zend/tests/type_declarations/typed_properties_091.phpt4
-rw-r--r--Zend/zend_execute.c38
-rw-r--r--ext/simplexml/tests/bug36611.phpt8
-rw-r--r--tests/lang/engine_assignExecutionOrder_008.phpt8
-rw-r--r--tests/lang/foreachLoop.016.phpt8
-rw-r--r--tests/lang/passByReference_006.phpt48
11 files changed, 168 insertions, 38 deletions
diff --git a/NEWS b/NEWS
index 2902141140..35680aefcf 100644
--- 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).
diff --git a/Zend/tests/bug52041.phpt b/Zend/tests/bug52041.phpt
index 7e1f3423a6..a1eb1f841b 100644
--- a/Zend/tests/bug52041.phpt
+++ b/Zend/tests/bug52041.phpt
@@ -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
diff --git a/Zend/tests/bug71539_5.phpt b/Zend/tests/bug71539_5.phpt
index 14559bf65e..7e89971ec2 100644
--- a/Zend/tests/bug71539_5.phpt
+++ b/Zend/tests/bug71539_5.phpt
@@ -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
index 0000000000..917dd413cc
--- /dev/null
+++ b/Zend/tests/bug75921.phpt
@@ -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)
+ }
+ }
+}
diff --git a/Zend/tests/objects_020.phpt b/Zend/tests/objects_020.phpt
index 14e34b9155..4b0e0d1ec7 100644
--- a/Zend/tests/objects_020.phpt
+++ b/Zend/tests/objects_020.phpt
@@ -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*
diff --git a/Zend/tests/type_declarations/typed_properties_091.phpt b/Zend/tests/type_declarations/typed_properties_091.phpt
index 7d6b54ae59..2083086086 100644
--- a/Zend/tests/type_declarations/typed_properties_091.phpt
+++ b/Zend/tests/type_declarations/typed_properties_091.phpt
@@ -135,6 +135,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"]=>
&NULL
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 2c7a4512a2..7fb7e44792 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -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;
diff --git a/ext/simplexml/tests/bug36611.phpt b/ext/simplexml/tests/bug36611.phpt
index eb202671ca..d9c2a049b5 100644
--- a/ext/simplexml/tests/bug36611.phpt
+++ b/ext/simplexml/tests/bug36611.phpt
@@ -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===
diff --git a/tests/lang/engine_assignExecutionOrder_008.phpt b/tests/lang/engine_assignExecutionOrder_008.phpt
index be9b3423c8..310e0d9964 100644
--- a/tests/lang/engine_assignExecutionOrder_008.phpt
+++ b/tests/lang/engine_assignExecutionOrder_008.phpt
@@ -70,10 +70,16 @@ 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
C::$p[0]=f(): good
diff --git a/tests/lang/foreachLoop.016.phpt b/tests/lang/foreachLoop.016.phpt
index 00deb5f1db..fa1267fa8d 100644
--- a/tests/lang/foreachLoop.016.phpt
+++ b/tests/lang/foreachLoop.016.phpt
@@ -158,18 +158,24 @@ 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]=>
string(8) "original"
}
$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"
@@ -178,6 +184,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]=>
string(8) "original"
diff --git a/tests/lang/passByReference_006.phpt b/tests/lang/passByReference_006.phpt
index 9f5d275333..c1478663ca 100644
--- a/tests/lang/passByReference_006.phpt
+++ b/tests/lang/passByReference_006.phpt
@@ -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"