diff options
author | Andrei Zmievski <andrei@php.net> | 2001-05-09 20:07:49 +0000 |
---|---|---|
committer | Andrei Zmievski <andrei@php.net> | 2001-05-09 20:07:49 +0000 |
commit | 41aebd058ea22f705319ddd0ce2daba1c47b5bf8 (patch) | |
tree | ca4a819f9b43a434b9c5f0179059415c1b5c744a | |
parent | 8112d1beba1b60e47f61607fe5d44646b31cf10c (diff) | |
download | php-git-41aebd058ea22f705319ddd0ce2daba1c47b5bf8.tar.gz |
Fix a few bugs in zend_is_callable() and make it stricter.
-rw-r--r-- | Zend/zend_API.c | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 333fe86383..45e869c4cc 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -918,6 +918,9 @@ zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callabl switch (Z_TYPE_P(callable)) { case IS_STRING: + if (callable_name) + *callable_name = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable)); + if (syntax_only) return 1; @@ -926,65 +929,69 @@ zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callabl if (zend_hash_exists(EG(function_table), lcname, Z_STRLEN_P(callable)+1)) retval = 1; efree(lcname); - if (!retval && callable_name) - *callable_name = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable)); break; case IS_ARRAY: { zval **method; zval **obj; - zend_class_entry *ce; + zend_class_entry *ce = NULL; char callable_name_len; - if (zend_hash_index_find(Z_ARRVAL_P(callable), 0, (void **) &obj) == SUCCESS && + if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2 && + zend_hash_index_find(Z_ARRVAL_P(callable), 0, (void **) &obj) == SUCCESS && zend_hash_index_find(Z_ARRVAL_P(callable), 1, (void **) &method) == SUCCESS && (Z_TYPE_PP(obj) == IS_OBJECT || Z_TYPE_PP(obj) == IS_STRING) && Z_TYPE_PP(method) == IS_STRING) { - if (syntax_only) - return 1; - if (Z_TYPE_PP(obj) == IS_STRING) { int found; + if (callable_name) { + char *ptr; + + callable_name_len = Z_STRLEN_PP(obj) + Z_STRLEN_PP(method) + sizeof("::"); + ptr = *callable_name = emalloc(callable_name_len); + memcpy(ptr, Z_STRVAL_PP(obj), Z_STRLEN_PP(obj)); + ptr += Z_STRLEN_PP(obj); + memcpy(ptr, "::", sizeof("::") - 1); + ptr += sizeof("::") - 1; + memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1); + } + + if (syntax_only) + return 1; + lcname = estrndup(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj)); zend_str_tolower(lcname, Z_STRLEN_PP(obj)); - found = zend_hash_find(EG(class_table), lcname, Z_STRLEN_PP(obj) + 1, (void**)&ce); + zend_hash_find(EG(class_table), lcname, Z_STRLEN_PP(obj) + 1, (void**)&ce); efree(lcname); - if (found == FAILURE) { - if (callable_name) { - char *ptr; - - callable_name_len = Z_STRLEN_PP(obj) + Z_STRLEN_PP(method) + sizeof("::"); - ptr = *callable_name = emalloc(callable_name_len); - memcpy(ptr, Z_STRVAL_PP(obj), Z_STRLEN_PP(obj)); - ptr += Z_STRLEN_PP(obj); - memcpy(ptr, "::", sizeof("::") - 1); - ptr += sizeof("::") - 1; - memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1); - } - break; - } } else { ce = Z_OBJCE_PP(obj); + + if (callable_name) { + char *ptr; + + callable_name_len = ce->name_length + Z_STRLEN_PP(method) + sizeof("::"); + ptr = *callable_name = emalloc(callable_name_len); + memcpy(ptr, ce->name, ce->name_length); + ptr += ce->name_length; + memcpy(ptr, "::", sizeof("::") - 1); + ptr += sizeof("::") - 1; + memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1); + } + + if (syntax_only) + return 1; } - lcname = estrndup(Z_STRVAL_PP(method), Z_STRLEN_PP(method)); - zend_str_tolower(lcname, Z_STRLEN_PP(method)); - if (zend_hash_exists(&ce->function_table, lcname, Z_STRLEN_PP(method)+1)) - retval = 1; - if (!retval && callable_name) { - char *ptr; - - callable_name_len = ce->name_length + Z_STRLEN_PP(method) + sizeof("::"); - ptr = *callable_name = emalloc(callable_name_len); - memcpy(ptr, ce->name, ce->name_length); - ptr += ce->name_length; - memcpy(ptr, "::", sizeof("::") - 1); - ptr += sizeof("::") - 1; - memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1); + + if (ce) { + lcname = estrndup(Z_STRVAL_PP(method), Z_STRLEN_PP(method)); + zend_str_tolower(lcname, Z_STRLEN_PP(method)); + if (zend_hash_exists(&ce->function_table, lcname, Z_STRLEN_PP(method)+1)) + retval = 1; + efree(lcname); } - efree(lcname); } else if (callable_name) *callable_name = estrndup("Array", sizeof("Array")-1); } |