Browse Source

- MFH: Fixed bug #47054 (BC break in static functions called as dynamic)

experimental/5.3-FPM
Felipe Pena 17 years ago
parent
commit
23f7fa57fe
  1. 39
      Zend/tests/bug47054.phpt
  2. 4
      Zend/zend_builtin_functions.c
  3. 11
      Zend/zend_vm_def.h
  4. 112
      Zend/zend_vm_execute.h

39
Zend/tests/bug47054.phpt

@ -0,0 +1,39 @@
--TEST--
Bug #47054 (BC break in static functions called as dynamic)
--FILE--
<?php
class C {
final static function s() {
print "Called class: " . get_called_class() . "\n";
}
}
class D extends C {
public function m() {
$this->s();
}
}
$d = new D();
$d->m();
C::s();
$c = new C();
$c->s();
get_called_class();
D::m();
?>
--EXPECTF--
Called class: D
Called class: C
Called class: C
Warning: get_called_class() called from outside a class in %s on line %d
Strict Standards: Non-static method D::m() should not be called statically in %s on line %d
Fatal error: Using $this when not in object context in %s on line %d

4
Zend/zend_builtin_functions.c

@ -748,10 +748,10 @@ ZEND_FUNCTION(get_called_class)
if (EG(called_scope)) {
RETURN_STRINGL(EG(called_scope)->name, EG(called_scope)->name_length, 1);
} else {
} else if (!EG(scope)) {
zend_error(E_WARNING, "get_called_class() called from outside a class");
RETURN_FALSE;
}
RETURN_FALSE;
}
/* }}} */

11
Zend/zend_vm_def.h

@ -1922,15 +1922,18 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {

112
Zend/zend_vm_execute.h

@ -5923,15 +5923,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -6389,15 +6392,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -6857,15 +6863,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -7419,15 +7428,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -10271,15 +10283,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -12104,15 +12119,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -13933,15 +13951,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -16372,15 +16393,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -17741,15 +17765,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -18871,15 +18898,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -19945,15 +19975,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -21289,15 +21322,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -24126,15 +24162,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -25790,15 +25829,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -27506,15 +27548,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {
@ -29730,15 +29775,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H
if (!EX(fbc)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
}
EX(called_scope) = Z_OBJCE_P(EX(object));
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
if (!EX(object) || (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
if (!EX(object)) {
EX(called_scope) = NULL;
EX(object) = NULL;
} else if (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
EX(object) = NULL;
} else {
EX(called_scope) = Z_OBJCE_P(EX(object));
if (!PZVAL_IS_REF(EX(object))) {
Z_ADDREF_P(EX(object)); /* For $this pointer */
} else {

Loading…
Cancel
Save