Files

113 lines
4.1 KiB
Go

package control
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"path/filepath"
"testing"
"time"
rvboxv1 "github.com/rvbox/rvbox/gen/go/rvbox/v1"
"github.com/rvbox/rvbox/internal/server/store"
"google.golang.org/protobuf/encoding/protojson"
)
func TestJSONRPCUnaryMatchesControlService_HP_CTL_15(t *testing.T) {
persistence, err := store.Open(context.Background(), store.Options{DataDir: filepath.Join(t.TempDir(), "state"), BusyTimeout: time.Second})
if err != nil {
t.Fatal(err)
}
defer persistence.Close()
registerControlClient(t, persistence, "win-a", rvboxv1.Platform_PLATFORM_WINDOWS, rvboxv1.ShellType_SHELL_POWERSHELL, 9)
service, err := NewService(Options{Store: persistence, CursorKey: bytesKey()})
if err != nil {
t.Fatal(err)
}
handler := httptest.NewServer(NewJSONRPCHandler(service, 1<<20))
defer handler.Close()
requestID := fixedIssue(0xaf).String()
params, err := protojson.Marshal(&rvboxv1.RunCommandRequest{TargetClientId: "win-a", RequestId: requestID, Spec: &rvboxv1.ExecutionSpec{Source: &rvboxv1.ExecutionSpec_CommandText{CommandText: "echo rpc"}}})
if err != nil {
t.Fatal(err)
}
body, _ := json.Marshal(map[string]any{"jsonrpc": "2.0", "id": 7, "method": "runCommand", "params": json.RawMessage(params)})
response, err := http.Post(handler.URL, "application/json", bytes.NewReader(body))
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
encoded, _ := io.ReadAll(response.Body)
var envelope struct {
Result json.RawMessage `json:"result"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(encoded, &envelope); err != nil || len(envelope.Error) != 0 {
t.Fatalf("JSON-RPC response = %s, %v", encoded, err)
}
result := &rvboxv1.RunCommandResponse{}
if err := protojson.Unmarshal(envelope.Result, result); err != nil || result.GetIssueUuid() != requestID {
t.Fatalf("JSON-RPC result = %s, %v", envelope.Result, err)
}
unknown, _ := json.Marshal(map[string]any{"jsonrpc": "2.0", "id": "x", "method": "notARealMethod", "params": map[string]any{}})
unknownResponse, err := http.Post(handler.URL, "application/json", bytes.NewReader(unknown))
if err != nil {
t.Fatal(err)
}
defer unknownResponse.Body.Close()
unknownBody, _ := io.ReadAll(unknownResponse.Body)
if !bytes.Contains(unknownBody, []byte(`-32601`)) {
t.Fatalf("unknown method response = %s", unknownBody)
}
}
func TestJSONRPCRejectsOversizeAndMalformedRequests_BH_CTL_16(t *testing.T) {
persistence, err := store.Open(context.Background(), store.Options{DataDir: filepath.Join(t.TempDir(), "state"), BusyTimeout: time.Second})
if err != nil {
t.Fatal(err)
}
defer persistence.Close()
service, err := NewService(Options{Store: persistence, CursorKey: bytesKey()})
if err != nil {
t.Fatal(err)
}
handler := httptest.NewServer(NewJSONRPCHandler(service, 16))
defer handler.Close()
response, err := http.Post(handler.URL, "application/json", bytes.NewReader([]byte(`{"jsonrpc":"2.0","id":1,"method":"listClients","params":{}}`)))
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
if !bytes.Contains(body, []byte(`-32600`)) {
t.Fatalf("oversize response = %s", body)
}
malformed, err := http.Post(handler.URL, "application/json", bytes.NewReader([]byte(`{"jsonrpc":"2.0","id":1,"method":"listClients","params":{}}`[:16])))
if err != nil {
t.Fatal(err)
}
defer malformed.Body.Close()
malformedBody, _ := io.ReadAll(malformed.Body)
if !bytes.Contains(malformedBody, []byte(`-32700`)) {
t.Fatalf("malformed response = %s", malformedBody)
}
}
func FuzzDecodeJSONRPCRequestBounded_SEC_CTL_01(f *testing.F) {
f.Add([]byte(`{"jsonrpc":"2.0","id":1,"method":"listClients","params":{}}`))
f.Add([]byte(`{"jsonrpc":"2.0","id":null,"method":"listClients"}`))
f.Add([]byte(`{"jsonrpc":"2.0","id":1,"method":"listClients"}{}`))
f.Fuzz(func(t *testing.T, body []byte) {
// Keep fuzzing at the same independently enforced boundary as the
// production handler rather than allowing a corpus entry to allocate
// unbounded JSON decoder state.
if len(body) > 64<<10 {
return
}
_, _, _ = decodeJSONRPCRequest(body, 64<<10)
})
}