- Core:
. Fixed bug #78340 (Include of stream wrapper not reading whole file).
(Nikita)
+ . Fixed bug #78344 (Segmentation fault on zend_check_protected). (Nikita)
- Iconv:
. Fixed bug #78342 (Bus error in configure test for iconv //IGNORE). (Rainer
--- /dev/null
+--TEST--
+Bug #78344: Segmentation fault on zend_check_protected
+--FILE--
+<?php
+
+class A {
+ protected const FOO = 1;
+}
+
+class B {}
+class C extends B {
+ public function method() {
+ var_dump(A::FOO);
+ }
+}
+(new C)->method();
+
+?>
+--EXPECTF--
+Fatal error: Uncaught Error: Cannot access protected const A::FOO in %s:%d
+Stack trace:
+#0 %s(%d): C->method()
+#1 {main}
+ thrown in %s on line %d
}
/* }}} */
+/* We don't use zend_verify_const_access because we need to deal with unlinked classes. */
+static zend_bool zend_verify_ct_const_access(zend_class_constant *c, zend_class_entry *scope)
+{
+ if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PUBLIC) {
+ return 1;
+ } else if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PRIVATE) {
+ return c->ce == scope;
+ } else {
+ zend_class_entry *ce = c->ce;
+ while (1) {
+ if (ce == scope) {
+ return 1;
+ }
+ if (!ce->parent) {
+ break;
+ }
+ if (ce->ce_flags & ZEND_ACC_RESOLVED_PARENT) {
+ ce = ce->parent;
+ } else {
+ ce = zend_hash_find_ptr_lc(CG(class_table), ZSTR_VAL(ce->parent_name), ZSTR_LEN(ce->parent_name));
+ if (!ce) {
+ break;
+ }
+ }
+ }
+ /* Reverse case cannot be true during compilation */
+ return 0;
+ }
+}
+
static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend_string *name) /* {{{ */
{
uint32_t fetch_type = zend_get_class_fetch_type(class_name);
return 0;
}
- if (!cc || !zend_verify_const_access(cc, CG(active_class_entry))) {
+ if (!cc || !zend_verify_ct_const_access(cc, CG(active_class_entry))) {
return 0;
}