cvs: ZendEngine2 / zend_API.c /tests access_modifiers_012.phpt

[email protected] ("Dmitry Stogov") Wed, 14 Jan 2009 11:56:24 -0000
Newsgroups php.zend-engine.cvs
Message-ID <cvsdmitry1231934184@cvsserver>
dmitry		Wed Jan 14 11:56:24 2009 UTC

  Modified files:              
    /ZendEngine2	zend_API.c 
    /ZendEngine2/tests	access_modifiers_012.phpt 
  Log:
  Fixed __call() to be invoked on private/protected method access through callback
  s
  
  
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_API.c?r1=1.495&r2=1.496&diff_format=u
Index: ZendEngine2/zend_API.c
diff -u ZendEngine2/zend_API.c:1.495 ZendEngine2/zend_API.c:1.496
--- ZendEngine2/zend_API.c:1.495	Wed Dec 31 11:12:28 2008
+++ ZendEngine2/zend_API.c	Wed Jan 14 11:56:24 2009
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_API.c,v 1.495 2008/12/31 11:12:28 sebastian Exp $ */
+/* $Id: zend_API.c,v 1.496 2009/01/14 11:56:24 dmitry Exp $ */
 
 #include "zend.h"
 #include "zend_execute.h"
@@ -2892,31 +2892,56 @@
 				fcc->function_handler = priv_fbc;
 			}
 		}
-	} else if (fcc->object_ptr) {
-		if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) {
-			zstr method = mname;
-			int method_len = mlen;
-
-			if (UG(unicode) && Z_TYPE_P(callable) == IS_STRING) {
-				zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.u, &method_len, mname.s, mlen TSRMLS_CC);
-			} else if (!UG(unicode) && Z_TYPE_P(callable) == IS_UNICODE) {
-				zend_unicode_to_string(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.s, &method_len, mname.u, mlen TSRMLS_CC);
-			}	
-			fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, method, method_len TSRMLS_CC);
-			if (method.v != mname.v) {
-				efree(method.v);
-			}
-			retval = fcc->function_handler ? 1 : 0;
-			call_via_handler = 1;
-		}
-	} else if (fcc->calling_scope) {
-		if (fcc->calling_scope->get_static_method) {
-			fcc->function_handler = fcc->calling_scope->get_static_method(fcc->calling_scope, Z_TYPE_P(callable), mname, mlen TSRMLS_CC);
-		} else {
-			fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, Z_TYPE_P(callable), mname, mlen TSRMLS_CC);
+		if ((check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0 &&
+		    (fcc->calling_scope &&
+		     (fcc->calling_scope->__call ||
+		      fcc->calling_scope->__callstatic))) {
+			if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
+				if (!zend_check_private(fcc->function_handler, fcc->object_ptr ? Z_OBJCE_P(fcc->object_ptr) : EG(scope), lmname, lmlen TSRMLS_CC)) {
+					retval = 0;
+					fcc->function_handler = NULL;
+					goto get_function_via_handler;
+				}
+			} else if ((fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED)) {
+				if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
+					retval = 0;
+					fcc->function_handler = NULL;
+					goto get_function_via_handler;
+				}
+			}
+		}
+	} else {
+get_function_via_handler:
+		if (fcc->object_ptr) {
+			if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) {
+				zstr method = mname;
+				int method_len = mlen;
+
+				if (UG(unicode) && Z_TYPE_P(callable) == IS_STRING) {
+					zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.u, &method_len, mname.s, mlen TSRMLS_CC);
+				} else if (!UG(unicode) && Z_TYPE_P(callable) == IS_UNICODE) {
+					zend_unicode_to_string(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.s, &method_len, mname.u, mlen TSRMLS_CC);
+				}	
+				fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, method, method_len TSRMLS_CC);
+				if (method.v != mname.v) {
+					efree(method.v);
+				}
+				if (fcc->function_handler) {
+					retval = 1;
+					call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
+				}
+			}
+		} else if (fcc->calling_scope) {
+			if (fcc->calling_scope->get_static_method) {
+				fcc->function_handler = fcc->calling_scope->get_static_method(fcc->calling_scope, Z_TYPE_P(callable), mname, mlen TSRMLS_CC);
+			} else {
+				fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, Z_TYPE_P(callable), mname, mlen TSRMLS_CC);
+			}
+			if (fcc->function_handler) {
+				retval = 1;
+				call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
+			}
 		}
-		retval = fcc->function_handler ? 1 : 0;
-		call_via_handler = 1;
 	}
 
 	if (retval) {
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/access_modifiers_012.phpt?r1=1.1&r2=1.2&diff_format=u
Index: ZendEngine2/tests/access_modifiers_012.phpt
diff -u /dev/null ZendEngine2/tests/access_modifiers_012.phpt:1.2
--- /dev/null	Wed Jan 14 11:56:24 2009
+++ ZendEngine2/tests/access_modifiers_012.phpt	Wed Jan 14 11:56:24 2009
@@ -0,0 +1,21 @@
+--TEST--
+Trigger __call() in lieu of non visible methods when called via a callback.
+--FILE--
+<?php
+class C {
+	protected function prot() { }
+	private function priv() { }
+	public function __call($name, $args)    {
+        echo "In __call() for method $name()\n";
+    }
+}
+
+$c = new C;
+call_user_func(array($c, 'none'));
+call_user_func(array($c, 'prot'));
+call_user_func(array($c, 'priv'));
+?>
+--EXPECTF--
+In __call() for method none()
+In __call() for method prot()
+In __call() for method priv()