summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Boehr <jbboehr@gmail.com>2016-09-21 20:09:45 -0700
committerNikita Popov <nikic@php.net>2016-09-22 12:38:07 +0200
commit68e602ff0a31f1c90ba3ad8717ae3a86d10854c7 (patch)
tree1e5cb50db1e7237cb431bd35b339748207bf7894
parentadaf68c3b1202d58f9ebef5a500db6e0afc6d463 (diff)
downloadphp-git-68e602ff0a31f1c90ba3ad8717ae3a86d10854c7.tar.gz
Fix bug #69579
-rw-r--r--NEWS1
-rw-r--r--Zend/tests/traits/bug69579.phpt20
-rw-r--r--Zend/tests/traits/get_declared_traits_001.phpt6
-rw-r--r--Zend/tests/traits/get_declared_traits_002.phpt6
-rw-r--r--Zend/tests/traits/get_declared_traits_003.phpt8
-rw-r--r--Zend/zend_builtin_functions.c23
-rw-r--r--Zend/zend_inheritance.c1
7 files changed, 56 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index bdb50089c8..b16eb2d227 100644
--- 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
index 0000000000..421734e74e
--- /dev/null
+++ b/Zend/tests/traits/bug69579.phpt
@@ -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)
diff --git a/Zend/tests/traits/get_declared_traits_001.phpt b/Zend/tests/traits/get_declared_traits_001.phpt
index 91f6b3d20a..b1faec3de8 100644
--- a/Zend/tests/traits/get_declared_traits_001.phpt
+++ b/Zend/tests/traits/get_declared_traits_001.phpt
@@ -12,8 +12,8 @@ final class e { }
var_dump(get_declared_traits());
?>
---EXPECT--
-array(1) {
- [0]=>
+--EXPECTF--
+array(%d) {%A
+ [%d]=>
string(1) "c"
}
diff --git a/Zend/tests/traits/get_declared_traits_002.phpt b/Zend/tests/traits/get_declared_traits_002.phpt
index 74fdcc4082..73dd73c927 100644
--- a/Zend/tests/traits/get_declared_traits_002.phpt
+++ b/Zend/tests/traits/get_declared_traits_002.phpt
@@ -13,8 +13,8 @@ namespace test {
}
?>
---EXPECT--
-array(1) {
- [0]=>
+--EXPECTF--
+array(%d) {%A
+ [%d]=>
string(6) "test\c"
}
diff --git a/Zend/tests/traits/get_declared_traits_003.phpt b/Zend/tests/traits/get_declared_traits_003.phpt
index 4a687467f2..edae3f1933 100644
--- a/Zend/tests/traits/get_declared_traits_003.phpt
+++ b/Zend/tests/traits/get_declared_traits_003.phpt
@@ -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"
}
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 4f2a62d822..c3160d0a6f 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -31,6 +31,10 @@
#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;
}
/* }}} */
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index 85aadcb29e..00c514259b 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -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);
}