106 lines
2.4 KiB
Diff
106 lines
2.4 KiB
Diff
From ebd3a210021ec3b8f210822f0c69ee8f3132f1dc Mon Sep 17 00:00:00 2001
|
|
From: Nikita Popov <nikita.ppv@gmail.com>
|
|
Date: Thu, 15 Jul 2021 09:29:08 +0200
|
|
Subject: [PATCH] Undef slot before destroying in unset_property
|
|
|
|
We need to make sure that destructors can't access the partially
|
|
destroyed property. Do the same we do in HTs.
|
|
|
|
Fixes oss-fuzz #36205.
|
|
---
|
|
Zend/tests/unset_prop_recursion.phpt | 65 ++++++++++++++++++++++++++++++++++++
|
|
Zend/zend_object_handlers.c | 4 ++-
|
|
2 files changed, 68 insertions(+), 1 deletion(-)
|
|
create mode 100644 Zend/tests/unset_prop_recursion.phpt
|
|
|
|
diff --git a/Zend/tests/unset_prop_recursion.phpt b/Zend/tests/unset_prop_recursion.phpt
|
|
new file mode 100644
|
|
index 0000000..afb1929
|
|
--- /dev/null
|
|
+++ b/Zend/tests/unset_prop_recursion.phpt
|
|
@@ -0,0 +1,65 @@
|
|
+--TEST--
|
|
+Unset property where unset will recursively access property again
|
|
+--FILE--
|
|
+<?php
|
|
+class Node {
|
|
+ public $parent = null;
|
|
+ public $children = [];
|
|
+ function insert(Node $node) {
|
|
+ $node->parent = $this;
|
|
+ $this->children[] = $node;
|
|
+ }
|
|
+ function __destruct() {
|
|
+ var_dump($this);
|
|
+ unset($this->children);
|
|
+ }
|
|
+}
|
|
+
|
|
+$a = new Node;
|
|
+$a->insert(new Node);
|
|
+$a->insert(new Node);
|
|
+?>
|
|
+--EXPECT--
|
|
+object(Node)#1 (2) {
|
|
+ ["parent"]=>
|
|
+ NULL
|
|
+ ["children"]=>
|
|
+ array(2) {
|
|
+ [0]=>
|
|
+ object(Node)#2 (2) {
|
|
+ ["parent"]=>
|
|
+ *RECURSION*
|
|
+ ["children"]=>
|
|
+ array(0) {
|
|
+ }
|
|
+ }
|
|
+ [1]=>
|
|
+ object(Node)#3 (2) {
|
|
+ ["parent"]=>
|
|
+ *RECURSION*
|
|
+ ["children"]=>
|
|
+ array(0) {
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+object(Node)#2 (2) {
|
|
+ ["parent"]=>
|
|
+ object(Node)#1 (2) {
|
|
+ ["parent"]=>
|
|
+ NULL
|
|
+ }
|
|
+ ["children"]=>
|
|
+ array(0) {
|
|
+ }
|
|
+}
|
|
+object(Node)#3 (2) {
|
|
+ ["parent"]=>
|
|
+ object(Node)#1 (2) {
|
|
+ ["parent"]=>
|
|
+ NULL
|
|
+ }
|
|
+ ["children"]=>
|
|
+ array(0) {
|
|
+ }
|
|
+}
|
|
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
|
|
index 7c2bd13..e61a5af 100644
|
|
--- a/Zend/zend_object_handlers.c
|
|
+++ b/Zend/zend_object_handlers.c
|
|
@@ -1137,8 +1137,10 @@ ZEND_API void zend_std_unset_property(zval *object, zval *member, void **cache_s
|
|
ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(slot), prop_info);
|
|
}
|
|
}
|
|
- zval_ptr_dtor(slot);
|
|
+ zval tmp;
|
|
+ ZVAL_COPY_VALUE(&tmp, slot);
|
|
ZVAL_UNDEF(slot);
|
|
+ zval_ptr_dtor(&tmp);
|
|
if (zobj->properties) {
|
|
HT_FLAGS(zobj->properties) |= HASH_FLAG_HAS_EMPTY_IND;
|
|
}
|
|
--
|
|
1.8.3.1
|
|
|