diff options
author | Marcus Boerger <helly@php.net> | 2005-11-02 20:30:13 +0000 |
---|---|---|
committer | Marcus Boerger <helly@php.net> | 2005-11-02 20:30:13 +0000 |
commit | a4bd0d6a2566d5dcc460ddc0a7d4c22df4a95064 (patch) | |
tree | 548725e12037b9d08648e87d522528ff1a67fadc /Zend/zend_API.c | |
parent | 703fc059bf49c0183c3c4a5bc6ab31c9e4f8a93e (diff) | |
download | php-git-a4bd0d6a2566d5dcc460ddc0a7d4c22df4a95064.tar.gz |
- Add missing cases and checks
Diffstat (limited to 'Zend/zend_API.c')
-rw-r--r-- | Zend/zend_API.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 9cf1d5537e..720eca988f 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1951,12 +1951,13 @@ ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_ ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char **callable_name, int *callable_name_len, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval ***zobj_ptr_ptr TSRMLS_DC) { - char *lcname; + char *lcname, *lmname, *colon; zend_bool retval = 0; - int callable_name_len_local; - zend_class_entry *ce_local; + int callable_name_len_local, clen, mlen; + zend_class_entry *ce_local, **pce; zend_function *fptr_local; zval **zobj_ptr_local; + HashTable *ftable; if (callable_name_len == NULL) { callable_name_len = &callable_name_len_local; @@ -1983,17 +1984,41 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char ** if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) { return 1; } + + if ((colon = strstr(Z_STRVAL_P(callable), "::")) != NULL) { + clen = colon - Z_STRVAL_P(callable); + mlen = Z_STRLEN_P(callable) - clen - 2; + lcname = estrndup(Z_STRVAL_P(callable), clen); + lcname[clen] = '\0'; + lmname = zend_str_tolower_dup(Z_STRVAL_P(callable) + clen + 2, mlen); + if (zend_lookup_class(lcname, clen, &pce TSRMLS_CC) == FAILURE) { + efree(lcname); + efree(lmname); + return 0; + } + *ce_ptr = *pce; + ftable = &(*ce_ptr)->function_table; + } else { + mlen = Z_STRLEN_P(callable); + lmname = zend_str_tolower_dup(Z_STRVAL_P(callable), mlen); + ftable = EG(function_table); + } - lcname = zend_str_tolower_dup(Z_STRVAL_P(callable), Z_STRLEN_P(callable)); - if (zend_hash_find(EG(function_table), lcname, Z_STRLEN_P(callable)+1, (void**)fptr_ptr) == SUCCESS) { + if (zend_hash_find(ftable, lmname, mlen+1, (void**)fptr_ptr) == SUCCESS) { retval = 1; } - efree(lcname); + if (*ce_ptr) { + efree(lcname); + if (!((*fptr_ptr)->common.fn_flags & ZEND_ACC_STATIC)) { + retval = 0; + } + } + efree(lmname); break; case IS_ARRAY: { - zend_class_entry *ce = NULL, **pce; + zend_class_entry *ce = NULL; zval **method; zval **obj; @@ -2021,17 +2046,17 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char ** return 1; } - lcname = zend_str_tolower_dup(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj)); - - if (EG(active_op_array) && strcmp(lcname, "self") == 0) { - ce = EG(active_op_array)->scope; - } else if (strcmp(lcname, "parent") == 0 && EG(active_op_array) && EG(active_op_array)->scope) { - ce = EG(active_op_array)->scope->parent; - } else if (zend_lookup_class(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), &pce TSRMLS_CC) == SUCCESS) { + if (zend_lookup_class(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), &pce TSRMLS_CC) == SUCCESS) { ce = *pce; + } else if (EG(active_op_array)) { + lcname = zend_str_tolower_dup(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj)); + if (Z_STRLEN_PP(obj) == sizeof("self") - 1 && memcmp(lcname, "self", sizeof("self")) == 0) { + ce = EG(active_op_array)->scope; + } else if (Z_STRLEN_PP(obj) == sizeof("parent") - 1 && memcmp(lcname, "parent", sizeof("parent")) == 0 && EG(active_op_array)->scope) { + ce = EG(active_op_array)->scope->parent; + } + efree(lcname); } - - efree(lcname); } else { ce = Z_OBJCE_PP(obj); /* TBFixed: what if it's overloaded? */ @@ -2090,6 +2115,9 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char ** *callable_name = estrndup("Array", sizeof("Array")-1); *callable_name_len = sizeof("Array") - 1; } + if (!*zobj_ptr_ptr && (!*fptr_ptr || !((*fptr_ptr)->common.fn_flags & ZEND_ACC_STATIC))) { + retval = 0; + } *ce_ptr = ce; } break; |