This is an automated email from the ASF dual-hosted git repository.
Alanxtl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/develop by this push:
new 598aa49ea fix(invocation): guard ActualMethodName type assertion to
avoid panic (#3684)
598aa49ea is described below
commit 598aa49eacc925a11c9a907a90c5e8aedfb08bb0
Author: Lcos <[email protected]>
AuthorDate: Thu Aug 20 13:12:14 2026 +0800
fix(invocation): guard ActualMethodName type assertion to avoid panic
(#3684)
* fix(invocation): guard ActualMethodName type assertion to avoid panic
IsGenericInvocation only guarantees len(Arguments)==3, not the element
types. The bare type assertion in ActualMethodName (arg[0].(string))
could panic on a malformed $invoke request. Replace it with comma-ok
form and fall back to MethodName() on mismatch, since the interface
signature has no error return. The interface and all 7 call sites are
unaffected.
Fixes #3683
Signed-off-by: Lcos <[email protected]>
Signed-off-by: user.email <[email protected]>
* refactor(invocation): address copilot review feedback
- Extract args := r.Arguments() before assertion for clarity.
- Wrap test assertion in require.NotPanics for intention-revealing.
Signed-off-by: Lcos <[email protected]>
Signed-off-by: user.email <[email protected]>
---------
Signed-off-by: Lcos <[email protected]>
Signed-off-by: user.email <[email protected]>
---
protocol/invocation/rpcinvocation.go | 12 +++++++++---
protocol/invocation/rpcinvocation_test.go | 29 +++++++++++++++++++++++++++++
2 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/protocol/invocation/rpcinvocation.go
b/protocol/invocation/rpcinvocation.go
index 242489c4e..9f5874a6b 100644
--- a/protocol/invocation/rpcinvocation.go
+++ b/protocol/invocation/rpcinvocation.go
@@ -84,10 +84,16 @@ func (r *RPCInvocation) MethodName() string {
// ActualMethodName gets actual invocation method name. It returns the method
name been called if it's a generic call
func (r *RPCInvocation) ActualMethodName() string {
if r.IsGenericInvocation() {
- return r.Arguments()[0].(string)
- } else {
- return r.MethodName()
+ // IsGenericInvocation only guarantees len(Arguments)==3, not
the element types;
+ // guard the assertion so a malformed $invoke falls back to
MethodName() instead of panicking.
+ args := r.Arguments()
+ mtdName, ok := args[0].(string)
+ if !ok {
+ return r.MethodName()
+ }
+ return mtdName
}
+ return r.MethodName()
}
// IsGenericInvocation gets if this is a generic invocation
diff --git a/protocol/invocation/rpcinvocation_test.go
b/protocol/invocation/rpcinvocation_test.go
index e8c47674f..f03f23c2f 100644
--- a/protocol/invocation/rpcinvocation_test.go
+++ b/protocol/invocation/rpcinvocation_test.go
@@ -164,6 +164,35 @@ func TestRPCInvocation_ActualMethodName(t *testing.T) {
assert.Equal(t, "actualAsyncMethod", invocation.ActualMethodName())
}
+// TestRPCInvocation_ActualMethodName_MalformedArgs ensures a malformed $invoke
+// (arg[0] not a string) falls back to MethodName() instead of panicking.
+// See issue #3683.
+func TestRPCInvocation_ActualMethodName_MalformedArgs(t *testing.T) {
+ cases := []struct {
+ name string
+ method string
+ args []any
+ want string
+ }{
+ {name: "invoke-arg0-int", method: constant.Generic, args:
[]any{123, []string{}, []any{}}, want: constant.Generic},
+ {name: "invoke-arg0-nil", method: constant.Generic, args:
[]any{nil, []string{}, []any{}}, want: constant.Generic},
+ {name: "invokeAsync-arg0-int", method: constant.GenericAsync,
args: []any{123, []string{}, []any{}}, want: constant.GenericAsync},
+ {name: "invokeAsync-arg0-nil", method: constant.GenericAsync,
args: []any{nil, []string{}, []any{}}, want: constant.GenericAsync},
+ }
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ inv := NewRPCInvocationWithOptions(
+ WithMethodName(tc.method),
+ WithArguments(tc.args),
+ )
+ // Should fall back to MethodName() without panicking.
+ require.NotPanics(t, func() {
+ assert.Equal(t, tc.want, inv.ActualMethodName())
+ })
+ })
+ }
+}
+
func TestRPCInvocation_IsGenericInvocation(t *testing.T) {
// Test non-generic invocation
invocation := NewRPCInvocationWithOptions(