diff options
Diffstat (limited to 'Zend/zend_constants.c')
-rw-r--r-- | Zend/zend_constants.c | 27 |
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); |