summaryrefslogtreecommitdiff
path: root/Zend/zend_builtin_functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_builtin_functions.c')
-rw-r--r--Zend/zend_builtin_functions.c65
1 files changed, 51 insertions, 14 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 82281c60a9..69921a1d60 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -516,8 +516,8 @@ ZEND_FUNCTION(defined)
ZEND_FUNCTION(get_class)
{
zval **arg;
- char *name;
- zend_uint name_len;
+ char *name = "";
+ zend_uint name_len = 0;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &arg)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
@@ -535,11 +535,15 @@ ZEND_FUNCTION(get_class)
RETURN_FALSE;
}
- name = ce->name;
- name_len = ce->name_length;
- }
+ if(ce->ns) {
+ zend_make_full_classname(ce, &name, &name_len);
+ RETURN_STRINGL(name, name_len, 0);
+ } else {
+ RETURN_STRINGL(ce->name, ce->name_length, 1);
+ }
+ }
- RETURN_STRINGL(name, name_len, 1);
+ RETURN_STRINGL(name, name_len, 0);
}
/* }}} */
@@ -550,20 +554,21 @@ ZEND_FUNCTION(get_parent_class)
{
zval **arg;
zend_class_entry *ce = NULL;
+ char *name;
+ zend_uint name_length;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &arg)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
if (Z_TYPE_PP(arg) == IS_OBJECT) {
- char *name;
- zend_uint name_length;
if (Z_OBJ_HT_PP(arg)->get_class_name
&& Z_OBJ_HT_PP(arg)->get_class_name(*arg, &name, &name_length, 1 TSRMLS_CC) == SUCCESS) {
- RETURN_STRINGL(name, name_length, 1);
+ RETURN_STRINGL(name, name_length, 0);
} else if (Z_OBJ_HT_PP(arg)->get_class_entry && (ce = zend_get_class_entry(*arg TSRMLS_CC))) {
- RETURN_STRINGL(ce->name, ce->name_length, 1);
+ zend_make_full_classname(ce, &name, &name_length);
+ RETURN_STRINGL(name, name_length, 0);
} else {
RETURN_FALSE;
}
@@ -578,7 +583,8 @@ ZEND_FUNCTION(get_parent_class)
}
if (ce && ce->parent) {
- RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
+ zend_make_full_classname(ce->parent, &name, &name_length);
+ RETURN_STRINGL(name, name_length, 0);
} else {
RETURN_FALSE;
}
@@ -846,7 +852,7 @@ ZEND_FUNCTION(function_exists)
{
zval **function_name;
zend_function *func;
- char *lcname;
+ char *lcname, *func_name, *func_name_end;
zend_bool retval;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &function_name)==FAILURE) {
@@ -856,14 +862,45 @@ ZEND_FUNCTION(function_exists)
lcname = estrndup((*function_name)->value.str.val, (*function_name)->value.str.len);
zend_str_tolower(lcname, (*function_name)->value.str.len);
- retval = (zend_hash_find(EG(function_table), lcname, (*function_name)->value.str.len+1, (void **)&func) == SUCCESS);
+ func_name_end = lcname + (*function_name)->value.str.len;
+ if((func_name = zend_memnstr(lcname, "::", sizeof("::")-1, func_name_end)) == NULL) {
+ retval = (zend_hash_find(EG(function_table), lcname, (*function_name)->value.str.len+1, (void **)&func) == SUCCESS);
+ } else {
+ /* handle ::f case */
+ if (func_name == lcname) {
+ retval = (zend_hash_find(EG(function_table), lcname+sizeof("::")-1, (*function_name)->value.str.len-(sizeof("::")-1)+1, (void **)&func) == SUCCESS);
+ } else {
+ /* handle ns::f case */
+ int ns_name_length = func_name - lcname;
+ char *ns_name;
+ zend_namespace **ns;
+
+ func_name += sizeof("::")-1;
+
+ if(func_name >= func_name_end) {
+ /* ns:: case */
+ retval = 0;
+ } else {
+ ns_name = estrndup(lcname, ns_name_length);
+
+ if (zend_hash_find(&EG(global_namespace_ptr)->class_table, ns_name, ns_name_length+1, (void **)&ns) == SUCCESS &&
+ CLASS_IS_NAMESPACE(*ns) &&
+ zend_hash_find(&(*ns)->function_table, func_name, func_name_end - func_name + 1, (void **)&func) == SUCCESS) {
+ retval = 1;
+ } else {
+ retval = 0;
+ }
+ efree(ns_name);
+ }
+ }
+ }
efree(lcname);
/*
* A bit of a hack, but not a bad one: we see if the handler of the function
* is actually one that displays "function is disabled" message.
*/
- if (retval &&
+ if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
func->internal_function.handler == zif_display_disabled_function) {
retval = 0;
}