Skip to content

Commit 4ae807e

Browse files
committed
Fixed bug #78344
When performing a constant visibility check during compilation we might be dealing with unlinked classes and as such should account for the possibility of unresolved parents.
1 parent 9bfda01 commit 4ae807e

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ PHP NEWS
55
- Core:
66
. Fixed bug #78340 (Include of stream wrapper not reading whole file).
77
(Nikita)
8+
. Fixed bug #78344 (Segmentation fault on zend_check_protected). (Nikita)
89

910
- Iconv:
1011
. Fixed bug #78342 (Bus error in configure test for iconv //IGNORE). (Rainer

Zend/tests/bug78344.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Bug #78344: Segmentation fault on zend_check_protected
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
protected const FOO = 1;
8+
}
9+
10+
class B {}
11+
class C extends B {
12+
public function method() {
13+
var_dump(A::FOO);
14+
}
15+
}
16+
(new C)->method();
17+
18+
?>
19+
--EXPECTF--
20+
Fatal error: Uncaught Error: Cannot access protected const A::FOO in %s:%d
21+
Stack trace:
22+
#0 %s(%d): C->method()
23+
#1 {main}
24+
thrown in %s on line %d

Zend/zend_compile.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,36 @@ static zend_bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_a
14101410
}
14111411
/* }}} */
14121412

1413+
/* We don't use zend_verify_const_access because we need to deal with unlinked classes. */
1414+
static zend_bool zend_verify_ct_const_access(zend_class_constant *c, zend_class_entry *scope)
1415+
{
1416+
if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PUBLIC) {
1417+
return 1;
1418+
} else if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PRIVATE) {
1419+
return c->ce == scope;
1420+
} else {
1421+
zend_class_entry *ce = c->ce;
1422+
while (1) {
1423+
if (ce == scope) {
1424+
return 1;
1425+
}
1426+
if (!ce->parent) {
1427+
break;
1428+
}
1429+
if (ce->ce_flags & ZEND_ACC_RESOLVED_PARENT) {
1430+
ce = ce->parent;
1431+
} else {
1432+
ce = zend_hash_find_ptr_lc(CG(class_table), ZSTR_VAL(ce->parent_name), ZSTR_LEN(ce->parent_name));
1433+
if (!ce) {
1434+
break;
1435+
}
1436+
}
1437+
}
1438+
/* Reverse case cannot be true during compilation */
1439+
return 0;
1440+
}
1441+
}
1442+
14131443
static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend_string *name) /* {{{ */
14141444
{
14151445
uint32_t fetch_type = zend_get_class_fetch_type(class_name);
@@ -1433,7 +1463,7 @@ static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name,
14331463
return 0;
14341464
}
14351465

1436-
if (!cc || !zend_verify_const_access(cc, CG(active_class_entry))) {
1466+
if (!cc || !zend_verify_ct_const_access(cc, CG(active_class_entry))) {
14371467
return 0;
14381468
}
14391469

0 commit comments

Comments
 (0)