summaryrefslogtreecommitdiff
path: root/Zend/zend_constants.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_constants.c')
-rw-r--r--Zend/zend_constants.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c
index 159379d71c..d539445be7 100644
--- a/Zend/zend_constants.c
+++ b/Zend/zend_constants.c
@@ -251,6 +251,18 @@ static zend_constant *zend_get_special_constant(const char *name, size_t name_le
}
}
+ZEND_API int zend_verify_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_ASSERT(Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PROTECTED);
+ return zend_check_protected(c->ce, scope);
+ }
+}
+/* }}} */
ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len)
{
@@ -360,16 +372,23 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
}
free_alloca(lcname, use_heap);
if (ce) {
- ret_constant = zend_hash_find(&ce->constants_table, constant_name);
- if (ret_constant == NULL) {
+ zend_class_constant *c = zend_hash_find_ptr(&ce->constants_table, constant_name);
+ if (c == NULL) {
if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
zend_throw_error(NULL, "Undefined class constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
zend_string_release(class_name);
zend_string_free(constant_name);
return NULL;
}
- } else if (Z_ISREF_P(ret_constant)) {
- ret_constant = Z_REFVAL_P(ret_constant);
+ ret_constant = NULL;
+ } else {
+ if (!zend_verify_const_access(c, scope)) {
+ zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
+ zend_string_release(class_name);
+ zend_string_free(constant_name);
+ return NULL;
+ }
+ ret_constant = &c->value;
}
}
zend_string_release(class_name);