diff options
author | Dmitry Stogov <dmitry@php.net> | 2005-06-24 08:45:17 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2005-06-24 08:45:17 +0000 |
commit | 12b66c262a46d0695d65ad5aa64d7ecb0aca0086 (patch) | |
tree | aa72f8512d20224dec268dbdbfe0819d323044b9 | |
parent | cc22d6690f94652c696596306f29ebd0088ce42e (diff) | |
download | php-git-12b66c262a46d0695d65ad5aa64d7ecb0aca0086.tar.gz |
Fixed bug #30519 (Interface not existing says Class not found)
-rw-r--r-- | NEWS | 1 | ||||
-rwxr-xr-x | Zend/tests/bug30519.phpt | 10 | ||||
-rw-r--r-- | Zend/zend_compile.c | 31 | ||||
-rw-r--r-- | Zend/zend_compile.h | 1 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 6 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 4 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 20 |
7 files changed, 59 insertions, 14 deletions
@@ -5,6 +5,7 @@ PHP NEWS overloaded (__get)). (Dmitry) - Fixed bug #30828 (debug_backtrace() reports incorrect class in overridden methods). (Dmitry) +- Fixed bug #30519 (Interface not existing says Class not found). (Dmitry) - Fixed bug #28377 (debug_backtrace is intermittently passing args). (Dmitry) - Fixed bug #27268 (Bad references accentuated by clone). (Dmitry) diff --git a/Zend/tests/bug30519.phpt b/Zend/tests/bug30519.phpt new file mode 100755 index 0000000000..185d21aef7 --- /dev/null +++ b/Zend/tests/bug30519.phpt @@ -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 + diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index aaa488eba4..718d1527e8 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1392,6 +1392,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; } @@ -2625,6 +2626,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; } @@ -2717,8 +2728,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; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 06f54ab218..b736eda958 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -581,6 +581,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) */ diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 82e59f7651..1ff2f99126 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1326,7 +1326,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; } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index d484ee853c..3bc99c1c5a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1586,7 +1586,7 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV) if (OP2_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); ZEND_VM_NEXT_OPCODE(); } @@ -1597,7 +1597,7 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV) 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_noreturn(E_ERROR, "Class name must be a valid object or a string"); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 46ee7fa7c1..7c9db30753 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -573,7 +573,7 @@ static int ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CONST == 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); ZEND_VM_NEXT_OPCODE(); } @@ -584,7 +584,7 @@ static int ZEND_FETCH_CLASS_SPEC_CONST_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_noreturn(E_ERROR, "Class name must be a valid object or a string"); @@ -769,7 +769,7 @@ static int ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_TMP_VAR == 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); ZEND_VM_NEXT_OPCODE(); } @@ -780,7 +780,7 @@ static int ZEND_FETCH_CLASS_SPEC_TMP_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_noreturn(E_ERROR, "Class name must be a valid object or a string"); @@ -923,7 +923,7 @@ static int ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_VAR == 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); ZEND_VM_NEXT_OPCODE(); } @@ -934,7 +934,7 @@ static int ZEND_FETCH_CLASS_SPEC_VAR_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_noreturn(E_ERROR, "Class name must be a valid object or a string"); @@ -1077,7 +1077,7 @@ static int ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_UNUSED == 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); ZEND_VM_NEXT_OPCODE(); } @@ -1088,7 +1088,7 @@ static int ZEND_FETCH_CLASS_SPEC_UNUSED_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_noreturn(E_ERROR, "Class name must be a valid object or a string"); @@ -1160,7 +1160,7 @@ static int ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CV == 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); ZEND_VM_NEXT_OPCODE(); } @@ -1171,7 +1171,7 @@ static int ZEND_FETCH_CLASS_SPEC_CV_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_noreturn(E_ERROR, "Class name must be a valid object or a string"); |