Skip to content

Commit f039225

Browse files
committedMar 5, 2015
Fixed bug #69174 (leaks when unused inner class use traits precedence)
1 parent 837eeef commit f039225

File tree

5 files changed

+44
-6
lines changed

5 files changed

+44
-6
lines changed
 

‎NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ PHP NEWS
33
?? ??? 2015, PHP 5.5.23
44

55
- Core:
6+
. Fixed bug #69174 (leaks when unused inner class use traits precedence).
7+
(Laruence)
68
. Fixed bug #69139 (Crash in gc_zval_possible_root on unserialize).
79
(Laruence)
810
. Fixed bug #69121 (Segfault in get_current_user when script owner is not

‎Zend/tests/bug69174.phpt

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Bug #69174 (leaks when unused inner class use traits precedence)
3+
--FILE--
4+
<?php
5+
function test() {
6+
class C1 {
7+
use T1, T2 {
8+
T1::foo insteadof T2;
9+
T1::bar insteadof T2;
10+
}
11+
}
12+
}
13+
?>
14+
==DONE==
15+
--EXPECT--
16+
==DONE==

‎Zend/zend_compile.c

+16-1
Original file line numberDiff line numberDiff line change
@@ -4204,23 +4204,38 @@ static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{
42044204
for (i = 0; i < ce->num_traits; i++) {
42054205
if (ce->trait_precedences) {
42064206
HashTable exclude_table;
4207+
zend_trait_precedence **precedences;
42074208

42084209
/* TODO: revisit this start size, may be its not optimal */
42094210
zend_hash_init_ex(&exclude_table, 2, NULL, NULL, 0, 0);
42104211

4211-
zend_traits_compile_exclude_table(&exclude_table, ce->trait_precedences, ce->traits[i]);
4212+
precedences = ce->trait_precedences;
4213+
ce->trait_precedences = NULL;
4214+
zend_traits_compile_exclude_table(&exclude_table, precedences, ce->traits[i]);
42124215

42134216
/* copies functions, applies defined aliasing, and excludes unused trait methods */
42144217
zend_hash_apply_with_arguments(&ce->traits[i]->function_table TSRMLS_CC, (apply_func_args_t)zend_traits_copy_functions, 3, ce, &overriden, &exclude_table);
42154218

42164219
zend_hash_destroy(&exclude_table);
4220+
ce->trait_precedences = precedences;
42174221
} else {
42184222
zend_hash_apply_with_arguments(&ce->traits[i]->function_table TSRMLS_CC, (apply_func_args_t)zend_traits_copy_functions, 3, ce, &overriden, NULL);
42194223
}
42204224
}
42214225

42224226
zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t)zend_fixup_trait_method, ce TSRMLS_CC);
42234227

4228+
if (ce->trait_precedences) {
4229+
i = 0;
4230+
while (ce->trait_precedences[i]) {
4231+
if (ce->trait_precedences[i]->exclude_from_classes) {
4232+
efree(ce->trait_precedences[i]->exclude_from_classes);
4233+
ce->trait_precedences[i]->exclude_from_classes = NULL;
4234+
}
4235+
i++;
4236+
}
4237+
}
4238+
42244239
if (overriden) {
42254240
zend_hash_destroy(overriden);
42264241
FREE_HASHTABLE(overriden);

‎Zend/zend_opcode.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,14 @@ void _destroy_zend_class_traits_info(zend_class_entry *ce)
256256
efree(ce->trait_precedences[i]->trait_method);
257257

258258
if (ce->trait_precedences[i]->exclude_from_classes) {
259+
zend_uint j = 0;
260+
zend_trait_precedence *cur_precedence = ce->trait_precedences[i];
261+
while (cur_precedence->exclude_from_classes[j]) {
262+
efree(cur_precedence->exclude_from_classes[j]);
263+
j++;
264+
}
259265
efree(ce->trait_precedences[i]->exclude_from_classes);
260266
}
261-
262267
efree(ce->trait_precedences[i]);
263268
i++;
264269
}

‎Zend/zend_signal.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context)
7878

7979
if (SIGG(active)) {
8080
if (SIGG(depth) == 0) { /* try to handle signal */
81-
if (SIGG(blocked) != -1) { /* inverse */
82-
SIGG(blocked) = -1; /* signal is not blocked */
81+
if (SIGG(blocked) != 0) { /* inverse */
82+
SIGG(blocked) = 0; /* signal is not blocked */
8383
}
8484
if (SIGG(running) == 0) {
8585
SIGG(running) = 1;
@@ -99,7 +99,7 @@ void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context)
9999
SIGG(running) = 0;
100100
}
101101
} else { /* delay signal handling */
102-
SIGG(blocked) = 0; /* signal is blocked */
102+
SIGG(blocked) = 1; /* signal is blocked */
103103

104104
if ((queue = SIGG(pavail))) { /* if none available it's simply forgotton */
105105
SIGG(pavail) = queue->next;
@@ -314,7 +314,7 @@ void zend_signal_deactivate(TSRMLS_D)
314314
SIGNAL_BEGIN_CRITICAL();
315315
SIGG(active) = 0;
316316
SIGG(running) = 0;
317-
SIGG(blocked) = -1;
317+
SIGG(blocked) = 0;
318318
SIGG(depth) = 0;
319319
SIGNAL_END_CRITICAL();
320320
}

0 commit comments

Comments
 (0)