summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2017-10-26 10:07:08 +0800
committerXinchen Hui <laruence@gmail.com>2017-10-26 10:07:08 +0800
commitd2047503cbc080ef96b00ac254604aaa01cf618e (patch)
treecd87186649ca60582fc48e7da30f7153d75fed52
parent578ba71b3b0a636554675be6a8f441615e74b80c (diff)
downloadphp-git-d2047503cbc080ef96b00ac254604aaa01cf618e.tar.gz
Fixed bug #75420 (Crash when modifing property name in __isset for BP_VAR_IS)
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug75420.phpt15
-rw-r--r--Zend/zend_object_handlers.c7
3 files changed, 22 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 8bb9f28fc3..e3d8178646 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PHP NEWS
?? ??? 2017 PHP 7.0.26
- Core:
+ . Fixed bug #75420 (Crash when modifing property name in __isset for
+ BP_VAR_IS). (Laruence)
. Fixed bug #75368 (mmap/munmap trashing on unlucky allocations). (Nikita,
Dmitry)
diff --git a/Zend/tests/bug75420.phpt b/Zend/tests/bug75420.phpt
new file mode 100644
index 0000000000..890fbe5ad5
--- /dev/null
+++ b/Zend/tests/bug75420.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug #75420 (Crash when modifing property name in __isset for BP_VAR_IS)
+--FILE--
+<?php
+
+class Test {
+ public function __isset($x) { $GLOBALS["name"] = 24; return true; }
+public function __get($x) { var_dump($x); return 42; }
+}
+
+$obj = new Test;
+$name = "foo";
+var_dump($obj->$name ?? 12);
+?>
+--EXPECT--
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 9ce9f1df1a..22455b9254 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -510,6 +510,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_
zval tmp_member;
zval *retval;
uint32_t property_offset;
+ zend_long *guard = NULL;
zobj = Z_OBJ_P(object);
@@ -545,7 +546,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_
/* magic isset */
if ((type == BP_VAR_IS) && zobj->ce->__isset) {
zval tmp_object, tmp_result;
- zend_long *guard = zend_get_property_guard(zobj, Z_STR_P(member));
+ guard = zend_get_property_guard(zobj, Z_STR_P(member));
if (!((*guard) & IN_ISSET)) {
ZVAL_COPY(&tmp_object, object);
@@ -569,7 +570,9 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_
/* magic get */
if (zobj->ce->__get) {
- zend_long *guard = zend_get_property_guard(zobj, Z_STR_P(member));
+ if (guard == NULL) {
+ guard = zend_get_property_guard(zobj, Z_STR_P(member));
+ }
if (!((*guard) & IN_GET)) {
zval tmp_object;