Skip to content

Commit d0f540c

Browse files
committed
fix: preserve empty-method requests during decode
1 parent c60a318 commit d0f540c

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

internal/jsonrpc2/messages.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,11 @@ func DecodeMessage(data []byte) (Message, error) {
183183
if err != nil {
184184
return nil, err
185185
}
186-
if msg.Method != "" {
186+
var fields map[string]json.RawMessage
187+
if err := internaljson.Unmarshal(data, &fields); err != nil {
188+
return nil, fmt.Errorf("unmarshaling jsonrpc message fields: %w", err)
189+
}
190+
if _, hasMethod := fields["method"]; hasMethod {
187191
// has a method, must be a call
188192
return &Request{
189193
Method: msg.Method,

internal/jsonrpc2/wire_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,23 @@ func TestWireMessage(t *testing.T) {
6363
}
6464
}
6565

66+
func TestDecodeMessageWithEmptyMethodIsRequest(t *testing.T) {
67+
msg, err := jsonrpc2.DecodeMessage([]byte(`{"jsonrpc":"2.0","id":5,"method":"","params":{}}`))
68+
if err != nil {
69+
t.Fatal(err)
70+
}
71+
req, ok := msg.(*jsonrpc2.Request)
72+
if !ok {
73+
t.Fatalf("DecodeMessage returned %T, want *jsonrpc2.Request", msg)
74+
}
75+
if req.Method != "" {
76+
t.Fatalf("Request.Method = %q, want empty string", req.Method)
77+
}
78+
if got := req.ID.Raw(); got != int64(5) {
79+
t.Fatalf("Request.ID = %v, want 5", got)
80+
}
81+
}
82+
6683
func newNotification(method string, params any) jsonrpc2.Message {
6784
msg, err := jsonrpc2.NewNotification(method, params)
6885
if err != nil {

0 commit comments

Comments
 (0)