Hello internals,

  Andrei asked me whether we could do something about the double
lowercasing when calling zend_is_callable_check_func(). The attached
patch adds the new fetch flag ZEND_FETCH_CLASS_NO_NORMALIZE which
prevent lowercasing. Also zend_u_lookup_class_ex() got a new parameter
which allows to specify whether the function needs to lowercase or
not. I am quite sure Andrei needs to touch it a bit further but i
think we should discuss this step first.

Best regards,
 Marcus
? Zend/tests/catch_005.phpt
Index: Zend/zend_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.378
diff -u -p -d -r1.378 zend_API.c
--- Zend/zend_API.c     13 Jul 2006 21:27:48 -0000      1.378
+++ Zend/zend_API.c     15 Jul 2006 19:49:28 -0000
@@ -2581,7 +2581,6 @@ static int zend_is_callable_check_func(i
        zstr lcname, lmname, mname, colon;
        unsigned int clen, mlen;
        zend_function *fptr;
-       zend_class_entry **pce;
        HashTable *ftable;
 
        *ce_ptr = NULL;
@@ -2603,15 +2602,7 @@ static int zend_is_callable_check_func(i
        if (colon.v != NULL) {
                lcname = zend_u_str_case_fold(Z_TYPE_P(callable), 
Z_UNIVAL_P(callable), clen, 0, &clen);
                /* caution: lcname is not '\0' terminated */
-               if (clen == sizeof("self") - 1 &&
-                   ZEND_U_EQUAL(Z_TYPE_P(callable), lcname, clen, "self", 
sizeof("self")-1)) {
-                       *ce_ptr = EG(scope);
-               } else if (clen == sizeof("parent") - 1 &&
-                   ZEND_U_EQUAL(Z_TYPE_P(callable), lcname, clen, "parent", 
sizeof("parent")-1)) {
-                       *ce_ptr = EG(scope) ? EG(scope)->parent : NULL;
-               } else if (zend_u_lookup_class(Z_TYPE_P(callable), 
Z_UNIVAL_P(callable), clen, &pce TSRMLS_CC) == SUCCESS) {
-                       *ce_ptr = *pce;
-               }
+               *ce_ptr = zend_u_fetch_class(Z_TYPE_P(callable), lcname, clen, 
ZEND_FETCH_CLASS_AUTO|ZEND_FETCH_CLASS_NO_NORMALIZE TSRMLS_CC);
                efree(lcname.v);
                if (!*ce_ptr) {
                        return 0;
Index: Zend/zend_builtin_functions.c
===================================================================
RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v
retrieving revision 1.318
diff -u -p -d -r1.318 zend_builtin_functions.c
--- Zend/zend_builtin_functions.c       15 Jul 2006 19:16:19 -0000      1.318
+++ Zend/zend_builtin_functions.c       15 Jul 2006 19:49:29 -0000
@@ -702,7 +702,7 @@ static void is_a_impl(INTERNAL_FUNCTION_
 
        convert_to_text_ex(class_name);
 
-       if (zend_u_lookup_class_ex(Z_TYPE_PP(class_name), 
Z_UNIVAL_PP(class_name), Z_UNILEN_PP(class_name), (instance_ce != NULL) ? 1 : 
0, &ce TSRMLS_CC) == FAILURE) {
+       if (zend_u_lookup_class_ex(Z_TYPE_PP(class_name), 
Z_UNIVAL_PP(class_name), Z_UNILEN_PP(class_name), (instance_ce != NULL) ? 1 : 
0, 1, &ce TSRMLS_CC) == FAILURE) {
                retval = 0;
        } else {
                if (only_subclass) {
Index: Zend/zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.343
diff -u -p -d -r1.343 zend_compile.h
--- Zend/zend_compile.h 13 Jun 2006 12:56:20 -0000      1.343
+++ Zend/zend_compile.h 15 Jul 2006 19:49:31 -0000
@@ -615,7 +615,9 @@ int zendlex(znode *zendlval TSRMLS_DC);
 #define ZEND_FETCH_CLASS_GLOBAL                4
 #define ZEND_FETCH_CLASS_AUTO          5
 #define ZEND_FETCH_CLASS_INTERFACE     6
-#define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80
+#define ZEND_FETCH_CLASS_FLAGS        0xF0
+#define ZEND_FETCH_CLASS_NO_NORMALIZE 0x10
+#define ZEND_FETCH_CLASS_NO_AUTOLOAD  0x80
 
 /* variable parsing type (compile-time) */
 #define ZEND_PARSED_MEMBER                             (1<<0)
Index: Zend/zend_execute.h
===================================================================
RCS file: /repository/ZendEngine2/zend_execute.h,v
retrieving revision 1.100
diff -u -p -d -r1.100 zend_execute.h
--- Zend/zend_execute.h 31 May 2006 13:02:15 -0000      1.100
+++ Zend/zend_execute.h 15 Jul 2006 19:49:31 -0000
@@ -71,7 +71,7 @@ static inline void safe_free_zval_ptr_re
 }
 ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry 
***ce TSRMLS_DC);
 ZEND_API int zend_u_lookup_class(zend_uchar type, zstr name, int name_length, 
zend_class_entry ***ce TSRMLS_DC);
-ZEND_API int zend_u_lookup_class_ex(zend_uchar type, zstr name, int 
name_length, int use_autoload, zend_class_entry ***ce TSRMLS_DC);
+ZEND_API int zend_u_lookup_class_ex(zend_uchar type, zstr name, int 
name_length, int use_autoload, int do_normalize, zend_class_entry ***ce 
TSRMLS_DC);
 ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name 
TSRMLS_DC);
 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char 
*string_name, int handle_exceptions TSRMLS_DC);
 ZEND_API int zend_u_eval_string(zend_uchar type, zstr str, zval *retval_ptr, 
char *string_name TSRMLS_DC);
Index: Zend/zend_execute_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute_API.c,v
retrieving revision 1.375
diff -u -p -d -r1.375 zend_execute_API.c
--- Zend/zend_execute_API.c     12 Jul 2006 07:54:18 -0000      1.375
+++ Zend/zend_execute_API.c     15 Jul 2006 19:49:31 -0000
@@ -1062,7 +1062,7 @@ int zend_call_function(zend_fcall_info *
 }
 
 
-ZEND_API int zend_u_lookup_class_ex(zend_uchar type, zstr name, int 
name_length, int use_autoload, zend_class_entry ***ce TSRMLS_DC)
+ZEND_API int zend_u_lookup_class_ex(zend_uchar type, zstr name, int 
name_length, int use_autoload, int do_normalize, zend_class_entry ***ce 
TSRMLS_DC)
 {
        zval **args[1];
        zval autoload_function;
@@ -1080,10 +1080,16 @@ ZEND_API int zend_u_lookup_class_ex(zend
                return FAILURE;
        }
 
-       lc_name = zend_u_str_case_fold(type, name, name_length, 1, 
&lc_name_len);
+       if (do_normalize) {
+               lc_name = zend_u_str_case_fold(type, name, name_length, 1, 
&lc_name_len);
+       } else {
+               lc_name = name;
+       }
 
        if (zend_u_hash_find(EG(class_table), type, lc_name, lc_name_len+1, 
(void **) ce) == SUCCESS) {
-               efree(lc_name.v);
+               if (do_normalize) {
+                       efree(lc_name.v);
+               }
                return SUCCESS;
        }
 
@@ -1091,7 +1097,9 @@ ZEND_API int zend_u_lookup_class_ex(zend
         * (doesn't impact fuctionality of __autoload()
        */
        if (!use_autoload || zend_is_compiling(TSRMLS_C)) {
-               efree(lc_name.v);
+               if (do_normalize) {
+                       efree(lc_name.v);
+               }
                return FAILURE;
        }
 
@@ -1101,7 +1109,9 @@ ZEND_API int zend_u_lookup_class_ex(zend
        }
 
        if (zend_u_hash_add(EG(in_autoload), type, lc_name, lc_name_len+1, 
(void**)&dummy, sizeof(char), NULL) == FAILURE) {
-               efree(lc_name.v);
+               if (do_normalize) {
+                       efree(lc_name.v);
+               }
                return FAILURE;
        }
 
@@ -1143,12 +1153,16 @@ ZEND_API int zend_u_lookup_class_ex(zend
 
        if (retval == FAILURE) {
                EG(exception) = exception;
-               efree(lc_name.v);
+               if (do_normalize) {
+                       efree(lc_name.v);
+               }
                return FAILURE;
        }
 
        if (EG(exception) && exception) {
-               efree(lc_name.v);
+               if (do_normalize) {
+                       efree(lc_name.v);
+               }
                zend_error(E_ERROR, "Function %s(%R) threw an exception of type 
'%v'", ZEND_AUTOLOAD_FUNC_NAME, type, name, Z_OBJCE_P(EG(exception))->name);
                return FAILURE;
        }
@@ -1160,13 +1174,15 @@ ZEND_API int zend_u_lookup_class_ex(zend
        }
 
        retval = zend_u_hash_find(EG(class_table), type, lc_name, lc_name_len + 
1, (void **) ce);
-       efree(lc_name.v);
+       if (do_normalize) {
+               efree(lc_name.v);
+       }
        return retval;
 }
 
 ZEND_API int zend_u_lookup_class(zend_uchar type, zstr name, int name_length, 
zend_class_entry ***ce TSRMLS_DC)
 {
-       return zend_u_lookup_class_ex(type, name, name_length, 1, ce TSRMLS_CC);
+       return zend_u_lookup_class_ex(type, name, name_length, 1, 1, ce 
TSRMLS_CC);
 }
 
 ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry 
***ce TSRMLS_DC)
@@ -1545,9 +1561,12 @@ void zend_unset_timeout(TSRMLS_D)
 ZEND_API zend_class_entry *zend_u_fetch_class(zend_uchar type, zstr 
class_name, uint class_name_len, int fetch_type TSRMLS_DC)
 {
        zend_class_entry **pce;
-       int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0;
+       int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD)  ? 0 : 1;
+       int do_normalize = (fetch_type & ZEND_FETCH_CLASS_NO_NORMALIZE) ? 0 : 1;
+       zstr lcname;
+
+       fetch_type = fetch_type & ~ZEND_FETCH_CLASS_FLAGS;
 
-       fetch_type = fetch_type & ~ZEND_FETCH_CLASS_NO_AUTOLOAD;
 check_fetch_type:
        switch (fetch_type) {
                case ZEND_FETCH_CLASS_SELF:
@@ -1564,15 +1583,24 @@ check_fetch_type:
                        }
                        return EG(scope)->parent;
                case ZEND_FETCH_CLASS_AUTO: {
-                               fetch_type = zend_get_class_fetch_type(type, 
class_name, class_name_len);
+                               if (do_normalize) {
+                                       lcname = zend_u_str_case_fold(type, 
class_name, class_name_len, 0, &class_name_len);
+                                       do_normalize = 0;
+                               } else {
+                                       lcname = class_name;
+                               }
+                               fetch_type = zend_get_class_fetch_type(type, 
lcname, class_name_len);
                                if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) {
+                                       if (do_normalize) {
+                                               efree(lcname.v);
+                                       }
                                        goto check_fetch_type;
                                }
                        }
                        break;
        }
 
-       if (zend_u_lookup_class_ex(type, class_name, class_name_len, 
use_autoload, &pce TSRMLS_CC)==FAILURE) {
+       if (zend_u_lookup_class_ex(type, class_name, class_name_len, 
use_autoload, do_normalize, &pce TSRMLS_CC)==FAILURE) {
                if (use_autoload) {
                        if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
                                zend_error(E_ERROR, "Interface '%R' not found", 
type, class_name);
Index: ext/reflection/php_reflection.c
===================================================================
RCS file: /repository/php-src/ext/reflection/php_reflection.c,v
retrieving revision 1.243
diff -u -p -d -r1.243 php_reflection.c
--- ext/reflection/php_reflection.c     13 Jul 2006 12:34:30 -0000      1.243
+++ ext/reflection/php_reflection.c     15 Jul 2006 19:49:39 -0000
@@ -1972,7 +1972,7 @@ ZEND_METHOD(reflection_parameter, getCla
        GET_REFLECTION_OBJECT_PTR(param);
 
        if (param->arg_info->class_name.v) {
-               if (zend_u_lookup_class_ex(UG(unicode)?IS_UNICODE:IS_STRING, 
param->arg_info->class_name, param->arg_info->class_name_len, 1, &pce 
TSRMLS_CC) == FAILURE) {
+               if (zend_u_lookup_class_ex(UG(unicode)?IS_UNICODE:IS_STRING, 
param->arg_info->class_name, param->arg_info->class_name_len, 1, 1, &pce 
TSRMLS_CC) == FAILURE) {
                        zend_throw_exception_ex(reflection_exception_ptr, 0 
TSRMLS_CC, 
                                "Class %v does not exist", 
param->arg_info->class_name);
                        return;
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to