summaryrefslogtreecommitdiff
path: root/Zend/zend_constants.c
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2016-05-02 19:58:56 +0200
committerNikita Popov <nikic@php.net>2016-05-02 19:59:43 +0200
commitec7c3c22b69814aa0b64c6b9aa9fef17f99103ab (patch)
tree4e6dd92f1565b91c9e8b7b5721e817d66191fafc /Zend/zend_constants.c
parent45c0301b693e1c26c663e8a73a804fb9eb1ba1cf (diff)
downloadphp-git-ec7c3c22b69814aa0b64c6b9aa9fef17f99103ab.tar.gz
Fix leak in zend_get_constant_ex
Diffstat (limited to 'Zend/zend_constants.c')
-rw-r--r--Zend/zend_constants.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c
index 7e93d93460..41edcd93d8 100644
--- a/Zend/zend_constants.c
+++ b/Zend/zend_constants.c
@@ -299,7 +299,6 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
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,13 +314,9 @@ 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);
@@ -330,48 +325,43 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
}
}
- 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(NULL, "Cannot access self:: when no class scope is active");
- return NULL;
+ 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(NULL, "Cannot access parent:: when no class scope is active");
- return NULL;
+ goto failure;
} else if (UNEXPECTED(!scope->parent)) {
zend_throw_error(NULL, "Cannot access parent:: when current class scope has no parent");
- return NULL;
+ 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(NULL, "Cannot access static:: when no class scope is active");
- return NULL;
+ 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) {
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);
}
}
+
+failure:
zend_string_release(class_name);
zend_string_free(constant_name);
if (ret_constant && Z_CONSTANT_P(ret_constant)) {