From: Dmitry Stogov Date: Fri, 9 Sep 2005 06:48:49 +0000 (+0000) Subject: Changed "instanceof" and "catch" operators, is_a() and is_subclass_of() functions... X-Git-Tag: RELEASE_1_0RC1~16 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9305339d94c701e8eda93dbf0231d70918ef4a6a;p=php Changed "instanceof" and "catch" operators, is_a() and is_subclass_of() functions to not call __autoload(). --- diff --git a/NEWS b/NEWS index 7ba55c4c7f..ee93fc89c5 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? Aug 2005, PHP 5.1 Release Candidate 2 +- Changed "instanceof" and "catch" operators, is_a() and is_subclass_of() + functions to not call __autoload(). (Dmitry) - Added support for class constants and static members for internal classes. (Dmitry, Michael Wallner) - Added "new_link" parameter to mssql_connect(). Bug #34369. (Frank) diff --git a/Zend/tests/catch.phpt b/Zend/tests/catch.phpt new file mode 100755 index 0000000000..0ec5cf7590 --- /dev/null +++ b/Zend/tests/catch.phpt @@ -0,0 +1,23 @@ +--TEST-- +catch shouldn't call __autoload +--FILE-- + +--EXPECT-- +ok diff --git a/Zend/tests/instanceof.phpt b/Zend/tests/instanceof.phpt new file mode 100755 index 0000000000..8bcbede999 --- /dev/null +++ b/Zend/tests/instanceof.phpt @@ -0,0 +1,18 @@ +--TEST-- +instanceof shouldn't call __autoload +--FILE-- + +--EXPECT-- +bool(false) +bool(true) diff --git a/Zend/tests/is_a.phpt b/Zend/tests/is_a.phpt new file mode 100755 index 0000000000..dfc0d59b49 --- /dev/null +++ b/Zend/tests/is_a.phpt @@ -0,0 +1,51 @@ +--TEST-- +is_a() and is_subclass_of() shouldn't call __autoload +--INI-- +error_reporting=4095 +--FILE-- + +--EXPECTF-- +Strict Standards: is_a(): Deprecated. Please use the instanceof operator in %sis_a.php on line 17 +bool(false) + +Strict Standards: is_a(): Deprecated. Please use the instanceof operator in %sis_a.php on line 18 +bool(true) + +Strict Standards: is_a(): Deprecated. Please use the instanceof operator in %sis_a.php on line 19 +bool(true) + +Strict Standards: is_a(): Deprecated. Please use the instanceof operator in %sis_a.php on line 20 +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +AUTOLOAD 'X1' +AUTOLOAD 'X2' +bool(false) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index e46a9ef0a9..ccadc146de 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -625,7 +625,7 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass) convert_to_string_ex(class_name); - if (zend_lookup_class(Z_STRVAL_PP(class_name), Z_STRLEN_PP(class_name), &ce TSRMLS_CC) == FAILURE) { + if (zend_lookup_class_ex(Z_STRVAL_PP(class_name), Z_STRLEN_PP(class_name), (instance_ce != NULL), &ce TSRMLS_CC) == FAILURE) { retval = 0; } else { if (only_subclass) { diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c1a4f586dd..1cfcef5087 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1712,6 +1712,13 @@ void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var, long catch_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline; + if (catch_op_number > 0) { + opline = &CG(active_op_array)->opcodes[catch_op_number-1]; + if (opline->opcode == ZEND_FETCH_CLASS) { + opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD; + } + } + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_CATCH; opline->op1 = *catch_class; @@ -3468,8 +3475,17 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type TSRMLS_DC) { - zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); + int last_op_number = get_next_op_number(CG(active_op_array)); + zend_op *opline; + if (last_op_number > 0) { + opline = &CG(active_op_array)->opcodes[last_op_number-1]; + if (opline->opcode == ZEND_FETCH_CLASS) { + opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD; + } + } + + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_INSTANCEOF; opline->result.op_type = IS_TMP_VAR; opline->result.u.var = get_temporary_variable(CG(active_op_array)); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index b63dd8c90a..006f0eedd8 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -583,7 +583,7 @@ 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 /* variable parsing type (compile-time) */ #define ZEND_PARSED_MEMBER (1<<0) diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index bf7657ed0f..98a6b04949 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -65,6 +65,7 @@ static inline void safe_free_zval_ptr_rel(zval *p ZEND_FILE_LINE_DC ZEND_FILE_LI } } ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC); +ZEND_API int zend_lookup_class_ex(char *name, int name_length, int use_autoload, 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); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index dcc1249f80..9022ee0de3 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -908,7 +908,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } -ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC) +ZEND_API int zend_lookup_class_ex(char *name, int name_length, int use_autoload, zend_class_entry ***ce TSRMLS_DC) { zval **args[1]; zval autoload_function; @@ -936,7 +936,7 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry *** /* The compiler is not-reentrant. Make sure we __autoload() only during run-time * (doesn't impact fuctionality of __autoload() */ - if (zend_is_compiling(TSRMLS_C)) { + if (!use_autoload || zend_is_compiling(TSRMLS_C)) { free_alloca(lc_name); return FAILURE; } @@ -1004,6 +1004,11 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry *** return retval; } +ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC) +{ + return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC); +} + ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) { zval pv; @@ -1329,7 +1334,9 @@ void zend_unset_timeout(TSRMLS_D) zend_class_entry *zend_fetch_class(char *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; + fetch_type = fetch_type & ~ZEND_FETCH_CLASS_NO_AUTOLOAD; check_fetch_type: switch (fetch_type) { case ZEND_FETCH_CLASS_SELF: @@ -1354,12 +1361,15 @@ check_fetch_type: break; } - if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) { - if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) { - zend_error(E_ERROR, "Interface '%s' not found", class_name); - } else { - zend_error(E_ERROR, "Class '%s' not found", class_name); + if (zend_lookup_class_ex(class_name, class_name_len, use_autoload, &pce TSRMLS_CC)==FAILURE) { + if (use_autoload) { + if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) { + zend_error(E_ERROR, "Interface '%s' not found", class_name); + } else { + zend_error(E_ERROR, "Class '%s' not found", class_name); + } } + return NULL; } return *pce; }