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.c189
1 files changed, 122 insertions, 67 deletions
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c
index fba024ac44..13f9ba9848 100644
--- a/Zend/zend_constants.c
+++ b/Zend/zend_constants.c
@@ -213,21 +213,82 @@ ZEND_API void zend_register_string_constant(char *name, uint name_len, char *str
}
-ZEND_API int zend_get_constant_ex(char *name, uint name_len, zval *result, zend_class_entry *scope TSRMLS_DC)
+ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC)
{
zend_constant *c;
int retval = 1;
char *lookup_name;
+
+ if (zend_hash_find(EG(zend_constants), name, name_len+1, (void **) &c) == FAILURE) {
+ lookup_name = zend_str_tolower_dup(name, name_len);
+
+ if (zend_hash_find(EG(zend_constants), lookup_name, name_len+1, (void **) &c)==SUCCESS) {
+ if ((c->flags & CONST_CS) && memcmp(c->name, name, name_len) != 0) {
+ retval=0;
+ }
+ } else {
+ static char haltoff[] = "__COMPILER_HALT_OFFSET__";
+
+ if (!EG(in_execution)) {
+ retval = 0;
+ } else if (name_len == sizeof("__COMPILER_HALT_OFFSET__")-1 &&
+ !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) {
+ char *cfilename, *haltname;
+ int len, clen;
+
+ cfilename = zend_get_executed_filename(TSRMLS_C);
+ clen = strlen(cfilename);
+ /* check for __COMPILER_HALT_OFFSET__ */
+ zend_mangle_property_name(&haltname, &len, haltoff,
+ sizeof("__COMPILER_HALT_OFFSET__") - 1, cfilename, clen, 0);
+ if (zend_hash_find(EG(zend_constants), haltname, len+1, (void **) &c) == SUCCESS) {
+ retval = 1;
+ } else {
+ retval=0;
+ }
+ pefree(haltname, 0);
+ } else {
+ retval=0;
+ }
+ }
+ efree(lookup_name);
+ }
+
+ if (retval) {
+ *result = c->value;
+ zval_copy_ctor(result);
+ result->refcount = 1;
+ result->is_ref = 0;
+ }
+
+ return retval;
+}
+
+ZEND_API int zend_get_constant_ex(char *name, uint name_len, zval *result, zend_class_entry *scope, ulong flags TSRMLS_DC)
+{
+ zend_constant *c;
+ int retval = 1;
char *colon;
- if ((colon = memchr(name, ':', name_len)) && colon[1] == ':') {
- /* class constant */
- zend_class_entry **ce = NULL;
- int class_name_len = colon-name;
+ /* Skip leading :: */
+ if (name[0] == ':' && name[1] == ':') {
+ name += 2;
+ name_len -= 2;
+ flags = 0;
+ }
+
+
+ if ((colon = zend_memrchr(name, ':', name_len)) &&
+ 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+2;
+ 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;
- char *class_name;
if (!scope) {
if (EG(in_execution)) {
@@ -236,42 +297,81 @@ ZEND_API int zend_get_constant_ex(char *name, uint name_len, zval *result, zend_
scope = CG(active_class_entry);
}
}
-
- class_name = estrndup(name, class_name_len);
- if (class_name_len == sizeof("self")-1 && strcmp(class_name, "self") == 0) {
+ if (class_name_len == sizeof("self")-1 &&
+ !memcmp(lcname, "self", sizeof("self")-1)) {
if (scope) {
- ce = &scope;
+ ce = scope;
} else {
zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
retval = 0;
}
- } else if (class_name_len == sizeof("parent")-1 && strcmp(class_name, "parent") == 0) {
- if (!scope) {
+ efree(lcname);
+ } else if (class_name_len == sizeof("parent")-1 &&
+ !memcmp(lcname, "parent", sizeof("parent")-1)) {
+ if (!scope) {
zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
- } else if (!scope->parent) {
- zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
+ } else if (!scope->parent) {
+ zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
} else {
- ce = &scope->parent;
+ ce = scope->parent;
}
+ efree(lcname);
} else {
- if (zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC) != SUCCESS) {
- retval = 0;
+ /* 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);
+ result->refcount = 1;
+ result->is_ref = 0;
+ return 1;
}
+ efree(lcname);
+
+ /* 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) {
+ if (zend_hash_find(&ce->constants_table, constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) {
retval = 0;
}
} else {
- zend_error(E_ERROR, "Class '%s' not found", class_name);
+ 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);
+ }
+ zend_error(E_ERROR, "Class '%s' not found", class_name);
+ }
retval = 0;
}
efree(class_name);
if (retval) {
- zval_update_constant_ex(ret_constant, (void*)1, *ce TSRMLS_CC);
+ zval_update_constant_ex(ret_constant, (void*)1, ce TSRMLS_CC);
*result = **ret_constant;
zval_copy_ctor(result);
}
@@ -279,52 +379,7 @@ ZEND_API int zend_get_constant_ex(char *name, uint name_len, zval *result, zend_
return retval;
}
- if (zend_hash_find(EG(zend_constants), name, name_len+1, (void **) &c) == FAILURE) {
- lookup_name = estrndup(name, name_len);
- zend_str_tolower(lookup_name, name_len);
-
- if (zend_hash_find(EG(zend_constants), lookup_name, name_len+1, (void **) &c)==SUCCESS) {
- if ((c->flags & CONST_CS) && memcmp(c->name, name, name_len)!=0) {
- retval=0;
- }
- } else {
- char haltoff[] = "__COMPILER_HALT_OFFSET__";
- if (!EG(in_execution)) {
- retval = 0;
- } else if (name_len == sizeof("__COMPILER_HALT_OFFSET__") - 1 && memcmp(haltoff, name, name_len) == 0) {
- char *cfilename, *haltname;
- int len, clen;
- cfilename = zend_get_executed_filename(TSRMLS_C);
- clen = strlen(cfilename);
- /* check for __COMPILER_HALT_OFFSET__ */
- zend_mangle_property_name(&haltname, &len, haltoff,
- sizeof("__COMPILER_HALT_OFFSET__") - 1, cfilename, clen, 0);
- if (zend_hash_find(EG(zend_constants), haltname, len+1, (void **) &c) == SUCCESS) {
- retval = 1;
- } else {
- retval=0;
- }
- pefree(haltname, 0);
- } else {
- retval = 0;
- }
- }
- efree(lookup_name);
- }
-
- if (retval) {
- *result = c->value;
- zval_copy_ctor(result);
- result->refcount = 1;
- result->is_ref = 0;
- }
-
- return retval;
-}
-
-ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC)
-{
- return zend_get_constant_ex(name, name_len, result, NULL TSRMLS_CC);
+ return zend_get_constant(name, name_len, result TSRMLS_CC);
}
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)