cvs: ZendEngine2(PHP_5_3) / zend_builtin_functions.c zend_vm_def.h zend_vm_execute.h /tests bug47054.phpt

[email protected] ("Felipe Pena") Sat, 10 Jan 2009 19:15:45 -0000
Newsgroups php.zend-engine.cvs
Message-ID <cvsfelipe1231614945@cvsserver>
felipe		Sat Jan 10 19:15:45 2009 UTC

  Added files:                 (Branch: PHP_5_3)
    /ZendEngine2/tests	bug47054.phpt 

  Modified files:              
    /ZendEngine2	zend_builtin_functions.c zend_vm_def.h 
                	zend_vm_execute.h 
  Log:
  - MFH: Fixed bug #47054 (BC break in static functions called as dynamic)
felipe-20090110191545.txt (text/plain, 15.3 KB)
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_builtin_functions.c?r1=1.277.2.12.2.25.2.43&r2=1.277.2.12.2.25.2.44&diff_format=u
Index: ZendEngine2/zend_builtin_functions.c
diff -u ZendEngine2/zend_builtin_functions.c:1.277.2.12.2.25.2.43 ZendEngine2/zend_builtin_functions.c:1.277.2.12.2.25.2.44
--- ZendEngine2/zend_builtin_functions.c:1.277.2.12.2.25.2.43	Wed Dec 31 13:25:21 2008
+++ ZendEngine2/zend_builtin_functions.c	Sat Jan 10 19:15:39 2009
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_builtin_functions.c,v 1.277.2.12.2.25.2.43 2008/12/31 13:25:21 helly Exp $ */
+/* $Id: zend_builtin_functions.c,v 1.277.2.12.2.25.2.44 2009/01/10 19:15:39 felipe Exp $ */
 
 #include "zend.h"
 #include "zend_API.h"
@@ -748,10 +748,10 @@
 
 	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;
 }
 /* }}} */
 
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.59.2.29.2.48.2.80&r2=1.59.2.29.2.48.2.81&diff_format=u
Index: ZendEngine2/zend_vm_def.h
diff -u ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.80 ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.81
--- ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.80	Mon Jan  5 20:31:51 2009
+++ ZendEngine2/zend_vm_def.h	Sat Jan 10 19:15:39 2009
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.80 2009/01/05 20:31:51 felipe Exp $ */
+/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.81 2009/01/10 19:15:39 felipe Exp $ */
 
 /* If you change this file, please regenerate the zend_vm_execute.h and
  * zend_vm_opcodes.h files by running:
@@ -1922,15 +1922,18 @@
 		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 {
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.62.2.30.2.49.2.80&r2=1.62.2.30.2.49.2.81&diff_format=u
Index: ZendEngine2/zend_vm_execute.h
diff -u ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.80 ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.81
--- ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.80	Mon Jan  5 20:31:51 2009
+++ ZendEngine2/zend_vm_execute.h	Sat Jan 10 19:15:40 2009
@@ -5923,15 +5923,18 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 {

http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug47054.phpt?view=markup&rev=1.1
Index: ZendEngine2/tests/bug47054.phpt
+++ ZendEngine2/tests/bug47054.phpt
--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