]> granicus.if.org Git - php/commitdiff
Fixed bug #30519 (Interface not existing says Class not found)
authorDmitry Stogov <dmitry@php.net>
Fri, 24 Jun 2005 08:45:44 +0000 (08:45 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 24 Jun 2005 08:45:44 +0000 (08:45 +0000)
NEWS
Zend/tests/bug30519.phpt [new file with mode: 0755]
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_execute_API.c

diff --git a/NEWS b/NEWS
index faf7c7e813dc09c78658ca225d98016518b5ba56..b5c1cab3e147b7f8018e6f19d81d9f9a2305ea0b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -149,6 +149,7 @@ PHP                                                                        NEWS
 - Fixed bug #30707 (Segmentation fault on exception in method). (Stas, Dmitry)
 - Fixed bug #30702 (cannot initialize class variable from class constant).
   (Dmitry)
+- Fixed bug #30519 (Interface not existing says Class not found). (Dmitry)
 - Fixed bug #30394 (Assignment operators yield wrong result with __get/__set).
   (Dmitry)
 - Fixed bug #30332 (zend.ze1_compatibility_mode isnt fully compatable with
diff --git a/Zend/tests/bug30519.phpt b/Zend/tests/bug30519.phpt
new file mode 100755 (executable)
index 0000000..185d21a
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+Bug #30519 Interface not existing says Class not found 
+--FILE--
+<?php
+class test implements a {
+}
+?>
+--EXPECTF--
+Fatal error: Interface 'a' not found in %sbug30519.php on line 2
+
index 4656b448a531a3240f9638ff56518d08fc16fb65..3e372a1bbc43b66ea83e6c1a12da1dd7bee26342 100644 (file)
@@ -1295,6 +1295,7 @@ void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC)
                opline->op2 = *class_name;
        }
        opline->result.u.var = get_temporary_variable(CG(active_op_array));
+       opline->result.u.EA.type = opline->extended_value;
        opline->result.op_type = IS_CONST; /* FIXME: Hack so that INIT_FCALL_BY_NAME still knows this is a class */
        *result = opline->result;
 }
@@ -2538,6 +2539,16 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
        new_class_entry->ce_flags |= class_token->u.EA.type;
 
        if (parent_class_name && parent_class_name->op_type != IS_UNUSED) {
+               switch (parent_class_name->u.EA.type) {
+                       case ZEND_FETCH_CLASS_SELF:
+                               zend_error(E_COMPILE_ERROR, "Cannot use 'self' as class name as it is reserved");
+                               break;
+                       case ZEND_FETCH_CLASS_PARENT:
+                               zend_error(E_COMPILE_ERROR, "Cannot use 'parent' as class name as it is reserved");
+                               break;
+                       default:
+                               break;
+               }
                doing_inheritance = 1;
        }
 
@@ -2630,8 +2641,26 @@ void zend_do_end_class_declaration(znode *class_token, znode *parent_token TSRML
 
 void zend_do_implements_interface(znode *interface_znode TSRMLS_DC)
 {
-       zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+       zend_op *opline;
 
+       switch (interface_znode->u.EA.type) {
+               case ZEND_FETCH_CLASS_SELF:
+                       zend_error(E_COMPILE_ERROR, "Cannot use 'self' as interface name as it is reserved");
+                       break;
+               case ZEND_FETCH_CLASS_PARENT:
+                       zend_error(E_COMPILE_ERROR, "Cannot use 'parent' as interface name as it is reserved");
+                       break;
+               default:
+                       if (CG(active_op_array)->last > 0) {
+                               opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
+                               if (opline->opcode == ZEND_FETCH_CLASS) {
+                                       opline->extended_value = ZEND_FETCH_CLASS_INTERFACE;
+                               }
+                       }
+                       break;
+       }
+       
+       opline = get_next_op(CG(active_op_array) TSRMLS_CC);
        opline->opcode = ZEND_ADD_INTERFACE;
        opline->op1 = CG(implementing_class);
        opline->op2 = *interface_znode;
index c17b49eb5fa5a27457a5a49c1e1a3725e27c1252..7eda6b9e6a52d448102ac19ec22d32561869cec7 100644 (file)
@@ -744,6 +744,7 @@ int zendlex(znode *zendlval TSRMLS_DC);
 #define ZEND_FETCH_CLASS_MAIN          3
 #define ZEND_FETCH_CLASS_GLOBAL                4
 #define ZEND_FETCH_CLASS_AUTO          5
+#define ZEND_FETCH_CLASS_INTERFACE     6
 
 
 /* variable parsing type (compile-time) */
index de38044c6542397907e998ce8dcfc28b555b22bd..3f930232949bb4c9d51414a7c56aed52213fa506 100644 (file)
@@ -2455,7 +2455,7 @@ int zend_fetch_class_handler(ZEND_OPCODE_HANDLER_ARGS)
        
 
        if (opline->op2.op_type == IS_UNUSED) {
-               EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, ZEND_FETCH_CLASS_AUTO, opline->extended_value TSRMLS_CC);
+               EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
                NEXT_OPCODE();
        }
 
@@ -2466,7 +2466,7 @@ int zend_fetch_class_handler(ZEND_OPCODE_HANDLER_ARGS)
                        EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name);
                        break;
                case IS_STRING:
-                       EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
+                       EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
                        break;
                default:
                        zend_error(E_ERROR, "Class name must be a valid object or a string");
index 560a6c6e01016d3487b2eae2b8f44a4346eba23c..0863845619f865e21b1390f88d0c0d985ac60cd5 100644 (file)
@@ -1338,7 +1338,11 @@ check_fetch_type:
        }
 
        if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) {
-               zend_error(E_ERROR, "Class '%s' not found", class_name);
+               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 *pce;
 }