]> granicus.if.org Git - php/commitdiff
fix unintentional bc break with compact('this') behavior
authorMárcio Almada <marcio3w@gmail.com>
Thu, 1 Sep 2016 07:50:58 +0000 (03:50 -0400)
committerNikita Popov <nikic@php.net>
Thu, 1 Sep 2016 11:01:38 +0000 (13:01 +0200)
ext/standard/array.c
ext/standard/tests/array/compact_no_this.phpt [new file with mode: 0644]
ext/standard/tests/array/compact_this.phpt [new file with mode: 0644]

index f471f2a7a49740f7bf7dd1a7f6bdeef16edd913b..0988a86f28f735b7c093e4384aa8bce43fa1fdab 100644 (file)
@@ -1976,6 +1976,14 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu
                        ZVAL_COPY(&data, value_ptr);
                        zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data);
                }
+               if (zend_string_equals_literal(Z_STR_P(entry), "this")) {
+                       zend_object *object = zend_get_this_object(EG(current_execute_data));
+                       if (object) {
+                               GC_REFCOUNT(object)++;
+                               ZVAL_OBJ(&data, object);
+                               zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data);
+                       }
+               }
        } else if (Z_TYPE_P(entry) == IS_ARRAY) {
                if ((Z_ARRVAL_P(entry)->u.v.nApplyCount > 1)) {
                        php_error_docref(NULL, E_WARNING, "recursion detected");
diff --git a/ext/standard/tests/array/compact_no_this.phpt b/ext/standard/tests/array/compact_no_this.phpt
new file mode 100644 (file)
index 0000000..df294f0
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+compact() without object context
+--FILE--
+<?php
+
+var_dump(
+    (new class {
+        function test(){
+            return (static function(){ return compact('this'); })();
+        }
+    })->test()
+);
+
+var_dump(compact('this'));
+
+var_dump((function(){ return compact('this'); })());
+
+?>
+--EXPECT--
+array(0) {
+}
+array(0) {
+}
+array(0) {
+}
diff --git a/ext/standard/tests/array/compact_this.phpt b/ext/standard/tests/array/compact_this.phpt
new file mode 100644 (file)
index 0000000..f3677e0
--- /dev/null
@@ -0,0 +1,46 @@
+--TEST--
+compact() with object context
+--FILE--
+<?php
+
+var_dump(
+    (new class {
+        function test(){
+            return compact('this');
+        }
+    })->test()
+);
+
+var_dump(
+    (new class {
+        function test(){
+            return compact([['this']]);
+        }
+    })->test()
+);
+
+var_dump(
+    (new class {
+        function test(){
+            return (function(){ return compact('this'); })();
+        }
+    })->test()
+);
+
+?>
+--EXPECT--
+array(1) {
+  ["this"]=>
+  object(class@anonymous)#1 (0) {
+  }
+}
+array(1) {
+  ["this"]=>
+  object(class@anonymous)#1 (0) {
+  }
+}
+array(1) {
+  ["this"]=>
+  object(class@anonymous)#1 (0) {
+  }
+}