diff options
-rw-r--r-- | Zend/zend_constants.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 9902992cf2..6235615579 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -217,22 +217,48 @@ ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC if((colon = memchr(name, ':', name_len)) && colon[1] == ':') { /* class constant */ - zend_class_entry **ce; + zend_class_entry **ce = NULL, *scope; int class_name_len = colon-name; int const_name_len = name_len - class_name_len - 2; char *constant_name = colon+2; zval **ret_constant; - + + if(EG(in_execution)) { + scope = EG(scope); + } else { + scope = CG(active_class_entry); + } + lookup_name = do_alloca(class_name_len+1); zend_str_tolower_copy(lookup_name, name, class_name_len); lookup_name[class_name_len] = '\0'; - if(zend_lookup_class(lookup_name, class_name_len, &ce TSRMLS_CC) != SUCCESS) { - retval = 0; + if(class_name_len == sizeof("self")-1 && strcmp(lookup_name, "self") == 0) { + if(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(lookup_name, "parent") == 0) { + 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 { + ce = &scope->parent; + } } else { - if (zend_hash_find(&((*ce)->constants_table), constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) { + if(zend_lookup_class(lookup_name, class_name_len, &ce TSRMLS_CC) != SUCCESS) { retval = 0; } + } + if(retval && ce) { + if (zend_hash_find(&((*ce)->constants_table), constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) { + retval = 0; + } + } else { + retval = 0; } if(retval) { |