]> granicus.if.org Git - php/commitdiff
Fixed bug #78409
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 15 Aug 2019 08:38:43 +0000 (10:38 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 15 Aug 2019 08:40:28 +0000 (10:40 +0200)
This removes an incorrect optimization (I think this code used to be
necessary to properly handle references in the Serializable based
implementation, but now this code just avoids an array duplication
in a way that is not sound).

NEWS
ext/spl/spl_array.c
ext/spl/tests/bug78409.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 64f8a51e2ac075ee8602b4197db7166a24fd7ab8..5a04cda6769f2442f38d04637d00dabc6445169c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,10 @@ PHP                                                                        NEWS
   . Fixed bug #78410 (Cannot "manually" unserialize class that is final and
     extends an internal one). (Nikita)
 
+- SPL:
+  . Fixed bug #78409 (Segfault when creating instance of ArrayIterator without
+    constructor). (Nikita)
+
 08 Aug 2019, PHP 7.4.0beta2
 
 - Core:
index 32f1fd8bbdb862564db13be364e5370df2dcc7c5..90861b49c68f07c40181050e09781d320a2b21d0 100644 (file)
@@ -1875,11 +1875,6 @@ SPL_METHOD(Array, __unserialize)
        if (flags & SPL_ARRAY_IS_SELF) {
                zval_ptr_dtor(&intern->array);
                ZVAL_UNDEF(&intern->array);
-       } else if (Z_TYPE_P(storage_zv) == IS_ARRAY) {
-               zval_ptr_dtor(&intern->array);
-               ZVAL_COPY_VALUE(&intern->array, storage_zv);
-               ZVAL_NULL(storage_zv);
-               SEPARATE_ARRAY(&intern->array);
        } else {
                spl_array_set_array(ZEND_THIS, intern, storage_zv, 0L, 1);
        }
diff --git a/ext/spl/tests/bug78409.phpt b/ext/spl/tests/bug78409.phpt
new file mode 100644 (file)
index 0000000..f59015f
--- /dev/null
@@ -0,0 +1,26 @@
+--TEST--
+Bug #78409: Segfault when creating instance of ArrayIterator without constructor
+--FILE--
+<?php
+
+$a = new ArrayObject;
+$u = [
+    0,
+    [],
+    [],
+];
+$a->__unserialize($u);
+var_dump($u);
+
+?>
+--EXPECT--
+array(3) {
+  [0]=>
+  int(0)
+  [1]=>
+  array(0) {
+  }
+  [2]=>
+  array(0) {
+  }
+}