]> granicus.if.org Git - php/commitdiff
nstanceof operator shouldn't call __autoload()
authorDmitry Stogov <dmitry@php.net>
Fri, 19 Aug 2005 08:11:16 +0000 (08:11 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 19 Aug 2005 08:11:16 +0000 (08:11 +0000)
NEWS
Zend/tests/instanceof.phpt [new file with mode: 0755]
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute_API.c

diff --git a/NEWS b/NEWS
index c203bd537323ccf102649f9b14d2a958b1f8f7c7..61becff453c56249182879ff522666a95a053a89 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? ????, PHP 6.0
 - Unicode support. (Andrei, Dmitriy, et al)
+- instanceof operator shouldn't call __autoload. (Dmitry)
 - cURL improvements: (Ilia)
   . Added curl_setopt_array() which allows setting of multiple cURL options.
   . Added CURLINFO_HEADER_OUT to facilitate request retrieval.
diff --git a/Zend/tests/instanceof.phpt b/Zend/tests/instanceof.phpt
new file mode 100755 (executable)
index 0000000..8bcbede
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+instanceof shouldn't call __autoload
+--FILE--
+<?php
+function __autoload($name) {
+       echo("AUTOLOAD '$name'\n");
+       eval("class $name {}");
+}
+
+class A {
+}
+$a = new A;
+var_dump($a instanceof B);
+var_dump($a instanceof A);
+?>
+--EXPECT--
+bool(false)
+bool(true)
index 9e7303869c39b9f46d6690e0466a8f35c9da0120..21cf8f77740fba067d53f50949302c8eee4af6ac 100644 (file)
@@ -3592,8 +3592,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));
index 8ddffd3be33ee15ecc4206a9978e1090a66b7c17..09877c4f477790dd87ed8aaf31db62fc6c453357 100644 (file)
@@ -597,7 +597,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)
index 60dbed82415b7b49d3fddd7971b3d989a7c31110..88df2439f29e24b937a8718498b4a4b9df1bbed5 100644 (file)
@@ -1421,7 +1421,9 @@ void zend_unset_timeout(TSRMLS_D)
 ZEND_API zend_class_entry *zend_u_fetch_class(zend_uchar type, void *class_name, uint class_name_len, int fetch_type TSRMLS_DC)
 {
        zend_class_entry **pce;
+       zend_bool 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:
@@ -1446,14 +1448,27 @@ check_fetch_type:
                        break;
        }
 
-       if (zend_u_lookup_class(type, class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) {
-               if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
-                       zend_error(E_ERROR, "Interface '%R' not found", type, class_name);
+       if (use_autoload) {
+               if (zend_u_lookup_class(type, class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) {
+                       if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
+                               zend_error(E_ERROR, "Interface '%R' not found", type, class_name);
+                       } else {
+                               zend_error(E_ERROR, "Class '%R' not found", type, class_name);
+                       }
+               }
+               return *pce;
+       } else {
+               unsigned int lc_name_len;
+               void *lc_name = zend_u_str_case_fold(type, class_name, class_name_len, 1, &lc_name_len);
+
+               if (zend_u_hash_find(EG(class_table), type, lc_name, lc_name_len+1, (void **) &pce) == SUCCESS) {
+                       efree(lc_name);
+                       return *pce;
                } else {
-                       zend_error(E_ERROR, "Class '%R' not found", type, class_name);
+                       efree(lc_name);
+                       return NULL;
                }
        }
-       return *pce;
 }
 
 zend_class_entry *zend_fetch_class(char *class_name, uint class_name_len, int fetch_type TSRMLS_DC)