Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:11939 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 32924 invoked by uid 1010); 5 Aug 2004 14:30:12 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 32275 invoked from network); 5 Aug 2004 14:30:05 -0000 Received: from unknown (HELO is.magroup.ru) (213.33.179.242) by pb1.pair.com with SMTP; 5 Aug 2004 14:30:05 -0000 Received: from grp-dovgal.media-arts.ru ([192.168.3.226]) by is.magroup.ru with Microsoft SMTPSVC(5.0.2195.6713); Thu, 5 Aug 2004 18:31:07 +0400 Date: Thu, 5 Aug 2004 18:31:06 +0400 To: php-dev Message-ID: <20040805183106.71abc7b1.tony2001@phpclub.net> X-Mailer: Sylpheed version 0.9.12cvs1 (GTK+ 1.2.10; i686-pc-linux-gnu) Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Multipart=_Thu__5_Aug_2004_18_31_06_+0400_MbP=k5lS7Ec._JuD" X-OriginalArrivalTime: 05 Aug 2004 14:31:07.0053 (UTC) FILETIME=[D82D1DD0:01C47AF8] Subject: [PATCH for ZE] is_callable() doesn't differentiate private/protected methods from public ones From: tony2001@phpclub.net (Antony Dovgal) --Multipart=_Thu__5_Aug_2004_18_31_06_+0400_MbP=k5lS7Ec._JuD Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Hi all. The patch fixes bug #29210 perfectly, but I'm not sure if the implementation is the best. The appropriate test is attached too. Any comments are welcome. --- WBR, Antony Dovgal aka tony2001 tony2001@phpclub.net || antony@dovgal.com --Multipart=_Thu__5_Aug_2004_18_31_06_+0400_MbP=k5lS7Ec._JuD Content-Type: text/plain; name="is_callable.diff.txt" Content-Disposition: attachment; filename="is_callable.diff.txt" Content-Transfer-Encoding: 7bit Index: zend_API.c =================================================================== RCS file: /repository/ZendEngine2/zend_API.c,v retrieving revision 1.256 diff -u -r1.256 zend_API.c --- zend_API.c 5 Jun 2004 14:59:21 -0000 1.256 +++ zend_API.c 5 Aug 2004 11:48:04 -0000 @@ -1721,10 +1721,47 @@ } if (ce) { + zend_function *fbc; + zend_object *zobj; + zval tmp_obj; + + if (Z_TYPE_PP(obj) == IS_OBJECT) { + zobj = zend_objects_get_address(*obj TSRMLS_CC); + tmp_obj = **obj; + } + else { + tmp_obj.value.obj = zend_objects_new(&zobj, ce TSRMLS_CC); + ALLOC_HASHTABLE(zobj->properties); + zend_hash_init(zobj->properties, 0, NULL, ZVAL_PTR_DTOR, 0); + } + lcname = zend_str_tolower_dup(Z_STRVAL_PP(method), Z_STRLEN_PP(method)); - if (zend_hash_exists(&ce->function_table, lcname, Z_STRLEN_PP(method)+1)) { - retval = 1; + + retval = 1; + + if (zend_hash_find(&zobj->ce->function_table, lcname, Z_STRLEN_PP(method)+1, (void **)&fbc) == SUCCESS) { + if (fbc->op_array.fn_flags & ZEND_ACC_PUBLIC) { + if (EG(scope) && fbc->op_array.fn_flags & ZEND_ACC_CHANGED) { + zend_function *priv_fbc; + + if (zend_hash_find(&EG(scope)->function_table, lcname, Z_STRLEN_PP(method)+1, (void **) &priv_fbc)==SUCCESS + && priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE) { + retval = 0; + } + } + } else if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) { + + if (!zend_check_private(fbc, tmp_obj.value.obj.handlers->get_class_entry(&tmp_obj TSRMLS_CC), fbc->common.fn_flags, lcname, Z_STRLEN_PP(method) TSRMLS_CC)) { + retval = 0; + } + } else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) { + if (!zend_check_protected(fbc->common.scope, EG(scope))) { + retval = 0; + } + } + } + /* check for __call too */ if (retval == 0 && ce->__call != 0) { retval = 1; Index: zend_object_handlers.c =================================================================== RCS file: /repository/ZendEngine2/zend_object_handlers.c,v retrieving revision 1.104 diff -u -r1.104 zend_object_handlers.c --- zend_object_handlers.c 22 Jul 2004 11:54:27 -0000 1.104 +++ zend_object_handlers.c 5 Aug 2004 11:48:04 -0000 @@ -601,7 +601,7 @@ * Returns the function address that should be called, or NULL * if no such function exists. */ -inline zend_function *zend_check_private(zend_function *fbc, zend_class_entry *ce, int fn_flags, char *function_name_strval, int function_name_strlen TSRMLS_DC) +ZEND_API inline zend_function *zend_check_private(zend_function *fbc, zend_class_entry *ce, int fn_flags, char *function_name_strval, int function_name_strlen TSRMLS_DC) { if (!ce) { return 0; Index: zend_object_handlers.h =================================================================== RCS file: /repository/ZendEngine2/zend_object_handlers.h,v retrieving revision 1.41 diff -u -r1.41 zend_object_handlers.h --- zend_object_handlers.h 4 May 2004 15:03:28 -0000 1.41 +++ zend_object_handlers.h 5 Aug 2004 11:48:04 -0000 @@ -137,6 +137,8 @@ #define IS_ZEND_STD_OBJECT(z) ((z).type == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL)) #define HAS_CLASS_ENTRY(z) (Z_OBJ_HT(z)->get_class_entry != NULL) +ZEND_API inline union _zend_function *zend_check_private(union _zend_function *fbc, zend_class_entry *ce, int fn_flags, char *function_name_strval, int function_name_strlen TSRMLS_CC); + ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope); ZEND_API int zend_check_property_access(zend_object *zobj, char *prop_info_name TSRMLS_DC); --Multipart=_Thu__5_Aug_2004_18_31_06_+0400_MbP=k5lS7Ec._JuD Content-Type: text/plain; name="is_callable.phpt.txt" Content-Disposition: attachment; filename="is_callable.phpt.txt" Content-Transfer-Encoding: 7bit --TEST-- is_callable() with public/private/protected methods --FILE-- foo(); $test2 = new Test2; $test2->boo(); ?> --EXPECT-- Public IS callable from outside the class (yes): yes, static: yes Private IS NOT callable from outside the class (no): no, static: no Protected IS NOT callable from outside the class (no): no, static: no Private IS callable from the class (yes): , static: yes Private IS NOT callable from the derived class (no): no, static: no Public IS callable from the derived class (yes): yes, static: yes Protected IS callable from the derived class (yes): yes, static: yes --Multipart=_Thu__5_Aug_2004_18_31_06_+0400_MbP=k5lS7Ec._JuD--