]> granicus.if.org Git - php/commitdiff
- Fix method invocation issues
authorMarcus Boerger <helly@php.net>
Sun, 22 Jan 2006 18:55:02 +0000 (18:55 +0000)
committerMarcus Boerger <helly@php.net>
Sun, 22 Jan 2006 18:55:02 +0000 (18:55 +0000)
Zend/zend_execute_API.c
Zend/zend_object_handlers.c

index d9d7333264fb496c83279b3417ff85720d641bfa..bbd2bd44aec98b1ad7e181eb4fe0524d16f1796d 100644 (file)
@@ -605,6 +605,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
        zend_op **original_opline_ptr;
        zend_class_entry *current_scope;
        zend_class_entry *calling_scope = NULL;
+       zend_class_entry *check_scope_or_static = NULL;
        zval *current_this;
        zend_execute_data execute_data;
        zval *method_name;
@@ -758,17 +759,19 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                                mname = colon + 2;
                        }
                }
-               if (calling_scope && colon != NULL) {
+               if (colon != NULL) {
                        zend_class_entry **pce, *ce_child = NULL;
                        if (zend_u_lookup_class(Z_TYPE_P(fci->function_name), Z_STRVAL_P(fci->function_name), clen, &pce TSRMLS_CC) == SUCCESS) {
                                ce_child = *pce;
                        } else {
                                lcname = zend_u_str_case_fold(Z_TYPE_P(fci->function_name), Z_UNIVAL_P(fci->function_name), clen, 0, &clen);
                                /* caution: lcname is not '\0' terminated */
-                               if (clen == sizeof("self") - 1 && memcmp(lcname, "self", sizeof("self") - 1) == 0) {
-                                       ce_child = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
-                               } else if (clen == sizeof("parent") - 1 && memcmp(lcname, "parent", sizeof("parent") - 1) == 0 && EG(active_op_array)->scope) {
-                                       ce_child = EG(active_op_array) && EG(active_op_array)->scope ? EG(scope)->parent : NULL;
+                               if (calling_scope) {
+                                       if (clen == sizeof("self") - 1 && memcmp(lcname, "self", sizeof("self") - 1) == 0) {
+                                               ce_child = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
+                                       } else if (clen == sizeof("parent") - 1 && memcmp(lcname, "parent", sizeof("parent") - 1) == 0 && EG(active_op_array)->scope) {
+                                               ce_child = EG(active_op_array) && EG(active_op_array)->scope ? EG(scope)->parent : NULL;
+                                       }
                                }
                                efree(lcname);
                        }
@@ -776,10 +779,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                                zend_error(E_ERROR, "Cannot call method %R() or method does not exist", Z_TYPE_P(fci->function_name), Z_UNIVAL_P(fci->function_name));
                                return FAILURE;
                        }
-                       if (!instanceof_function(calling_scope, ce_child TSRMLS_CC)) {
-                               zend_error(E_ERROR, "Cannot call method %R() of class %v which is not a derived from %v", Z_TYPE_P(fci->function_name), Z_UNIVAL_P(fci->function_name), ce_child->name, calling_scope->name);
-                               return 0;
-                       }
+                       check_scope_or_static = calling_scope;
                        fci->function_table = &ce_child->function_table;
                        calling_scope = ce_child;
                        fname = colon + (Z_TYPE_P(fci->function_name) == IS_UNICODE ? 4 : 2);
@@ -810,6 +810,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                        EX(function_state).function = 
                                zend_std_get_static_method(calling_scope, lcname, lcname_len TSRMLS_CC);
                        efree(lcname);
+                       if (check_scope_or_static && EX(function_state).function
+                       && !(EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)
+                       && !instanceof_function(check_scope_or_static, calling_scope TSRMLS_CC)) {
+                               zend_error(E_ERROR, "Cannot call method %R() of class %v which is not a derived from %v", Z_TYPE_P(fci->function_name), Z_UNIVAL_P(fci->function_name), calling_scope->name, check_scope_or_static->name);
+                               return 0;
+                       }
                } else {
                        unsigned int lcname_len;
                        char *lcname = zend_u_str_case_fold(Z_TYPE_P(fci->function_name), fname, fname_len, 1, &lcname_len);
index a59e0aed60fa45b6c614fef13a4cac5cafab7105..710484fb3487babe4058558bc326561e0fb58df6 100644 (file)
@@ -792,14 +792,14 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
                 */
                updated_fbc = zend_check_private_int(fbc, object->value.obj.handlers->get_class_entry(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC);
                if (!updated_fbc) {
-                       zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : EMPTY_STR);
+                       zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : (char*)EMPTY_STR);
                }
                fbc = updated_fbc;
        } else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) {
                /* Ensure that if we're calling a protected function, we're allowed to do so.
                 */
                if (!zend_check_protected(fbc->common.scope, EG(scope))) {
-                       zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : EMPTY_STR);
+                       zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : (char*)EMPTY_STR);
                }
        }
 
@@ -819,10 +819,17 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f
                char *class_name = ce->name;
 
                if (!class_name) {
-                       class_name = EMPTY_STR;
+                       class_name = (char*)EMPTY_STR;
                }
                zend_error(E_ERROR, "Call to undefined method %R::%R()", type, class_name, type, function_name_strval);
        }
+#if MBO_0
+       /* right now this function is used for non static method lookup too */
+       /* Is the function static */
+       if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+               zend_error(E_ERROR, "Cannot call non static method %v::%v() without object", ZEND_FN_SCOPE_NAME(fbc), fbc->common.function_name);
+       }
+#endif
        if (fbc->op_array.fn_flags & ZEND_ACC_PUBLIC) {
                /* No further checks necessary, most common case */
        } else if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) {
@@ -832,14 +839,14 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f
                 */
                updated_fbc = zend_check_private_int(fbc, EG(scope), function_name_strval, function_name_strlen TSRMLS_CC); 
                if (!updated_fbc) {
-                       zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : EMPTY_STR);
+                       zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), fbc->common.function_name, EG(scope) ? EG(scope)->name : (char*)EMPTY_STR);
                }
                fbc = updated_fbc;
        } else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) {
                /* Ensure that if we're calling a protected function, we're allowed to do so.
                 */
                if (!zend_check_protected(EG(scope), fbc->common.scope)) {
-                       zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : EMPTY_STR);
+                       zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), fbc->common.function_name, EG(scope) ? EG(scope)->name : (char*)EMPTY_STR);
                }
        }
 
@@ -908,13 +915,13 @@ static union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC)
                        /* Ensure that if we're calling a private function, we're allowed to do so.
                         */
                        if (object->value.obj.handlers->get_class_entry(object TSRMLS_CC) != EG(scope)) {
-                               zend_error(E_ERROR, "Call to private %v::%v() from context '%v'", constructor->common.scope->name, constructor->common.function_name, EG(scope) ? EG(scope)->name : EMPTY_STR);
+                               zend_error(E_ERROR, "Call to private %v::%v() from context '%v'", constructor->common.scope->name, constructor->common.function_name, EG(scope) ? EG(scope)->name : (char*)EMPTY_STR);
                        }
                } else if ((constructor->common.fn_flags & ZEND_ACC_PROTECTED)) {
                        /* Ensure that if we're calling a protected function, we're allowed to do so.
                         */
                        if (!zend_check_protected(constructor->common.scope, EG(scope))) {
-                               zend_error(E_ERROR, "Call to protected %v::%v() from context '%v'", constructor->common.scope->name, constructor->common.function_name, EG(scope) ? EG(scope)->name : EMPTY_STR);
+                               zend_error(E_ERROR, "Call to protected %v::%v() from context '%v'", constructor->common.scope->name, constructor->common.function_name, EG(scope) ? EG(scope)->name : (char*)EMPTY_STR);
                        }
                }
        }