From: Marcus Boerger Date: Sun, 22 Jan 2006 18:55:02 +0000 (+0000) Subject: - Fix method invocation issues X-Git-Tag: RELEASE_0_9_4~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f4a0ce710eb3d1aec9a9c86d86f15c958b6b880e;p=php - Fix method invocation issues --- diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index d9d7333264..bbd2bd44ae 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -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); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index a59e0aed60..710484fb34 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -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); } } }