From a9159d7f186bb55045473db3da05f12a1ff74178 Mon Sep 17 00:00:00 2001 From: dxbjavid Date: Wed, 17 Jun 2026 15:23:16 +0530 Subject: [PATCH 1/2] check wire-supplied size in simple json ReadMapBegin --- lib/go/thrift/simple_json_protocol.go | 2 +- lib/go/thrift/simple_json_protocol_test.go | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/go/thrift/simple_json_protocol.go b/lib/go/thrift/simple_json_protocol.go index ec12991a1d7..46384f8a11f 100644 --- a/lib/go/thrift/simple_json_protocol.go +++ b/lib/go/thrift/simple_json_protocol.go @@ -432,7 +432,7 @@ func (p *TSimpleJSONProtocol) ReadMapBegin(ctx context.Context) (keyType TType, if err != nil { return keyType, valueType, 0, err } - err = checkSizeForProtocol(int32(size), p.cfg) + err = checkSizeForProtocol(int32(iSize), p.cfg) if err != nil { return keyType, valueType, 0, err } diff --git a/lib/go/thrift/simple_json_protocol_test.go b/lib/go/thrift/simple_json_protocol_test.go index 18650989a00..c2370ab5691 100644 --- a/lib/go/thrift/simple_json_protocol_test.go +++ b/lib/go/thrift/simple_json_protocol_test.go @@ -791,3 +791,24 @@ func TestJSONContextStack(t *testing.T) { func TestTSimpleJSONProtocolUnmatchedBeginEnd(t *testing.T) { UnmatchedBeginEndProtocolTest(t, NewTSimpleJSONProtocolFactory()) } + +func TestReadSimpleJSONProtocolMapBeginSizeLimit(t *testing.T) { + ctx := context.Background() + trans := NewTMemoryBuffer() + wp := NewTSimpleJSONProtocol(trans) + if err := wp.WriteMapBegin(ctx, STRING, STRING, 1<<30); err != nil { + t.Fatal(err) + } + if err := wp.Flush(ctx); err != nil { + t.Fatal(err) + } + + rp := NewTSimpleJSONProtocolConf(trans, &TConfiguration{MaxMessageSize: 1024}) + _, _, size, err := rp.ReadMapBegin(ctx) + if err == nil { + t.Fatalf("expected size-limit error reading oversized map, got nil with size %d", size) + } + if terr, ok := err.(TProtocolException); !ok || terr.TypeId() != SIZE_LIMIT { + t.Errorf("expected SIZE_LIMIT protocol exception, got %v", err) + } +} From 495a4219d43598c6fd5a4d80af1c6275e1b9f9f8 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Wed, 17 Jun 2026 17:15:46 +0200 Subject: [PATCH 2/2] Validate map size fits int32 range before narrowing in ReadMapBegin Client: go Companion to THRIFT-6071 (same guard for ParseElemListBegin). Co-Authored-By: Claude Sonnet 4.6 --- lib/go/thrift/simple_json_protocol.go | 6 ++++++ lib/go/thrift/simple_json_protocol_test.go | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/go/thrift/simple_json_protocol.go b/lib/go/thrift/simple_json_protocol.go index 46384f8a11f..6ae3cba5662 100644 --- a/lib/go/thrift/simple_json_protocol.go +++ b/lib/go/thrift/simple_json_protocol.go @@ -432,6 +432,12 @@ func (p *TSimpleJSONProtocol) ReadMapBegin(ctx context.Context) (keyType TType, if err != nil { return keyType, valueType, 0, err } + if iSize > math.MaxInt32 { + return keyType, valueType, 0, NewTProtocolExceptionWithType( + SIZE_LIMIT, + fmt.Errorf("size exceeded max allowed: %d", iSize), + ) + } err = checkSizeForProtocol(int32(iSize), p.cfg) if err != nil { return keyType, valueType, 0, err diff --git a/lib/go/thrift/simple_json_protocol_test.go b/lib/go/thrift/simple_json_protocol_test.go index c2370ab5691..e7f2ac95a74 100644 --- a/lib/go/thrift/simple_json_protocol_test.go +++ b/lib/go/thrift/simple_json_protocol_test.go @@ -812,3 +812,23 @@ func TestReadSimpleJSONProtocolMapBeginSizeLimit(t *testing.T) { t.Errorf("expected SIZE_LIMIT protocol exception, got %v", err) } } + +func TestReadSimpleJSONProtocolMapBeginSizeOverflow(t *testing.T) { + // iSize = 1<<32 + 1; int32 narrowing wraps it to 1, which would pass checkSizeForProtocol. + // The map 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 + buf := NewTMemoryBuffer() + buf.WriteString(fmt.Sprintf("[%d,%d,%d]", I32, I32, overflowSize)) + proto := NewTSimpleJSONProtocolConf(buf, &TConfiguration{MaxMessageSize: 1024}) + _, _, _, err := proto.ReadMapBegin(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) + } +}