mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Fixed bug #30519 (Interface not existing says Class not found)
This commit is contained in:
parent
cc22d6690f
commit
12b66c262a
1
NEWS
1
NEWS
@ -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)
|
||||
|
||||
|
10
Zend/tests/bug30519.phpt
Executable file
10
Zend/tests/bug30519.phpt
Executable file
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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) */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user