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(

Reply via email to