diff options
Diffstat (limited to 'Zend/zend_constants.c')
-rw-r--r-- | Zend/zend_constants.c | 99 |
1 files changed, 54 insertions, 45 deletions
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 168c23a850..3e09f0cbb8 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) 1998-2015 Zend Technologies Ltd. (http://www.zend.com) | + | Copyright (c) 1998-2016 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | @@ -33,7 +33,7 @@ void free_zend_constant(zval *zv) zend_constant *c = Z_PTR_P(zv); if (!(c->flags & CONST_PERSISTENT)) { - zval_dtor(&c->value); + zval_ptr_dtor(&c->value); } else { zval_internal_dtor(&c->value); } @@ -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) { @@ -294,12 +306,11 @@ ZEND_API zval *zend_get_constant(zend_string *name) return c ? &c->value : NULL; } -ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, zend_ulong flags) +ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags) { zend_constant *c; const char *colon; zend_class_entry *ce = NULL; - zend_string *class_name; const char *name = ZSTR_VAL(cname); size_t name_len = ZSTR_LEN(cname); @@ -315,70 +326,68 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, int class_name_len = colon - name - 1; size_t const_name_len = name_len - class_name_len - 2; zend_string *constant_name = zend_string_init(colon + 1, const_name_len, 0); - char *lcname; + zend_string *class_name = zend_string_init(name, class_name_len, 0); zval *ret_constant = NULL; - ALLOCA_FLAG(use_heap) - - class_name = zend_string_init(name, class_name_len, 0); - lcname = do_alloca(class_name_len + 1, use_heap); - zend_str_tolower_copy(lcname, name, class_name_len); - if (!scope) { - if (EG(current_execute_data)) { - scope = EG(scope); - } else { - scope = CG(active_class_entry); - } - } - if (class_name_len == sizeof("self")-1 && - !memcmp(lcname, "self", sizeof("self")-1)) { + if (zend_string_equals_literal_ci(class_name, "self")) { if (UNEXPECTED(!scope)) { - zend_throw_error(zend_ce_error, "Cannot access self:: when no class scope is active"); - return NULL; + zend_throw_error(NULL, "Cannot access self:: when no class scope is active"); + goto failure; } ce = scope; - } else if (class_name_len == sizeof("parent")-1 && - !memcmp(lcname, "parent", sizeof("parent")-1)) { + } else if (zend_string_equals_literal_ci(class_name, "parent")) { if (UNEXPECTED(!scope)) { - zend_throw_error(zend_ce_error, "Cannot access parent:: when no class scope is active"); - return NULL; + zend_throw_error(NULL, "Cannot access parent:: when no class scope is active"); + goto failure; } else if (UNEXPECTED(!scope->parent)) { - zend_throw_error(zend_ce_error, "Cannot access parent:: when current class scope has no parent"); - return NULL; + zend_throw_error(NULL, "Cannot access parent:: when current class scope has no parent"); + goto failure; } else { ce = scope->parent; } - } else if (class_name_len == sizeof("static")-1 && - !memcmp(lcname, "static", sizeof("static")-1)) { + } else if (zend_string_equals_literal_ci(class_name, "static")) { ce = zend_get_called_scope(EG(current_execute_data)); if (UNEXPECTED(!ce)) { - zend_throw_error(zend_ce_error, "Cannot access static:: when no class scope is active"); - return NULL; + zend_throw_error(NULL, "Cannot access static:: when no class scope is active"); + goto failure; } } else { ce = zend_fetch_class(class_name, flags); } - 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(zend_ce_error, "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; + zend_throw_error(NULL, "Undefined class constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); + goto failure; + } + 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)); + goto failure; } - } else if (Z_ISREF_P(ret_constant)) { - ret_constant = Z_REFVAL_P(ret_constant); + ret_constant = &c->value; } } - zend_string_release(class_name); - zend_string_free(constant_name); + if (ret_constant && Z_CONSTANT_P(ret_constant)) { - if (UNEXPECTED(zval_update_constant_ex(ret_constant, 1, ce) != SUCCESS)) { - return NULL; + if (Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) { + if (IS_CONSTANT_VISITED(ret_constant)) { + zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); + goto failure; + } + MARK_CONSTANT_VISITED(ret_constant); + } + if (UNEXPECTED(zval_update_constant_ex(ret_constant, ce) != SUCCESS)) { + RESET_CONSTANT_VISITED(ret_constant); + goto failure; } + RESET_CONSTANT_VISITED(ret_constant); } +failure: + zend_string_release(class_name); + zend_string_free(constant_name); return ret_constant; } @@ -427,7 +436,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, } } -zend_constant *zend_quick_get_constant(const zval *key, zend_ulong flags) +zend_constant *zend_quick_get_constant(const zval *key, uint32_t flags) { zend_constant *c; |