From 4ae807e84e102db9e0e97411cac90909f75f63f4 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 29 Jul 2019 11:12:00 +0200 Subject: [PATCH] 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. --- NEWS | 1 + Zend/tests/bug78344.phpt | 24 ++++++++++++++++++++++++ Zend/zend_compile.c | 32 +++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/bug78344.phpt diff --git a/NEWS b/NEWS index d04416d347..952071d36f 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ PHP NEWS - 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 diff --git a/Zend/tests/bug78344.phpt b/Zend/tests/bug78344.phpt new file mode 100644 index 0000000000..c1ff5e0b40 --- /dev/null +++ b/Zend/tests/bug78344.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #78344: Segmentation fault on zend_check_protected +--FILE-- +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 diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 40b29058bc..10a6b294f7 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1410,6 +1410,36 @@ static zend_bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_a } /* }}} */ +/* 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); @@ -1433,7 +1463,7 @@ static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *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; } -- 2.40.0