]> granicus.if.org Git - php/commitdiff
- Fixed bug #47054 (BC break in static functions called as dynamic)
authorFelipe Pena <felipe@php.net>
Sat, 10 Jan 2009 19:14:27 +0000 (19:14 +0000)
committerFelipe Pena <felipe@php.net>
Sat, 10 Jan 2009 19:14:27 +0000 (19:14 +0000)
Zend/tests/bug47054.phpt [new file with mode: 0644]
Zend/zend_builtin_functions.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/bug47054.phpt b/Zend/tests/bug47054.phpt
new file mode 100644 (file)
index 0000000..ab6c6e1
--- /dev/null
@@ -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
index d8ffc81e23047a3eeaa934bc48d375b001b2fcca..f976c7500b30376c94ff5798e35fdc8920097208 100644 (file)
@@ -743,10 +743,10 @@ ZEND_FUNCTION(get_called_class)
 
        if (EG(called_scope)) {
                RETURN_TEXTL(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;
 }
 /* }}} */
 
index 8177ec6b3b8e547765f44607a4faa4a4c615956a..34b7707f625c1a6cb88b29ea610c690ac1aad7e2 100644 (file)
@@ -1977,15 +1977,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+               
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
index 6153fbe092c3f8be09e27f717ceafead88fb54e7..dc13bb495d95a751d059fb35cbd206c0d85de1ad 100644 (file)
@@ -6193,15 +6193,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -6666,15 +6669,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -7141,15 +7147,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -7711,15 +7720,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -10719,15 +10731,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -12632,15 +12647,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -14529,15 +14547,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -17046,15 +17067,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -18480,15 +18504,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -19680,15 +19707,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -20812,15 +20842,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -22213,15 +22246,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -25248,15 +25284,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -26970,15 +27009,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -28744,15 +28786,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {
@@ -31026,15 +31071,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 %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
                }
+
+               EX(called_scope) = Z_OBJCE_P(EX(object));
        } else {
                zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), 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 {