diff options
Diffstat (limited to 'Zend/zend_constants.c')
-rw-r--r-- | Zend/zend_constants.c | 113 |
1 files changed, 59 insertions, 54 deletions
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index cdf4dcac65..f215a885ba 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -277,26 +277,27 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result, zend_constant *c; int retval = 1; char *colon; - zend_class_entry *ce = NULL; - char *class_name; - zval **ret_constant; - - /* Skip leading \\ */ - if (name[0] == '\\') { - name += 1; - name_len -= 1; - } + /* Skip leading :: */ + if (name[0] == ':' && name[1] == ':') { + name += 2; + name_len -= 2; + flags &= ZEND_FETCH_CLASS_SILENT; + } + if ((colon = zend_memrchr(name, ':', name_len)) && - colon > name && (*(colon - 1) == ':')) { + colon > name && + *(colon-1) == ':') { + /* compound constant name */ + zend_class_entry *ce = NULL; int class_name_len = colon - name - 1; int const_name_len = name_len - class_name_len - 2; - char *constant_name = colon + 1; - char *lcname; + char *constant_name = constant_name = colon + 1; + char *class_name = estrndup(name, class_name_len); + char *lcname = zend_str_tolower_dup(class_name, class_name_len); + zval **ret_constant; - class_name = estrndup(name, class_name_len); - lcname = zend_str_tolower_dup(class_name, class_name_len); if (!scope) { if (EG(in_execution)) { scope = EG(scope); @@ -333,58 +334,62 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result, } efree(lcname); } else { + /* Check for namespace constant */ + char *nsname; + unsigned int nsname_len; + + /* Concatenate lowercase namespace name and constant name */ + lcname = erealloc(lcname, class_name_len + 2 + const_name_len + 1); + lcname[class_name_len] = ':'; + lcname[class_name_len+1] = ':'; + memcpy(lcname + class_name_len + 2, constant_name, const_name_len + 1); + + nsname = lcname; + nsname_len = class_name_len + 2 + const_name_len; + if (flags & ZEND_FETCH_CLASS_RT_NS_NAME) { + nsname = (char *)memchr(nsname, ':', nsname_len) + 2; + nsname_len -= (nsname - lcname); + } + + if (zend_hash_find(EG(zend_constants), nsname, nsname_len+1, (void **) &c) == SUCCESS) { + efree(lcname); + efree(class_name); + *result = c->value; + zval_update_constant_ex(&result, (void*)1, NULL TSRMLS_CC); + zval_copy_ctor(result); + Z_SET_REFCOUNT_P(result, 1); + Z_UNSET_ISREF_P(result); + return 1; + } efree(lcname); - ce = zend_fetch_class(class_name, class_name_len, flags TSRMLS_CC); + + if ((flags & IS_CONSTANT_RT_NS_CHECK) == 0) { + /* Check for class */ + ce = zend_fetch_class(class_name, class_name_len, flags TSRMLS_CC); + } } + if (retval && ce) { if (zend_hash_find(&ce->constants_table, constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) { retval = 0; + } + } else { + if ((flags & ZEND_FETCH_CLASS_RT_NS_NAME) == 0) { + if ((flags & IS_CONSTANT_RT_NS_CHECK) != 0) { + name = constant_name; + name_len = const_name_len; + efree(class_name); + retval = 1; + return zend_get_constant(name, name_len, result TSRMLS_CC); + } if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) { - zend_error(E_ERROR, "Undefined class constant '%s::%s'", class_name, constant_name); + zend_error(E_ERROR, "Class '%s' not found", class_name); } } - } else if (!ce) { retval = 0; } efree(class_name); - goto finish; - } - - /* non-class constant */ - if ((colon = zend_memrchr(name, '\\', name_len)) != NULL) { - /* compound constant name */ - int prefix_len = colon - name; - int const_name_len = name_len - prefix_len - 1; - char *constant_name = colon + 1; - char *lcname; - - lcname = zend_str_tolower_dup(name, prefix_len); - /* Check for namespace constant */ - /* Concatenate lowercase namespace name and constant name */ - lcname = erealloc(lcname, prefix_len + 1 + const_name_len + 1); - lcname[prefix_len] = '\\'; - memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1); - - if (zend_hash_find(EG(zend_constants), lcname, prefix_len + 1 + const_name_len + 1, (void **) &c) == SUCCESS) { - efree(lcname); - *result = c->value; - zval_update_constant_ex(&result, (void*)1, NULL TSRMLS_CC); - zval_copy_ctor(result); - Z_SET_REFCOUNT_P(result, 1); - Z_UNSET_ISREF_P(result); - return 1; - } - - efree(lcname); - /* name requires runtime resolution, need to check non-namespaced name */ - if ((flags & IS_CONSTANT_UNQUALIFIED) != 0) { - name = constant_name; - name_len = const_name_len; - return zend_get_constant(name, name_len, result TSRMLS_CC); - } - retval = 0; -finish: if (retval) { zval_update_constant_ex(ret_constant, (void*)1, ce TSRMLS_CC); *result = **ret_constant; |