]> granicus.if.org Git - php/commitdiff
Fix bug #69579
authorJohn Boehr <jbboehr@gmail.com>
Thu, 22 Sep 2016 03:09:45 +0000 (20:09 -0700)
committerNikita Popov <nikic@php.net>
Thu, 22 Sep 2016 10:38:07 +0000 (12:38 +0200)
NEWS
Zend/tests/traits/bug69579.phpt [new file with mode: 0644]
Zend/tests/traits/get_declared_traits_001.phpt
Zend/tests/traits/get_declared_traits_002.phpt
Zend/tests/traits/get_declared_traits_003.phpt
Zend/zend_builtin_functions.c
Zend/zend_inheritance.c

diff --git a/NEWS b/NEWS
index bdb50089c850985c4aa3afbed0ddf289d84afb73..b16eb2d2274f2bf37b057d97988665339eb405d6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ PHP                                                                        NEWS
   . Fixed bug #72703 (Out of bounds global memory read in BF_crypt triggered by
     password_verify). (Anatol)
   . Fixed bug #73058 (crypt broken when salt is 'too' long). (Anatol)
+  . Fixed bug #69579 (Invalid free in extension trait). (John Boehr)
 
 - COM:
   . Fixed bug #73126 (Cannot pass parameter 1 by reference). (Anatol)
diff --git a/Zend/tests/traits/bug69579.phpt b/Zend/tests/traits/bug69579.phpt
new file mode 100644 (file)
index 0000000..421734e
--- /dev/null
@@ -0,0 +1,20 @@
+--TEST--
+Bug #69579 (Internal trait double-free)
+--SKIPIF--
+<?php
+if (!PHP_DEBUG) die("skip only run in debug version");
+?>
+--FILE--
+<?php
+
+class Bar{
+  use _ZendTestTrait;
+}
+
+$bar = new Bar();
+var_dump($bar->testMethod());
+// destruction causes a double-free and explodes
+
+?>
+--EXPECT--
+bool(true)
index 91f6b3d20ae6e1b042224ec7df1e57b5ebd20bc6..b1faec3de8a8e0cabd53ad0f2176bc2f4a172194 100644 (file)
@@ -12,8 +12,8 @@ final class e { }
 var_dump(get_declared_traits());
 
 ?>
---EXPECT--
-array(1) {
-  [0]=>
+--EXPECTF--
+array(%d) {%A
+  [%d]=>
   string(1) "c"
 }
index 74fdcc40824426c624e9e5e9836f72e65cfa6f48..73dd73c9273348b697c00c01b0f48b7d31fc3932 100644 (file)
@@ -13,8 +13,8 @@ namespace test {
 }
 
 ?>
---EXPECT--
-array(1) {
-  [0]=>
+--EXPECTF--
+array(%d) {%A
+  [%d]=>
   string(6) "test\c"
 }
index 4a687467f265dbe194d457bce39b876c898fad37..edae3f193358b35141f2fe75b5a0e2ba24087f91 100644 (file)
@@ -13,13 +13,15 @@ var_dump(get_declared_traits());
 
 ?>
 --EXPECTF--
-%astring(1) "a"
+array(%d) {%A
+  [%d]=>
+  string(1) "a"
   [%d]=>
   string(1) "d"
   [%d]=>
   string(1) "e"
 }
-array(1) {
-  [0]=>
+array(%d) {%A
+  [%d]=>
   string(1) "c"
 }
index 4f2a62d822819df2a846a1fe1d6694eae3614189..c3160d0a6fec0029cfa3e401e5b92a8bc985cc8b 100644 (file)
 
 #undef ZEND_TEST_EXCEPTIONS
 
+#if ZEND_DEBUG
+static zend_class_entry *zend_test_trait;
+#endif
+
 static ZEND_FUNCTION(zend_version);
 static ZEND_FUNCTION(func_num_args);
 static ZEND_FUNCTION(func_get_arg);
@@ -257,6 +261,18 @@ ZEND_END_ARG_INFO()
 
 /* }}} */
 
+#if ZEND_DEBUG
+static ZEND_METHOD(_ZendTestTrait, testMethod) /* {{{ */ {
+       RETURN_TRUE;
+}
+/* }}} */
+
+static zend_function_entry zend_test_trait_methods[] = {
+    ZEND_ME(_ZendTestTrait, testMethod, arginfo_zend__void, ZEND_ACC_PUBLIC)
+    ZEND_FE_END
+};
+#endif
+
 static const zend_function_entry builtin_functions[] = { /* {{{ */
        ZEND_FE(zend_version,           arginfo_zend__void)
        ZEND_FE(func_num_args,          arginfo_zend__void)
@@ -339,6 +355,13 @@ ZEND_MINIT_FUNCTION(core) { /* {{{ */
 
        zend_register_default_classes();
 
+#if ZEND_DEBUG
+       INIT_CLASS_ENTRY(class_entry, "_ZendTestTrait", zend_test_trait_methods);
+       zend_test_trait = zend_register_internal_class(&class_entry);
+       zend_test_trait->ce_flags |= ZEND_ACC_TRAIT;
+       zend_declare_property_null(zend_test_trait, "testProp", sizeof("testProp")-1, ZEND_ACC_PUBLIC);
+#endif
+
        return SUCCESS;
 }
 /* }}} */
index 85aadcb29e4092a6a77e540a2ea48f8738687f5c..00c514259b98fa17ed8466dd89694f5148f20df6 100644 (file)
@@ -1180,6 +1180,7 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
        function_add_ref(fn);
        new_fn = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
        memcpy(new_fn, fn, sizeof(zend_op_array));
+       new_fn->common.fn_flags |= ZEND_ACC_ARENA_ALLOCATED;
        fn = zend_hash_update_ptr(&ce->function_table, key, new_fn);
        zend_add_magic_methods(ce, key, fn);
 }