From 89f2f1adea5aefdee03342519fa9b2ff2a1682a4 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Wed, 17 Jun 2026 17:13:32 +0200 Subject: [PATCH] THRIFT-6071: Validate container size fits int32 range before narrowing conversion in TSimpleJSONProtocol Client: go Co-Authored-By: Claude Sonnet 4.6 --- lib/go/thrift/simple_json_protocol.go | 6 +++++ lib/go/thrift/simple_json_protocol_test.go | 29 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/go/thrift/simple_json_protocol.go b/lib/go/thrift/simple_json_protocol.go index 6ae3cba566..7239e2acba 100644 --- a/lib/go/thrift/simple_json_protocol.go +++ b/lib/go/thrift/simple_json_protocol.go @@ -1117,6 +1117,12 @@ func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e if err != nil { return elemType, 0, err } + if nSize > math.MaxInt32 { + return elemType, 0, NewTProtocolExceptionWithType( + SIZE_LIMIT, + fmt.Errorf("size exceeded max allowed: %d", nSize), + ) + } err = checkSizeForProtocol(int32(nSize), p.cfg) if err != nil { return elemType, 0, err diff --git a/lib/go/thrift/simple_json_protocol_test.go b/lib/go/thrift/simple_json_protocol_test.go index e7f2ac95a7..88dba7c881 100644 --- a/lib/go/thrift/simple_json_protocol_test.go +++ b/lib/go/thrift/simple_json_protocol_test.go @@ -832,3 +832,32 @@ func TestReadSimpleJSONProtocolMapBeginSizeOverflow(t *testing.T) { t.Errorf("expected SIZE_LIMIT, got %d: %v", tpe.TypeId(), err) } } + +func TestReadSimpleJSONProtocolListBeginSizeOverflow(t *testing.T) { + // nSize = 1<<32 + 1; int32 narrowing wraps it to 1, which would pass checkSizeForProtocol. + // The list header is written directly as raw JSON to avoid int-width issues on 32-bit platforms. + overflowSize := int64(math.MaxInt32)*2 + 3 // = 4294967297 = 1<<32 + 1 + for _, name := range []string{"list", "set"} { + t.Run(name, func(t *testing.T) { + buf := NewTMemoryBuffer() + buf.WriteString(fmt.Sprintf("[%d,%d]", I32, overflowSize)) + proto := NewTSimpleJSONProtocolConf(buf, &TConfiguration{MaxMessageSize: 1024}) + var err error + if name == "list" { + _, _, err = proto.ReadListBegin(context.Background()) + } else { + _, _, err = proto.ReadSetBegin(context.Background()) + } + if err == nil { + t.Fatal("expected error, got nil") + } + tpe, ok := err.(TProtocolException) + if !ok { + t.Fatalf("expected TProtocolException, got %T: %v", err, err) + } + if tpe.TypeId() != SIZE_LIMIT { + t.Errorf("expected SIZE_LIMIT, got %d: %v", tpe.TypeId(), err) + } + }) + } +}