cvs: ZendEngine2 / zend_compile.c zend_compile.h zend_execute.c
| From: | Zeev Suraski | Date: | Thu, 02 Jan 2003 13:58:08 +0000 |
| Subject: | cvs: ZendEngine2 / zend_compile.c zend_compile.h zend_execute.c | ||
| Groups: | php.zend-engine.cvs | ||
| Request: | Send a blank email to php-zend-engine-cvs+get-746@lists.php.net to get a copy of this message | ||
zeev Thu Jan 2 08:58:08 2003 EDT
Modified files:
/ZendEngine2 zend_compile.c zend_compile.h zend_execute.c
Log:
Fix incorrect linkage of access-levels, when using private methods
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.337 ZendEngine2/zend_compile.c:1.338
--- ZendEngine2/zend_compile.c:1.337 Tue Dec 31 10:54:07 2002
+++ ZendEngine2/zend_compile.c Thu Jan 2 08:58:07 2003
@@ -1592,10 +1592,17 @@
zend_error(E_COMPILE_ERROR, "Cannot make non abstract method %s::%s() abstract in class
%s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child));
}
- /* Prevent derived classes from restricting access that was available in parent classes
- */
- if ((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK)) {
- zend_error(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s",
ZEND_FN_SCOPE_NAME(parent), child->common.function_name, zend_visibility_string(parent_flags),
ZEND_FN_SCOPE_NAME(child), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or
weaker");
+ if (parent_flags & ZEND_ACC_CHANGED) {
+ child->common.fn_flags |= ZEND_ACC_CHANGED;
+ } else {
+ /* Prevent derived classes from restricting access that was available in parent classes
+ */
+ if ((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK)) {
+ zend_error(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s",
ZEND_FN_SCOPE_NAME(parent), child->common.function_name, zend_visibility_string(parent_flags),
ZEND_FN_SCOPE_NAME(child), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or
weaker");
+ } else if (((child_flags & ZEND_ACC_PPP_MASK) < (parent_flags & ZEND_ACC_PPP_MASK))
+ && ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) {
+ child->common.fn_flags |= ZEND_ACC_CHANGED;
+ }
}
return 0;
Index: ZendEngine2/zend_compile.h
diff -u ZendEngine2/zend_compile.h:1.201 ZendEngine2/zend_compile.h:1.202
--- ZendEngine2/zend_compile.h:1.201 Tue Dec 31 10:54:08 2002
+++ ZendEngine2/zend_compile.h Thu Jan 2 08:58:08 2003
@@ -92,10 +92,12 @@
#define ZEND_ACC_ABSTRACT 0x02
/* The order of those must be kept - public < protected < private */
-#define ZEND_ACC_PUBLIC 0x10
-#define ZEND_ACC_PROTECTED 0x20
-#define ZEND_ACC_PRIVATE 0x40
+#define ZEND_ACC_PUBLIC 0x10
+#define ZEND_ACC_PROTECTED 0x20
+#define ZEND_ACC_PRIVATE 0x40
#define ZEND_ACC_PPP_MASK (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE)
+
+#define ZEND_ACC_CHANGED 0x80
char *zend_visibility_string(zend_uint fn_flags);
Index: ZendEngine2/zend_execute.c
diff -u ZendEngine2/zend_execute.c:1.404 ZendEngine2/zend_execute.c:1.405
--- ZendEngine2/zend_execute.c:1.404 Tue Dec 31 10:54:08 2002
+++ ZendEngine2/zend_execute.c Thu Jan 2 08:58:08 2003
@@ -2228,19 +2228,23 @@
return 0;
}
- /* We may call a private function in one of two cases:
- * 1. The scope of the function is the same as the class entry of our object
- * 2. The class of our object is different, but a private function exists
- * in one of the ancestor that corresponds to our object's ce.
+ /* We may call a private function if:
+ * 1. The class of our object is the same as the scope, and the private
+ * function (EX(fbc)) has the same scope.
+ * 2. One of our parent classes are the same as the scope, and it contains
+ * a private function with the same name that has the same scope.
*/
- if (EX(fbc)->common.scope == ce) {
+ if (EX(fbc)->common.scope == ce
+ && EG(scope) == ce) {
/* rule #1 checks out ok, allow the function call */
return 1;
}
- orig_fbc = EX(fbc);
/* Check rule #2 */
+ orig_fbc = EX(fbc);
+
+ ce = ce->parent;
while (ce) {
if (ce == EG(scope)) {
if (zend_hash_find(&ce->function_table, function_name_strval, function_name_strlen+1,
(void **) &EX(fbc))==SUCCESS
@@ -2296,7 +2300,7 @@
EX(fbc) = EX(fbc_constructor);
if (EX(fbc)->type == ZEND_USER_FUNCTION) { /* HACK!! */
if (EX(fbc)->op_array.fn_flags & ZEND_ACC_PUBLIC) {
- /* No further checks necessary, most common case */
+ /* No further checks necessary */
} else if (EX(fbc)->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
@@ -2347,7 +2351,17 @@
}
if (EX(fbc)->op_array.fn_flags & ZEND_ACC_PUBLIC) {
- /* No further checks necessary, most common case */
+ /* Ensure that we haven't overridden a private function and end up calling
+ * the overriding public function...
+ */
+ if (EX(fbc)->op_array.fn_flags & ZEND_ACC_CHANGED) {
+ zend_function *priv_fbc;
+
+ if (zend_hash_find(&EG(scope)->function_table, function_name_strval,
function_name_strlen+1, (void **) &priv_fbc)==SUCCESS
+ && priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE) {
+ EX(fbc) = priv_fbc;
+ }
+ }
} else if (EX(fbc)->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/