From 1056a6cdcaac2b57543435a1a065538ff7e9a1b6 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Mar 2026 22:40:54 +0530 Subject: [PATCH 01/11] added guardrails and their type Errors --- go/fory/buffer.go | 40 +++++++++++++++++++++++++++++++++------- go/fory/errors.go | 24 ++++++++++++++++++++++++ go/fory/fory.go | 44 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 97 insertions(+), 11 deletions(-) diff --git a/go/fory/buffer.go b/go/fory/buffer.go index c51071fd14..03d5fcfc65 100644 --- a/go/fory/buffer.go +++ b/go/fory/buffer.go @@ -26,11 +26,13 @@ import ( ) type ByteBuffer struct { - data []byte // Most accessed field first for cache locality - writerIndex int - readerIndex int - reader io.Reader - bufferSize int + data []byte // Most accessed field first for cache locality + writerIndex int + readerIndex int + reader io.Reader + bufferSize int + maxCollectionSize int + maxBinarySize int } func NewByteBuffer(data []byte) *ByteBuffer { @@ -196,8 +198,32 @@ func (b *ByteBuffer) WriteLength(value int) { b.WriteVarUint32(uint32(value)) } -func (b *ByteBuffer) ReadLength(err *Error) int { - return int(b.ReadVarUint32(err)) +func (b *ByteBuffer) ReadCollectionLength(err *Error) int { + length := int(b.ReadVarUint32(err)) + if err != nil && err.HasError() { + return 0 + } + if b.maxCollectionSize > 0 && length > b.maxCollectionSize { + if err != nil { + *err = MaxCollectionSizeExceededError(length, b.maxCollectionSize) + } + return 0 + } + return length +} + +func (b *ByteBuffer) ReadBinaryLength(err *Error) int { + length := int(b.ReadVarUint32(err)) + if err != nil && err.HasError() { + return 0 + } + if b.maxBinarySize > 0 && length > b.maxBinarySize { + if err != nil { + *err = MaxBinarySizeExceededError(length, b.maxBinarySize) + } + return 0 + } + return length } func (b *ByteBuffer) WriteUint64(value uint64) { diff --git a/go/fory/errors.go b/go/fory/errors.go index 25f7dd087a..6dc092bf2d 100644 --- a/go/fory/errors.go +++ b/go/fory/errors.go @@ -52,6 +52,10 @@ const ( ErrKindInvalidTag // ErrKindInvalidUTF16String indicates malformed UTF-16 string data ErrKindInvalidUTF16String + // ErrKindMaxCollectionSizeExceeded indicates max collection size exceeded + ErrKindMaxCollectionSizeExceeded + // ErrKindMaxBinarySizeExceeded indicates max binary size exceeded + ErrKindMaxBinarySizeExceeded ) // Error is a lightweight error type optimized for hot path performance. @@ -296,6 +300,26 @@ func InvalidUTF16StringError(byteCount int) Error { }) } +// MaxCollectionSizeExceededError creates a max collection size exceeded error +// +//go:noinline +func MaxCollectionSizeExceededError(size, limit int) Error { + return panicIfEnabled(Error{ + kind: ErrKindMaxCollectionSizeExceeded, + message: fmt.Sprintf("max collection size exceeded: size=%d, limit=%d", size, limit), + }) +} + +// MaxBinarySizeExceededError creates a max binary size exceeded error +// +//go:noinline +func MaxBinarySizeExceededError(size, limit int) Error { + return panicIfEnabled(Error{ + kind: ErrKindMaxBinarySizeExceeded, + message: fmt.Sprintf("max binary size exceeded: size=%d, limit=%d", size, limit), + }) +} + // WrapError wraps a standard error into a fory Error // //go:noinline diff --git a/go/fory/fory.go b/go/fory/fory.go index 342b0acc3a..7f2348ed6e 100644 --- a/go/fory/fory.go +++ b/go/fory/fory.go @@ -50,10 +50,12 @@ const ( // Config holds configuration options for Fory instances type Config struct { - TrackRef bool - MaxDepth int - IsXlang bool - Compatible bool // Schema evolution compatibility mode + TrackRef bool + MaxDepth int + IsXlang bool + Compatible bool // Schema evolution compatibility mode + MaxCollectionSize int + MaxBinarySize int } // defaultConfig returns the default configuration @@ -101,6 +103,20 @@ func WithCompatible(enabled bool) Option { } } +// WithMaxCollectionSize sets the maximum collection size limit +func WithMaxCollectionSize(size int) Option { + return func(f *Fory) { + f.config.MaxCollectionSize = size + } +} + +// WithMaxBinarySize sets the maximum binary size limit +func WithMaxBinarySize(size int) Option { + return func(f *Fory) { + f.config.MaxBinarySize = size + } +} + // ============================================================================ // Fory - Main serialization instance // ============================================================================ @@ -152,6 +168,8 @@ func New(opts ...Option) *Fory { f.writeCtx.xlang = f.config.IsXlang f.readCtx = NewReadContext(f.config.TrackRef) + f.readCtx.buffer.maxCollectionSize = f.config.MaxCollectionSize + f.readCtx.buffer.maxBinarySize = f.config.MaxBinarySize f.readCtx.typeResolver = f.typeResolver f.readCtx.refResolver = f.refResolver f.readCtx.compatible = f.config.Compatible @@ -490,6 +508,11 @@ func (f *Fory) Serialize(value any) ([]byte, error) { // The target must be a pointer to the value to deserialize into. func (f *Fory) Deserialize(data []byte, v any) error { defer f.resetReadState() + + // Apply Fory config guardrails + f.readCtx.buffer.maxCollectionSize = f.config.MaxCollectionSize + f.readCtx.buffer.maxBinarySize = f.config.MaxBinarySize + f.readCtx.SetData(data) isNull := readHeader(f.readCtx) @@ -592,6 +615,10 @@ func (f *Fory) DeserializeFrom(buf *ByteBuffer, v any) error { // Reset contexts for each independent serialized object defer f.resetReadState() + // Apply Fory config guardrails to the incoming buffer + buf.maxCollectionSize = f.config.MaxCollectionSize + buf.maxBinarySize = f.config.MaxBinarySize + // Temporarily swap buffer origBuffer := f.readCtx.buffer f.readCtx.buffer = buf @@ -686,6 +713,10 @@ func (f *Fory) SerializeWithCallback(buffer *ByteBuffer, v any, callback func(Bu // DeserializeWithCallbackBuffers deserializes from buffer into the provided value (for streaming/cross-language use). // The third parameter is optional external buffers for out-of-band data (can be nil). func (f *Fory) DeserializeWithCallbackBuffers(buffer *ByteBuffer, v any, buffers []*ByteBuffer) error { + // Apply Fory config guardrails to the incoming buffer + buffer.maxCollectionSize = f.config.MaxCollectionSize + buffer.maxBinarySize = f.config.MaxBinarySize + // Reset context and use the provided buffer f.readCtx.buffer = buffer defer func() { @@ -989,6 +1020,11 @@ func Serialize[T any](f *Fory, value T) ([]byte, error) { func Deserialize[T any](f *Fory, data []byte, target *T) error { // Reuse context, reset and set new data f.readCtx.Reset() + + // Apply Fory config guardrails + f.readCtx.buffer.maxCollectionSize = f.config.MaxCollectionSize + f.readCtx.buffer.maxBinarySize = f.config.MaxBinarySize + f.readCtx.SetData(data) // ReadData and validate header From a923301b30e23cc4cd935fe304f4476424bc64f4 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Mar 2026 22:58:15 +0530 Subject: [PATCH 02/11] added specific read path guardrails --- go/fory/reader.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/go/fory/reader.go b/go/fory/reader.go index a0a37d92fb..ab1a687d63 100644 --- a/go/fory/reader.go +++ b/go/fory/reader.go @@ -237,10 +237,16 @@ func (c *ReadContext) ReadAndValidateTypeId(expected TypeId) { } } -// ReadLength reads a length value as varint (non-negative values) -func (c *ReadContext) ReadLength() int { +// ReadCollectionLength reads a length value for collections with size guardrails +func (c *ReadContext) ReadCollectionLength() int { err := c.Err() - return int(c.buffer.ReadVarUint32(err)) + return c.buffer.ReadCollectionLength(err) +} + +// ReadBinaryLength reads a length value for binary arrays with size guardrails +func (c *ReadContext) ReadBinaryLength() int { + err := c.Err() + return c.buffer.ReadBinaryLength(err) } // ============================================================================ @@ -434,7 +440,7 @@ func (c *ReadContext) ReadByteSlice(refMode RefMode, readType bool) []byte { if readType { _ = c.buffer.ReadUint8(err) } - size := c.buffer.ReadLength(err) + size := c.buffer.ReadBinaryLength(err) return c.buffer.ReadBinary(size, err) } @@ -583,7 +589,7 @@ func (c *ReadContext) ReadBufferObject() *ByteBuffer { err := c.Err() isInBand := c.buffer.ReadBool(err) if isInBand { - size := c.buffer.ReadLength(err) + size := c.buffer.ReadBinaryLength(err) buf := c.buffer.Slice(c.buffer.readerIndex, size) c.buffer.readerIndex += size return buf From bda1ffff3541e8cb70eca8f70ea2d3cd4517a112 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Mar 2026 23:02:26 +0530 Subject: [PATCH 03/11] replaced ReadLength with specific read path gaurdrail --- go/fory/array.go | 2 +- go/fory/array_primitive.go | 26 +++++++++++++------------- go/fory/codegen/decoder.go | 20 ++++++++++---------- go/fory/map.go | 2 +- go/fory/map_primitive.go | 18 +++++++++--------- go/fory/set.go | 2 +- go/fory/skip.go | 14 +++++++------- go/fory/slice.go | 2 +- go/fory/slice_dyn.go | 2 +- go/fory/slice_primitive.go | 36 ++++++++++++++++++------------------ 10 files changed, 62 insertions(+), 62 deletions(-) diff --git a/go/fory/array.go b/go/fory/array.go index 9b8b9c17d3..92e5e67b91 100644 --- a/go/fory/array.go +++ b/go/fory/array.go @@ -366,7 +366,7 @@ func (s byteArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeType func (s byteArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - length := buf.ReadLength(err) + length := buf.ReadCollectionLength(err) if ctx.HasError() { return } diff --git a/go/fory/array_primitive.go b/go/fory/array_primitive.go index 27813060b7..afdf4d8179 100644 --- a/go/fory/array_primitive.go +++ b/go/fory/array_primitive.go @@ -66,7 +66,7 @@ func (s boolArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeType func (s boolArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - length := buf.ReadLength(err) + length := buf.ReadBinaryLength(err) if ctx.HasError() { return } @@ -131,7 +131,7 @@ func (s int8ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeType func (s int8ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - length := buf.ReadLength(err) + length := buf.ReadBinaryLength(err) if ctx.HasError() { return } @@ -197,7 +197,7 @@ func (s int16ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTyp func (s int16ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 2 if ctx.HasError() { return @@ -269,7 +269,7 @@ func (s int32ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTyp func (s int32ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 4 if ctx.HasError() { return @@ -341,7 +341,7 @@ func (s int64ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTyp func (s int64ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 8 if ctx.HasError() { return @@ -413,7 +413,7 @@ func (s float32ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeT func (s float32ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 4 if ctx.HasError() { return @@ -485,7 +485,7 @@ func (s float64ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeT func (s float64ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 8 if ctx.HasError() { return @@ -556,7 +556,7 @@ func (s uint8ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTyp func (s uint8ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - length := buf.ReadLength(err) + length := buf.ReadBinaryLength(err) if ctx.HasError() { return } @@ -623,7 +623,7 @@ func (s uint16ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTy func (s uint16ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 2 if ctx.HasError() { return @@ -694,7 +694,7 @@ func (s uint32ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTy func (s uint32ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 4 if ctx.HasError() { return @@ -764,7 +764,7 @@ func (s uint64ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTy func (s uint64ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 8 if ctx.HasError() { return @@ -838,7 +838,7 @@ func (s float16ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeT func (s float16ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - size := buf.ReadLength(ctxErr) + size := buf.ReadBinaryLength(ctxErr) length := size / 2 if ctx.HasError() { return @@ -912,7 +912,7 @@ func (s bfloat16ArraySerializer) Write(ctx *WriteContext, refMode RefMode, write func (s bfloat16ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - size := buf.ReadLength(ctxErr) + size := buf.ReadBinaryLength(ctxErr) length := size / 2 if ctx.HasError() { return diff --git a/go/fory/codegen/decoder.go b/go/fory/codegen/decoder.go index d3713a2433..3024a7c7ca 100644 --- a/go/fory/codegen/decoder.go +++ b/go/fory/codegen/decoder.go @@ -168,7 +168,7 @@ func generateFieldReadTyped(buf *bytes.Buffer, field *FieldInfo) error { fmt.Fprintf(buf, "\t\tisXlang := ctx.TypeResolver().IsXlang()\n") fmt.Fprintf(buf, "\t\tif isXlang {\n") fmt.Fprintf(buf, "\t\t\t// xlang mode: slices are not nullable, read directly without null flag\n") - fmt.Fprintf(buf, "\t\t\tsliceLen := int(buf.ReadVarUint32(err))\n") + fmt.Fprintf(buf, "\t\t\tsliceLen := buf.ReadCollectionLength(err)\n") fmt.Fprintf(buf, "\t\t\tif sliceLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t%s = make([]any, 0)\n", fieldAccess) fmt.Fprintf(buf, "\t\t\t} else {\n") @@ -187,7 +187,7 @@ func generateFieldReadTyped(buf *bytes.Buffer, field *FieldInfo) error { fmt.Fprintf(buf, "\t\t\tif nullFlag == -3 {\n") // NullFlag fmt.Fprintf(buf, "\t\t\t\t%s = nil\n", fieldAccess) fmt.Fprintf(buf, "\t\t\t} else {\n") - fmt.Fprintf(buf, "\t\t\t\tsliceLen := int(buf.ReadVarUint32(err))\n") + fmt.Fprintf(buf, "\t\t\t\tsliceLen := buf.ReadCollectionLength(err)\n") fmt.Fprintf(buf, "\t\t\t\tif sliceLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t\t%s = make([]any, 0)\n", fieldAccess) fmt.Fprintf(buf, "\t\t\t\t} else {\n") @@ -517,7 +517,7 @@ func generateSliceReadInline(buf *bytes.Buffer, sliceType *types.Slice, fieldAcc fmt.Fprintf(buf, "\t\tisXlang := ctx.TypeResolver().IsXlang()\n") fmt.Fprintf(buf, "\t\tif isXlang {\n") fmt.Fprintf(buf, "\t\t\t// xlang mode: slices are not nullable, read directly without null flag\n") - fmt.Fprintf(buf, "\t\t\tsliceLen := int(buf.ReadVarUint32(err))\n") + fmt.Fprintf(buf, "\t\t\tsliceLen := buf.ReadCollectionLength(err)\n") fmt.Fprintf(buf, "\t\t\tif sliceLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t%s = make(%s, 0)\n", fieldAccess, sliceType.String()) fmt.Fprintf(buf, "\t\t\t} else {\n") @@ -532,7 +532,7 @@ func generateSliceReadInline(buf *bytes.Buffer, sliceType *types.Slice, fieldAcc fmt.Fprintf(buf, "\t\t\tif nullFlag == -3 {\n") // NullFlag fmt.Fprintf(buf, "\t\t\t\t%s = nil\n", fieldAccess) fmt.Fprintf(buf, "\t\t\t} else {\n") - fmt.Fprintf(buf, "\t\t\t\tsliceLen := int(buf.ReadVarUint32(err))\n") + fmt.Fprintf(buf, "\t\t\t\tsliceLen := buf.ReadCollectionLength(err)\n") fmt.Fprintf(buf, "\t\t\t\tif sliceLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t\t%s = make(%s, 0)\n", fieldAccess, sliceType.String()) fmt.Fprintf(buf, "\t\t\t\t} else {\n") @@ -555,7 +555,7 @@ func generateSliceReadInlineNoNull(buf *bytes.Buffer, sliceType *types.Slice, fi unwrappedElem := types.Unalias(elemType) if iface, ok := unwrappedElem.(*types.Interface); ok && iface.Empty() { fmt.Fprintf(buf, "%s// Dynamic slice []any handling - no null flag\n", indent) - fmt.Fprintf(buf, "%ssliceLen := int(buf.ReadVarUint32(err))\n", indent) + fmt.Fprintf(buf, "%ssliceLen := buf.ReadCollectionLength(err)\n", indent) fmt.Fprintf(buf, "%sif sliceLen == 0 {\n", indent) fmt.Fprintf(buf, "%s\t%s = make([]any, 0)\n", indent, fieldAccess) fmt.Fprintf(buf, "%s} else {\n", indent) @@ -573,7 +573,7 @@ func generateSliceReadInlineNoNull(buf *bytes.Buffer, sliceType *types.Slice, fi } elemIsReferencable := isReferencableType(elemType) - fmt.Fprintf(buf, "%ssliceLen := int(buf.ReadVarUint32(err))\n", indent) + fmt.Fprintf(buf, "%ssliceLen := buf.ReadCollectionLength(err)\n", indent) fmt.Fprintf(buf, "%sif sliceLen == 0 {\n", indent) fmt.Fprintf(buf, "%s\t%s = make(%s, 0)\n", indent, fieldAccess, sliceType.String()) fmt.Fprintf(buf, "%s} else {\n", indent) @@ -703,7 +703,7 @@ func writePrimitiveSliceReadCall(buf *bytes.Buffer, basic *types.Basic, fieldAcc case types.Int8: fmt.Fprintf(buf, "%s%s = fory.ReadInt8Slice(buf, err)\n", indent, fieldAccess) case types.Uint8: - fmt.Fprintf(buf, "%ssizeBytes := buf.ReadLength(err)\n", indent) + fmt.Fprintf(buf, "%ssizeBytes := buf.ReadBinaryLength(err)\n", indent) fmt.Fprintf(buf, "%s%s = make([]uint8, sizeBytes)\n", indent, fieldAccess) fmt.Fprintf(buf, "%sif sizeBytes > 0 {\n", indent) fmt.Fprintf(buf, "%s\traw := buf.ReadBinary(sizeBytes, err)\n", indent) @@ -925,7 +925,7 @@ func generateMapReadInline(buf *bytes.Buffer, mapType *types.Map, fieldAccess st fmt.Fprintf(buf, "\t\tisXlang := ctx.TypeResolver().IsXlang()\n") fmt.Fprintf(buf, "\t\tif isXlang {\n") fmt.Fprintf(buf, "\t\t\t// xlang mode: maps are not nullable, read directly without null flag\n") - fmt.Fprintf(buf, "\t\t\tmapLen := int(buf.ReadVarUint32(err))\n") + fmt.Fprintf(buf, "\t\t\tmapLen := buf.ReadCollectionLength(err)\n") fmt.Fprintf(buf, "\t\t\tif mapLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t%s = make(%s)\n", fieldAccess, mapType.String()) fmt.Fprintf(buf, "\t\t\t} else {\n") @@ -940,7 +940,7 @@ func generateMapReadInline(buf *bytes.Buffer, mapType *types.Map, fieldAccess st fmt.Fprintf(buf, "\t\t\tif nullFlag == -3 {\n") // NullFlag fmt.Fprintf(buf, "\t\t\t\t%s = nil\n", fieldAccess) fmt.Fprintf(buf, "\t\t\t} else {\n") - fmt.Fprintf(buf, "\t\t\t\tmapLen := int(buf.ReadVarUint32(err))\n") + fmt.Fprintf(buf, "\t\t\t\tmapLen := buf.ReadCollectionLength(err)\n") fmt.Fprintf(buf, "\t\t\t\tif mapLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t\t%s = make(%s)\n", fieldAccess, mapType.String()) fmt.Fprintf(buf, "\t\t\t\t} else {\n") @@ -972,7 +972,7 @@ func generateMapReadInlineNoNull(buf *bytes.Buffer, mapType *types.Map, fieldAcc } indent := "\t\t\t" - fmt.Fprintf(buf, "%smapLen := int(buf.ReadVarUint32(err))\n", indent) + fmt.Fprintf(buf, "%smapLen := buf.ReadCollectionLength(err)\n", indent) fmt.Fprintf(buf, "%sif mapLen == 0 {\n", indent) fmt.Fprintf(buf, "%s\t%s = make(%s)\n", indent, fieldAccess, mapType.String()) fmt.Fprintf(buf, "%s} else {\n", indent) diff --git a/go/fory/map.go b/go/fory/map.go index f2489601f3..a26c43bafd 100644 --- a/go/fory/map.go +++ b/go/fory/map.go @@ -305,7 +305,7 @@ func (s mapSerializer) ReadData(ctx *ReadContext, value reflect.Value) { } refResolver.Reference(value) - size := int(buf.ReadVarUint32(ctxErr)) + size := buf.ReadCollectionLength(ctxErr) if size == 0 || ctx.HasError() { return } diff --git a/go/fory/map_primitive.go b/go/fory/map_primitive.go index 21a4bd7b5d..79622c89d2 100644 --- a/go/fory/map_primitive.go +++ b/go/fory/map_primitive.go @@ -70,7 +70,7 @@ func writeMapStringString(buf *ByteBuffer, m map[string]string, hasGenerics bool // readMapStringString reads map[string]string using chunk protocol func readMapStringString(buf *ByteBuffer, err *Error) map[string]string { - size := int(buf.ReadVarUint32(err)) + size := buf.ReadCollectionLength(err) result := make(map[string]string, size) if size == 0 { return result @@ -173,7 +173,7 @@ func writeMapStringInt64(buf *ByteBuffer, m map[string]int64, hasGenerics bool) // readMapStringInt64 reads map[string]int64 using chunk protocol func readMapStringInt64(buf *ByteBuffer, err *Error) map[string]int64 { - size := int(buf.ReadVarUint32(err)) + size := buf.ReadCollectionLength(err) result := make(map[string]int64, size) if size == 0 { return result @@ -247,7 +247,7 @@ func writeMapStringInt32(buf *ByteBuffer, m map[string]int32, hasGenerics bool) // readMapStringInt32 reads map[string]int32 using chunk protocol func readMapStringInt32(buf *ByteBuffer, err *Error) map[string]int32 { - size := int(buf.ReadVarUint32(err)) + size := buf.ReadCollectionLength(err) result := make(map[string]int32, size) if size == 0 { return result @@ -321,7 +321,7 @@ func writeMapStringInt(buf *ByteBuffer, m map[string]int, hasGenerics bool) { // readMapStringInt reads map[string]int using chunk protocol func readMapStringInt(buf *ByteBuffer, err *Error) map[string]int { - size := int(buf.ReadVarUint32(err)) + size := buf.ReadCollectionLength(err) result := make(map[string]int, size) if size == 0 { return result @@ -395,7 +395,7 @@ func writeMapStringFloat64(buf *ByteBuffer, m map[string]float64, hasGenerics bo // readMapStringFloat64 reads map[string]float64 using chunk protocol func readMapStringFloat64(buf *ByteBuffer, err *Error) map[string]float64 { - size := int(buf.ReadVarUint32(err)) + size := buf.ReadCollectionLength(err) result := make(map[string]float64, size) if size == 0 { return result @@ -469,7 +469,7 @@ func writeMapStringBool(buf *ByteBuffer, m map[string]bool, hasGenerics bool) { // readMapStringBool reads map[string]bool using chunk protocol func readMapStringBool(buf *ByteBuffer, err *Error) map[string]bool { - size := int(buf.ReadVarUint32(err)) + size := buf.ReadCollectionLength(err) result := make(map[string]bool, size) if size == 0 { return result @@ -548,7 +548,7 @@ func writeMapInt32Int32(buf *ByteBuffer, m map[int32]int32, hasGenerics bool) { // readMapInt32Int32 reads map[int32]int32 using chunk protocol func readMapInt32Int32(buf *ByteBuffer, err *Error) map[int32]int32 { - size := int(buf.ReadVarUint32(err)) + size := buf.ReadCollectionLength(err) result := make(map[int32]int32, size) if size == 0 { return result @@ -622,7 +622,7 @@ func writeMapInt64Int64(buf *ByteBuffer, m map[int64]int64, hasGenerics bool) { // readMapInt64Int64 reads map[int64]int64 using chunk protocol func readMapInt64Int64(buf *ByteBuffer, err *Error) map[int64]int64 { - size := int(buf.ReadVarUint32(err)) + size := buf.ReadCollectionLength(err) result := make(map[int64]int64, size) if size == 0 { return result @@ -696,7 +696,7 @@ func writeMapIntInt(buf *ByteBuffer, m map[int]int, hasGenerics bool) { // readMapIntInt reads map[int]int using chunk protocol func readMapIntInt(buf *ByteBuffer, err *Error) map[int]int { - size := int(buf.ReadVarUint32(err)) + size := buf.ReadCollectionLength(err) result := make(map[int]int, size) if size == 0 { return result diff --git a/go/fory/set.go b/go/fory/set.go index 2105b3e9df..d6477457f8 100644 --- a/go/fory/set.go +++ b/go/fory/set.go @@ -295,7 +295,7 @@ func (s setSerializer) ReadData(ctx *ReadContext, value reflect.Value) { err := ctx.Err() type_ := value.Type() // ReadData collection length from buffer - length := int(buf.ReadVarUint32(err)) + length := buf.ReadCollectionLength(err) if length == 0 { // Initialize empty set if length is 0 value.Set(reflect.MakeMap(type_)) diff --git a/go/fory/skip.go b/go/fory/skip.go index 34005ad74d..d524c2af35 100644 --- a/go/fory/skip.go +++ b/go/fory/skip.go @@ -213,7 +213,7 @@ func readTypeInfoForSkip(ctx *ReadContext, fieldTypeId TypeId) *TypeInfo { // Uses context error state for deferred error checking. func skipCollection(ctx *ReadContext, fieldDef FieldDef) { err := ctx.Err() - length := ctx.buffer.ReadVarUint32(err) + length := uint32(ctx.buffer.ReadCollectionLength(err)) if ctx.HasError() || length == 0 { return } @@ -283,7 +283,7 @@ func skipCollection(ctx *ReadContext, fieldDef FieldDef) { // Uses context error state for deferred error checking. func skipMap(ctx *ReadContext, fieldDef FieldDef) { bufErr := ctx.Err() - length := ctx.buffer.ReadVarUint32(bufErr) + length := uint32(ctx.buffer.ReadCollectionLength(bufErr)) if ctx.HasError() || length == 0 { return } @@ -601,31 +601,31 @@ func skipValue(ctx *ReadContext, fieldDef FieldDef, readRefFlag bool, isField bo _ = ctx.buffer.ReadBinary(int(size), err) } case BINARY: - length := ctx.buffer.ReadVarUint32(err) + length := uint32(ctx.buffer.ReadBinaryLength(err)) if ctx.HasError() { return } _ = ctx.buffer.ReadBinary(int(length), err) case BOOL_ARRAY, INT8_ARRAY, UINT8_ARRAY: - length := ctx.buffer.ReadLength(err) + length := ctx.buffer.ReadBinaryLength(err) if ctx.HasError() { return } _ = ctx.buffer.ReadBinary(length, err) case INT16_ARRAY, UINT16_ARRAY, FLOAT16_ARRAY, BFLOAT16_ARRAY: - length := ctx.buffer.ReadLength(err) + length := ctx.buffer.ReadBinaryLength(err) if ctx.HasError() { return } _ = ctx.buffer.ReadBinary(length*2, err) case INT32_ARRAY, UINT32_ARRAY, FLOAT32_ARRAY: - length := ctx.buffer.ReadLength(err) + length := ctx.buffer.ReadBinaryLength(err) if ctx.HasError() { return } _ = ctx.buffer.ReadBinary(length*4, err) case INT64_ARRAY, UINT64_ARRAY, FLOAT64_ARRAY: - length := ctx.buffer.ReadLength(err) + length := ctx.buffer.ReadBinaryLength(err) if ctx.HasError() { return } diff --git a/go/fory/slice.go b/go/fory/slice.go index bd3a9aa7ee..a292fe0ae4 100644 --- a/go/fory/slice.go +++ b/go/fory/slice.go @@ -264,7 +264,7 @@ func (s *sliceSerializer) ReadWithTypeInfo(ctx *ReadContext, refMode RefMode, ty func (s *sliceSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - length := int(buf.ReadVarUint32(ctxErr)) + length := buf.ReadCollectionLength(ctxErr) isArrayType := value.Type().Kind() == reflect.Array if length == 0 { diff --git a/go/fory/slice_dyn.go b/go/fory/slice_dyn.go index 3393d4b22b..7c5b149d25 100644 --- a/go/fory/slice_dyn.go +++ b/go/fory/slice_dyn.go @@ -261,7 +261,7 @@ func (s sliceDynSerializer) Read(ctx *ReadContext, refMode RefMode, readType boo func (s sliceDynSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - length := int(buf.ReadVarUint32(ctxErr)) + length := buf.ReadCollectionLength(ctxErr) sliceType := value.Type() value.Set(reflect.MakeSlice(sliceType, length, length)) if length == 0 { diff --git a/go/fory/slice_primitive.go b/go/fory/slice_primitive.go index c893908987..a6236964f1 100644 --- a/go/fory/slice_primitive.go +++ b/go/fory/slice_primitive.go @@ -74,7 +74,7 @@ func (s byteSliceSerializer) ReadWithTypeInfo(ctx *ReadContext, refMode RefMode, func (s byteSliceSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - length := buf.ReadLength(ctxErr) + length := buf.ReadBinaryLength(ctxErr) ptr := (*[]byte)(value.Addr().UnsafePointer()) if length == 0 { *ptr = make([]byte, 0) @@ -642,7 +642,7 @@ func (s stringSliceSerializer) ReadWithTypeInfo(ctx *ReadContext, refMode RefMod func (s stringSliceSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - length := int(buf.ReadVarUint32(ctxErr)) + length := buf.ReadCollectionLength(ctxErr) ptr := (*[]string)(value.Addr().UnsafePointer()) if length == 0 { *ptr = make([]string, 0) @@ -691,7 +691,7 @@ func WriteByteSlice(buf *ByteBuffer, value []byte) { // ReadByteSlice reads []byte from buffer using ARRAY protocol func ReadByteSlice(buf *ByteBuffer, err *Error) []byte { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) if size == 0 { return make([]byte, 0) } @@ -712,7 +712,7 @@ func WriteBoolSlice(buf *ByteBuffer, value []bool) { // ReadBoolSlice reads []bool from buffer using ARRAY protocol func ReadBoolSlice(buf *ByteBuffer, err *Error) []bool { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) if size == 0 { return make([]bool, 0) } @@ -733,7 +733,7 @@ func WriteInt8Slice(buf *ByteBuffer, value []int8) { // ReadInt8Slice reads []int8 from buffer using ARRAY protocol func ReadInt8Slice(buf *ByteBuffer, err *Error) []int8 { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) if size == 0 { return make([]int8, 0) } @@ -760,7 +760,7 @@ func WriteInt16Slice(buf *ByteBuffer, value []int16) { // ReadInt16Slice reads []int16 from buffer using ARRAY protocol func ReadInt16Slice(buf *ByteBuffer, err *Error) []int16 { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 2 if length == 0 { return make([]int16, 0) @@ -794,7 +794,7 @@ func WriteInt32Slice(buf *ByteBuffer, value []int32) { // ReadInt32Slice reads []int32 from buffer using ARRAY protocol func ReadInt32Slice(buf *ByteBuffer, err *Error) []int32 { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 4 if length == 0 { return make([]int32, 0) @@ -828,7 +828,7 @@ func WriteInt64Slice(buf *ByteBuffer, value []int64) { // ReadInt64Slice reads []int64 from buffer using ARRAY protocol func ReadInt64Slice(buf *ByteBuffer, err *Error) []int64 { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 8 if length == 0 { return make([]int64, 0) @@ -862,7 +862,7 @@ func WriteUint16Slice(buf *ByteBuffer, value []uint16) { // ReadUint16Slice reads []uint16 from buffer using ARRAY protocol func ReadUint16Slice(buf *ByteBuffer, err *Error) []uint16 { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 2 if length == 0 { return make([]uint16, 0) @@ -896,7 +896,7 @@ func WriteUint32Slice(buf *ByteBuffer, value []uint32) { // ReadUint32Slice reads []uint32 from buffer using ARRAY protocol func ReadUint32Slice(buf *ByteBuffer, err *Error) []uint32 { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 4 if length == 0 { return make([]uint32, 0) @@ -930,7 +930,7 @@ func WriteUint64Slice(buf *ByteBuffer, value []uint64) { // ReadUint64Slice reads []uint64 from buffer using ARRAY protocol func ReadUint64Slice(buf *ByteBuffer, err *Error) []uint64 { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 8 if length == 0 { return make([]uint64, 0) @@ -964,7 +964,7 @@ func WriteFloat32Slice(buf *ByteBuffer, value []float32) { // ReadFloat32Slice reads []float32 from buffer using ARRAY protocol func ReadFloat32Slice(buf *ByteBuffer, err *Error) []float32 { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 4 if length == 0 { return make([]float32, 0) @@ -998,7 +998,7 @@ func WriteFloat64Slice(buf *ByteBuffer, value []float64) { // ReadFloat64Slice reads []float64 from buffer using ARRAY protocol func ReadFloat64Slice(buf *ByteBuffer, err *Error) []float64 { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) length := size / 8 if length == 0 { return make([]float64, 0) @@ -1071,7 +1071,7 @@ func (s float16SliceSerializer) ReadWithTypeInfo(ctx *ReadContext, refMode RefMo func (s float16SliceSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - size := buf.ReadLength(ctxErr) + size := buf.ReadBinaryLength(ctxErr) length := size / 2 if ctx.HasError() { return @@ -1131,7 +1131,7 @@ func WriteIntSlice(buf *ByteBuffer, value []int) { // ReadIntSlice reads []int from buffer using ARRAY protocol func ReadIntSlice(buf *ByteBuffer, err *Error) []int { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) if strconv.IntSize == 64 { length := size / 8 if length == 0 { @@ -1196,7 +1196,7 @@ func WriteUintSlice(buf *ByteBuffer, value []uint) { // ReadUintSlice reads []uint from buffer using ARRAY protocol func ReadUintSlice(buf *ByteBuffer, err *Error) []uint { - size := buf.ReadLength(err) + size := buf.ReadBinaryLength(err) if strconv.IntSize == 64 { length := size / 8 if length == 0 { @@ -1253,7 +1253,7 @@ func WriteStringSlice(buf *ByteBuffer, value []string, hasGenerics bool) { // ReadStringSlice reads []string from buffer using LIST protocol func ReadStringSlice(buf *ByteBuffer, err *Error) []string { - length := int(buf.ReadVarUint32(err)) + length := buf.ReadCollectionLength(err) if length == 0 { return make([]string, 0) } @@ -1328,7 +1328,7 @@ func (s bfloat16SliceSerializer) ReadWithTypeInfo(ctx *ReadContext, refMode RefM func (s bfloat16SliceSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - size := buf.ReadLength(ctxErr) + size := buf.ReadBinaryLength(ctxErr) length := size / 2 if ctx.HasError() { return From dc4086133ccb3b6f21aae9d22ab856a771d3e692 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Mar 2026 23:03:10 +0530 Subject: [PATCH 04/11] added test suites --- go/fory/limit_test.go | 86 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 go/fory/limit_test.go diff --git a/go/fory/limit_test.go b/go/fory/limit_test.go new file mode 100644 index 0000000000..a4c3759fdf --- /dev/null +++ b/go/fory/limit_test.go @@ -0,0 +1,86 @@ +package fory + +import ( + "testing" + "github.com/stretchr/testify/require" +) + +func TestMaxCollectionSizeGuardrail(t *testing.T) { + // 1. Test slice exceeding limit + t.Run("Slice exceeds MaxCollectionSize", func(t *testing.T) { + config := WithMaxCollectionSize(2) + f := NewFory(config) + + slice := []string{"a", "b", "c"} + fBase := NewFory() + bytes, _ := fBase.Serialize(slice) + + var decoded []string + err := f.Deserialize(bytes, &decoded) + require.Error(t, err) + require.Contains(t, err.Error(), "max collection size exceeded: size=3, limit=2") + }) + + // 2. Test map exceeding limit + t.Run("Map exceeds MaxCollectionSize", func(t *testing.T) { + config := WithMaxCollectionSize(2) + f := NewFory(config) + + m := map[int32]int32{1: 1, 2: 2, 3: 3} + fBase := NewFory() + bytes, _ := fBase.Serialize(m) + + var decoded map[int32]int32 + err := f.Deserialize(bytes, &decoded) + require.Error(t, err) + require.Contains(t, err.Error(), "max collection size exceeded: size=3, limit=2") + }) + + // 3. Test string is not affected by MaxCollectionSize + t.Run("String unaffected by MaxCollectionSize", func(t *testing.T) { + config := WithMaxCollectionSize(2) + f := NewFory(config) + + str := "hello world" // length 11 + bytes, err := f.Serialize(str) + require.NoError(t, err) + + var decoded string + err = f.Deserialize(bytes, &decoded) + require.NoError(t, err) + require.Equal(t, str, decoded) + }) +} + +func TestMaxBinarySizeGuardrail(t *testing.T) { + // 1. Test binary (byte slice) exceeding limit + t.Run("Byte slice exceeds MaxBinarySize", func(t *testing.T) { + config := WithMaxBinarySize(5) + f := NewFory(config) + + // We can serialize a byte slice using standard serializer, then decode with the f instance + slice := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + fBase := NewFory() + bytes, _ := fBase.Serialize(slice) + + var decoded []byte + err := f.Deserialize(bytes, &decoded) + require.Error(t, err) + require.Contains(t, err.Error(), "max binary size exceeded: size=10, limit=5") + }) + + // 2. Test string is not affected by MaxBinarySize + t.Run("String unaffected by MaxBinarySize", func(t *testing.T) { + config := WithMaxBinarySize(2) + f := NewFory(config) + + str := "hello world" // length 11 + bytes, err := f.Serialize(str) + require.NoError(t, err) + + var decoded string + err = f.Deserialize(bytes, &decoded) + require.NoError(t, err) + require.Equal(t, str, decoded) + }) +} From 98f9085b4c5b05d9b7c5cf3e46c52f29a447e414 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Mar 2026 23:11:39 +0530 Subject: [PATCH 05/11] added asf license --- go/fory/limit_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/go/fory/limit_test.go b/go/fory/limit_test.go index a4c3759fdf..f905dfe3b6 100644 --- a/go/fory/limit_test.go +++ b/go/fory/limit_test.go @@ -1,3 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + package fory import ( From 5743bbba00f6b904bdd35fdd8dc6ebbf16c3d864 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Mar 2026 23:20:41 +0530 Subject: [PATCH 06/11] lint fixes --- go/fory/fory.go | 8 ++++---- go/fory/limit_test.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/fory/fory.go b/go/fory/fory.go index 7f2348ed6e..567b2310ab 100644 --- a/go/fory/fory.go +++ b/go/fory/fory.go @@ -508,11 +508,11 @@ func (f *Fory) Serialize(value any) ([]byte, error) { // The target must be a pointer to the value to deserialize into. func (f *Fory) Deserialize(data []byte, v any) error { defer f.resetReadState() - + // Apply Fory config guardrails f.readCtx.buffer.maxCollectionSize = f.config.MaxCollectionSize f.readCtx.buffer.maxBinarySize = f.config.MaxBinarySize - + f.readCtx.SetData(data) isNull := readHeader(f.readCtx) @@ -1020,11 +1020,11 @@ func Serialize[T any](f *Fory, value T) ([]byte, error) { func Deserialize[T any](f *Fory, data []byte, target *T) error { // Reuse context, reset and set new data f.readCtx.Reset() - + // Apply Fory config guardrails f.readCtx.buffer.maxCollectionSize = f.config.MaxCollectionSize f.readCtx.buffer.maxBinarySize = f.config.MaxBinarySize - + f.readCtx.SetData(data) // ReadData and validate header diff --git a/go/fory/limit_test.go b/go/fory/limit_test.go index f905dfe3b6..64d32f7a3d 100644 --- a/go/fory/limit_test.go +++ b/go/fory/limit_test.go @@ -18,8 +18,8 @@ package fory import ( - "testing" "github.com/stretchr/testify/require" + "testing" ) func TestMaxCollectionSizeGuardrail(t *testing.T) { @@ -77,7 +77,7 @@ func TestMaxBinarySizeGuardrail(t *testing.T) { // We can serialize a byte slice using standard serializer, then decode with the f instance slice := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - fBase := NewFory() + fBase := NewFory() bytes, _ := fBase.Serialize(slice) var decoded []byte From 0c0def52a4cdfda03489fa59f2f57d20a88ea3b5 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Wed, 18 Mar 2026 16:25:04 +0530 Subject: [PATCH 07/11] fix: moved semantics from bytebuffer to readcontext --- go/fory/array.go | 4 +-- go/fory/buffer.go | 40 +++++-------------------- go/fory/reader.go | 74 +++++++++++++++++++++++++++++------------------ 3 files changed, 55 insertions(+), 63 deletions(-) diff --git a/go/fory/array.go b/go/fory/array.go index 92e5e67b91..44b26b1090 100644 --- a/go/fory/array.go +++ b/go/fory/array.go @@ -365,8 +365,8 @@ func (s byteArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeType func (s byteArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() - err := ctx.Err() - length := buf.ReadCollectionLength(err) + _ = ctx.Err() + length := ctx.ReadCollectionLength() if ctx.HasError() { return } diff --git a/go/fory/buffer.go b/go/fory/buffer.go index 03d5fcfc65..c51071fd14 100644 --- a/go/fory/buffer.go +++ b/go/fory/buffer.go @@ -26,13 +26,11 @@ import ( ) type ByteBuffer struct { - data []byte // Most accessed field first for cache locality - writerIndex int - readerIndex int - reader io.Reader - bufferSize int - maxCollectionSize int - maxBinarySize int + data []byte // Most accessed field first for cache locality + writerIndex int + readerIndex int + reader io.Reader + bufferSize int } func NewByteBuffer(data []byte) *ByteBuffer { @@ -198,32 +196,8 @@ func (b *ByteBuffer) WriteLength(value int) { b.WriteVarUint32(uint32(value)) } -func (b *ByteBuffer) ReadCollectionLength(err *Error) int { - length := int(b.ReadVarUint32(err)) - if err != nil && err.HasError() { - return 0 - } - if b.maxCollectionSize > 0 && length > b.maxCollectionSize { - if err != nil { - *err = MaxCollectionSizeExceededError(length, b.maxCollectionSize) - } - return 0 - } - return length -} - -func (b *ByteBuffer) ReadBinaryLength(err *Error) int { - length := int(b.ReadVarUint32(err)) - if err != nil && err.HasError() { - return 0 - } - if b.maxBinarySize > 0 && length > b.maxBinarySize { - if err != nil { - *err = MaxBinarySizeExceededError(length, b.maxBinarySize) - } - return 0 - } - return length +func (b *ByteBuffer) ReadLength(err *Error) int { + return int(b.ReadVarUint32(err)) } func (b *ByteBuffer) WriteUint64(value uint64) { diff --git a/go/fory/reader.go b/go/fory/reader.go index ab1a687d63..ceacc9f0f8 100644 --- a/go/fory/reader.go +++ b/go/fory/reader.go @@ -29,20 +29,22 @@ import ( // ReadContext holds all state needed during deserialization. type ReadContext struct { - buffer *ByteBuffer - refReader *RefReader - trackRef bool // Cached flag to avoid indirection - xlang bool // Cross-language serialization mode - compatible bool // Schema evolution compatibility mode - typeResolver *TypeResolver // For complex type deserialization - refResolver *RefResolver // For reference tracking (legacy) - outOfBandBuffers []*ByteBuffer // Out-of-band buffers for deserialization - outOfBandIndex int // Current index into out-of-band buffers - depth int // Current nesting depth for cycle detection - maxDepth int // Maximum allowed nesting depth - err Error // Accumulated error state for deferred checking - lastTypePtr uintptr - lastTypeInfo *TypeInfo + buffer *ByteBuffer + refReader *RefReader + trackRef bool // Cached flag to avoid indirection + xlang bool // Cross-language serialization mode + compatible bool // Schema evolution compatibility mode + typeResolver *TypeResolver // For complex type deserialization + refResolver *RefResolver // For reference tracking (legacy) + outOfBandBuffers []*ByteBuffer // Out-of-band buffers for deserialization + outOfBandIndex int // Current index into out-of-band buffers + depth int // Current nesting depth for cycle detection + maxDepth int // Maximum allowed nesting depth + err Error // Accumulated error state for deferred checking + lastTypePtr uintptr + lastTypeInfo *TypeInfo + maxCollectionSize int // Size guardrail for collection reads + maxBinarySize int // Size guardrail for binary reads } // IsXlang returns whether cross-language serialization mode is enabled @@ -240,13 +242,29 @@ func (c *ReadContext) ReadAndValidateTypeId(expected TypeId) { // ReadCollectionLength reads a length value for collections with size guardrails func (c *ReadContext) ReadCollectionLength() int { err := c.Err() - return c.buffer.ReadCollectionLength(err) + length := c.buffer.ReadLength(err) + if c.err.HasError() { + return 0 + } + if c.maxCollectionSize > 0 && length > c.maxCollectionSize { + c.SetError(MaxCollectionSizeExceededError(length, c.maxCollectionSize)) + return 0 + } + return length } -// ReadBinaryLength reads a length value for binary arrays with size guardrails +// ReadBinaryLength reads a length value for binary data with size guardrails func (c *ReadContext) ReadBinaryLength() int { err := c.Err() - return c.buffer.ReadBinaryLength(err) + length := c.buffer.ReadLength(err) + if c.err.HasError() { + return 0 + } + if c.maxBinarySize > 0 && length > c.maxBinarySize { + c.SetError(MaxBinarySizeExceededError(length, c.maxBinarySize)) + return 0 + } + return length } // ============================================================================ @@ -440,7 +458,7 @@ func (c *ReadContext) ReadByteSlice(refMode RefMode, readType bool) []byte { if readType { _ = c.buffer.ReadUint8(err) } - size := c.buffer.ReadBinaryLength(err) + size := c.ReadBinaryLength() return c.buffer.ReadBinary(size, err) } @@ -469,7 +487,7 @@ func (c *ReadContext) ReadStringStringMap(refMode RefMode, readType bool) map[st if readType { _ = c.buffer.ReadUint8(err) } - return readMapStringString(c.buffer, err) + return readMapStringString(c) } // ReadStringInt64Map reads map[string]int64 with optional ref/type info @@ -483,7 +501,7 @@ func (c *ReadContext) ReadStringInt64Map(refMode RefMode, readType bool) map[str if readType { _ = c.buffer.ReadUint8(err) } - return readMapStringInt64(c.buffer, err) + return readMapStringInt64(c) } // ReadStringInt32Map reads map[string]int32 with optional ref/type info @@ -497,7 +515,7 @@ func (c *ReadContext) ReadStringInt32Map(refMode RefMode, readType bool) map[str if readType { _ = c.buffer.ReadUint8(err) } - return readMapStringInt32(c.buffer, err) + return readMapStringInt32(c) } // ReadStringIntMap reads map[string]int with optional ref/type info @@ -511,7 +529,7 @@ func (c *ReadContext) ReadStringIntMap(refMode RefMode, readType bool) map[strin if readType { _ = c.buffer.ReadUint8(err) } - return readMapStringInt(c.buffer, err) + return readMapStringInt(c) } // ReadStringFloat64Map reads map[string]float64 with optional ref/type info @@ -525,7 +543,7 @@ func (c *ReadContext) ReadStringFloat64Map(refMode RefMode, readType bool) map[s if readType { _ = c.buffer.ReadUint8(err) } - return readMapStringFloat64(c.buffer, err) + return readMapStringFloat64(c) } // ReadStringBoolMap reads map[string]bool with optional ref/type info @@ -539,7 +557,7 @@ func (c *ReadContext) ReadStringBoolMap(refMode RefMode, readType bool) map[stri if readType { _ = c.buffer.ReadUint8(err) } - return readMapStringBool(c.buffer, err) + return readMapStringBool(c) } // ReadInt32Int32Map reads map[int32]int32 with optional ref/type info @@ -553,7 +571,7 @@ func (c *ReadContext) ReadInt32Int32Map(refMode RefMode, readType bool) map[int3 if readType { _ = c.buffer.ReadUint8(err) } - return readMapInt32Int32(c.buffer, err) + return readMapInt32Int32(c) } // ReadInt64Int64Map reads map[int64]int64 with optional ref/type info @@ -567,7 +585,7 @@ func (c *ReadContext) ReadInt64Int64Map(refMode RefMode, readType bool) map[int6 if readType { _ = c.buffer.ReadUint8(err) } - return readMapInt64Int64(c.buffer, err) + return readMapInt64Int64(c) } // ReadIntIntMap reads map[int]int with optional ref/type info @@ -581,7 +599,7 @@ func (c *ReadContext) ReadIntIntMap(refMode RefMode, readType bool) map[int]int if readType { _ = c.buffer.ReadUint8(err) } - return readMapIntInt(c.buffer, err) + return readMapIntInt(c) } // ReadBufferObject reads a buffer object @@ -589,7 +607,7 @@ func (c *ReadContext) ReadBufferObject() *ByteBuffer { err := c.Err() isInBand := c.buffer.ReadBool(err) if isInBand { - size := c.buffer.ReadBinaryLength(err) + size := c.ReadBinaryLength() buf := c.buffer.Slice(c.buffer.readerIndex, size) c.buffer.readerIndex += size return buf From a166d0a3787eb86e5214dd476225f28e169ec371 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Wed, 18 Mar 2026 16:29:15 +0530 Subject: [PATCH 08/11] fix: replaced buf with ctx --- go/fory/codegen/decoder.go | 20 ++++++++++---------- go/fory/fory.go | 24 ++++++++++++------------ 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/go/fory/codegen/decoder.go b/go/fory/codegen/decoder.go index 3024a7c7ca..8e580b053d 100644 --- a/go/fory/codegen/decoder.go +++ b/go/fory/codegen/decoder.go @@ -168,7 +168,7 @@ func generateFieldReadTyped(buf *bytes.Buffer, field *FieldInfo) error { fmt.Fprintf(buf, "\t\tisXlang := ctx.TypeResolver().IsXlang()\n") fmt.Fprintf(buf, "\t\tif isXlang {\n") fmt.Fprintf(buf, "\t\t\t// xlang mode: slices are not nullable, read directly without null flag\n") - fmt.Fprintf(buf, "\t\t\tsliceLen := buf.ReadCollectionLength(err)\n") + fmt.Fprintf(buf, "\t\t\tsliceLen := ctx.ReadCollectionLength()\n") fmt.Fprintf(buf, "\t\t\tif sliceLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t%s = make([]any, 0)\n", fieldAccess) fmt.Fprintf(buf, "\t\t\t} else {\n") @@ -187,7 +187,7 @@ func generateFieldReadTyped(buf *bytes.Buffer, field *FieldInfo) error { fmt.Fprintf(buf, "\t\t\tif nullFlag == -3 {\n") // NullFlag fmt.Fprintf(buf, "\t\t\t\t%s = nil\n", fieldAccess) fmt.Fprintf(buf, "\t\t\t} else {\n") - fmt.Fprintf(buf, "\t\t\t\tsliceLen := buf.ReadCollectionLength(err)\n") + fmt.Fprintf(buf, "\t\t\t\tsliceLen := ctx.ReadCollectionLength()\n") fmt.Fprintf(buf, "\t\t\t\tif sliceLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t\t%s = make([]any, 0)\n", fieldAccess) fmt.Fprintf(buf, "\t\t\t\t} else {\n") @@ -517,7 +517,7 @@ func generateSliceReadInline(buf *bytes.Buffer, sliceType *types.Slice, fieldAcc fmt.Fprintf(buf, "\t\tisXlang := ctx.TypeResolver().IsXlang()\n") fmt.Fprintf(buf, "\t\tif isXlang {\n") fmt.Fprintf(buf, "\t\t\t// xlang mode: slices are not nullable, read directly without null flag\n") - fmt.Fprintf(buf, "\t\t\tsliceLen := buf.ReadCollectionLength(err)\n") + fmt.Fprintf(buf, "\t\t\tsliceLen := ctx.ReadCollectionLength()\n") fmt.Fprintf(buf, "\t\t\tif sliceLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t%s = make(%s, 0)\n", fieldAccess, sliceType.String()) fmt.Fprintf(buf, "\t\t\t} else {\n") @@ -532,7 +532,7 @@ func generateSliceReadInline(buf *bytes.Buffer, sliceType *types.Slice, fieldAcc fmt.Fprintf(buf, "\t\t\tif nullFlag == -3 {\n") // NullFlag fmt.Fprintf(buf, "\t\t\t\t%s = nil\n", fieldAccess) fmt.Fprintf(buf, "\t\t\t} else {\n") - fmt.Fprintf(buf, "\t\t\t\tsliceLen := buf.ReadCollectionLength(err)\n") + fmt.Fprintf(buf, "\t\t\t\tsliceLen := ctx.ReadCollectionLength()\n") fmt.Fprintf(buf, "\t\t\t\tif sliceLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t\t%s = make(%s, 0)\n", fieldAccess, sliceType.String()) fmt.Fprintf(buf, "\t\t\t\t} else {\n") @@ -555,7 +555,7 @@ func generateSliceReadInlineNoNull(buf *bytes.Buffer, sliceType *types.Slice, fi unwrappedElem := types.Unalias(elemType) if iface, ok := unwrappedElem.(*types.Interface); ok && iface.Empty() { fmt.Fprintf(buf, "%s// Dynamic slice []any handling - no null flag\n", indent) - fmt.Fprintf(buf, "%ssliceLen := buf.ReadCollectionLength(err)\n", indent) + fmt.Fprintf(buf, "%ssliceLen := ctx.ReadCollectionLength()\n", indent) fmt.Fprintf(buf, "%sif sliceLen == 0 {\n", indent) fmt.Fprintf(buf, "%s\t%s = make([]any, 0)\n", indent, fieldAccess) fmt.Fprintf(buf, "%s} else {\n", indent) @@ -573,7 +573,7 @@ func generateSliceReadInlineNoNull(buf *bytes.Buffer, sliceType *types.Slice, fi } elemIsReferencable := isReferencableType(elemType) - fmt.Fprintf(buf, "%ssliceLen := buf.ReadCollectionLength(err)\n", indent) + fmt.Fprintf(buf, "%ssliceLen := ctx.ReadCollectionLength()\n", indent) fmt.Fprintf(buf, "%sif sliceLen == 0 {\n", indent) fmt.Fprintf(buf, "%s\t%s = make(%s, 0)\n", indent, fieldAccess, sliceType.String()) fmt.Fprintf(buf, "%s} else {\n", indent) @@ -703,7 +703,7 @@ func writePrimitiveSliceReadCall(buf *bytes.Buffer, basic *types.Basic, fieldAcc case types.Int8: fmt.Fprintf(buf, "%s%s = fory.ReadInt8Slice(buf, err)\n", indent, fieldAccess) case types.Uint8: - fmt.Fprintf(buf, "%ssizeBytes := buf.ReadBinaryLength(err)\n", indent) + fmt.Fprintf(buf, "%ssizeBytes := ctx.ReadBinaryLength()\n", indent) fmt.Fprintf(buf, "%s%s = make([]uint8, sizeBytes)\n", indent, fieldAccess) fmt.Fprintf(buf, "%sif sizeBytes > 0 {\n", indent) fmt.Fprintf(buf, "%s\traw := buf.ReadBinary(sizeBytes, err)\n", indent) @@ -925,7 +925,7 @@ func generateMapReadInline(buf *bytes.Buffer, mapType *types.Map, fieldAccess st fmt.Fprintf(buf, "\t\tisXlang := ctx.TypeResolver().IsXlang()\n") fmt.Fprintf(buf, "\t\tif isXlang {\n") fmt.Fprintf(buf, "\t\t\t// xlang mode: maps are not nullable, read directly without null flag\n") - fmt.Fprintf(buf, "\t\t\tmapLen := buf.ReadCollectionLength(err)\n") + fmt.Fprintf(buf, "\t\t\tmapLen := ctx.ReadCollectionLength()\n") fmt.Fprintf(buf, "\t\t\tif mapLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t%s = make(%s)\n", fieldAccess, mapType.String()) fmt.Fprintf(buf, "\t\t\t} else {\n") @@ -940,7 +940,7 @@ func generateMapReadInline(buf *bytes.Buffer, mapType *types.Map, fieldAccess st fmt.Fprintf(buf, "\t\t\tif nullFlag == -3 {\n") // NullFlag fmt.Fprintf(buf, "\t\t\t\t%s = nil\n", fieldAccess) fmt.Fprintf(buf, "\t\t\t} else {\n") - fmt.Fprintf(buf, "\t\t\t\tmapLen := buf.ReadCollectionLength(err)\n") + fmt.Fprintf(buf, "\t\t\t\tmapLen := ctx.ReadCollectionLength()\n") fmt.Fprintf(buf, "\t\t\t\tif mapLen == 0 {\n") fmt.Fprintf(buf, "\t\t\t\t\t%s = make(%s)\n", fieldAccess, mapType.String()) fmt.Fprintf(buf, "\t\t\t\t} else {\n") @@ -972,7 +972,7 @@ func generateMapReadInlineNoNull(buf *bytes.Buffer, mapType *types.Map, fieldAcc } indent := "\t\t\t" - fmt.Fprintf(buf, "%smapLen := buf.ReadCollectionLength(err)\n", indent) + fmt.Fprintf(buf, "%smapLen := ctx.ReadCollectionLength()\n", indent) fmt.Fprintf(buf, "%sif mapLen == 0 {\n", indent) fmt.Fprintf(buf, "%s\t%s = make(%s)\n", indent, fieldAccess, mapType.String()) fmt.Fprintf(buf, "%s} else {\n", indent) diff --git a/go/fory/fory.go b/go/fory/fory.go index 567b2310ab..37e6bad7d1 100644 --- a/go/fory/fory.go +++ b/go/fory/fory.go @@ -168,8 +168,8 @@ func New(opts ...Option) *Fory { f.writeCtx.xlang = f.config.IsXlang f.readCtx = NewReadContext(f.config.TrackRef) - f.readCtx.buffer.maxCollectionSize = f.config.MaxCollectionSize - f.readCtx.buffer.maxBinarySize = f.config.MaxBinarySize + f.readCtx.maxCollectionSize = f.config.MaxCollectionSize + f.readCtx.maxBinarySize = f.config.MaxBinarySize f.readCtx.typeResolver = f.typeResolver f.readCtx.refResolver = f.refResolver f.readCtx.compatible = f.config.Compatible @@ -510,8 +510,8 @@ func (f *Fory) Deserialize(data []byte, v any) error { defer f.resetReadState() // Apply Fory config guardrails - f.readCtx.buffer.maxCollectionSize = f.config.MaxCollectionSize - f.readCtx.buffer.maxBinarySize = f.config.MaxBinarySize + f.readCtx.maxCollectionSize = f.config.MaxCollectionSize + f.readCtx.maxBinarySize = f.config.MaxBinarySize f.readCtx.SetData(data) @@ -615,9 +615,9 @@ func (f *Fory) DeserializeFrom(buf *ByteBuffer, v any) error { // Reset contexts for each independent serialized object defer f.resetReadState() - // Apply Fory config guardrails to the incoming buffer - buf.maxCollectionSize = f.config.MaxCollectionSize - buf.maxBinarySize = f.config.MaxBinarySize + // Apply Fory config guardrails + f.readCtx.maxCollectionSize = f.config.MaxCollectionSize + f.readCtx.maxBinarySize = f.config.MaxBinarySize // Temporarily swap buffer origBuffer := f.readCtx.buffer @@ -713,9 +713,9 @@ func (f *Fory) SerializeWithCallback(buffer *ByteBuffer, v any, callback func(Bu // DeserializeWithCallbackBuffers deserializes from buffer into the provided value (for streaming/cross-language use). // The third parameter is optional external buffers for out-of-band data (can be nil). func (f *Fory) DeserializeWithCallbackBuffers(buffer *ByteBuffer, v any, buffers []*ByteBuffer) error { - // Apply Fory config guardrails to the incoming buffer - buffer.maxCollectionSize = f.config.MaxCollectionSize - buffer.maxBinarySize = f.config.MaxBinarySize + // Apply Fory config guardrails + f.readCtx.maxCollectionSize = f.config.MaxCollectionSize + f.readCtx.maxBinarySize = f.config.MaxBinarySize // Reset context and use the provided buffer f.readCtx.buffer = buffer @@ -1022,8 +1022,8 @@ func Deserialize[T any](f *Fory, data []byte, target *T) error { f.readCtx.Reset() // Apply Fory config guardrails - f.readCtx.buffer.maxCollectionSize = f.config.MaxCollectionSize - f.readCtx.buffer.maxBinarySize = f.config.MaxBinarySize + f.readCtx.maxCollectionSize = f.config.MaxCollectionSize + f.readCtx.maxBinarySize = f.config.MaxBinarySize f.readCtx.SetData(data) From 3e27a634918007a679e3080d8d5ea793e51ce684 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Wed, 18 Mar 2026 16:30:06 +0530 Subject: [PATCH 09/11] fix: updated readcollection and readbinary paths --- go/fory/array_primitive.go | 26 +++++++------- go/fory/map.go | 2 +- go/fory/map_primitive.go | 70 ++++++++++++++++++++++++-------------- go/fory/set.go | 2 +- go/fory/skip.go | 14 ++++---- go/fory/slice.go | 2 +- go/fory/slice_dyn.go | 2 +- go/fory/slice_primitive.go | 36 ++++++++++---------- 8 files changed, 86 insertions(+), 68 deletions(-) diff --git a/go/fory/array_primitive.go b/go/fory/array_primitive.go index afdf4d8179..06c76dc782 100644 --- a/go/fory/array_primitive.go +++ b/go/fory/array_primitive.go @@ -66,7 +66,7 @@ func (s boolArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeType func (s boolArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - length := buf.ReadBinaryLength(err) + length := ctx.ReadBinaryLength() if ctx.HasError() { return } @@ -131,7 +131,7 @@ func (s int8ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeType func (s int8ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - length := buf.ReadBinaryLength(err) + length := ctx.ReadBinaryLength() if ctx.HasError() { return } @@ -197,7 +197,7 @@ func (s int16ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTyp func (s int16ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadBinaryLength(err) + size := ctx.ReadBinaryLength() length := size / 2 if ctx.HasError() { return @@ -269,7 +269,7 @@ func (s int32ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTyp func (s int32ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadBinaryLength(err) + size := ctx.ReadBinaryLength() length := size / 4 if ctx.HasError() { return @@ -341,7 +341,7 @@ func (s int64ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTyp func (s int64ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadBinaryLength(err) + size := ctx.ReadBinaryLength() length := size / 8 if ctx.HasError() { return @@ -413,7 +413,7 @@ func (s float32ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeT func (s float32ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadBinaryLength(err) + size := ctx.ReadBinaryLength() length := size / 4 if ctx.HasError() { return @@ -485,7 +485,7 @@ func (s float64ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeT func (s float64ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadBinaryLength(err) + size := ctx.ReadBinaryLength() length := size / 8 if ctx.HasError() { return @@ -556,7 +556,7 @@ func (s uint8ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTyp func (s uint8ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - length := buf.ReadBinaryLength(err) + length := ctx.ReadBinaryLength() if ctx.HasError() { return } @@ -623,7 +623,7 @@ func (s uint16ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTy func (s uint16ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadBinaryLength(err) + size := ctx.ReadBinaryLength() length := size / 2 if ctx.HasError() { return @@ -694,7 +694,7 @@ func (s uint32ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTy func (s uint32ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadBinaryLength(err) + size := ctx.ReadBinaryLength() length := size / 4 if ctx.HasError() { return @@ -764,7 +764,7 @@ func (s uint64ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeTy func (s uint64ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() err := ctx.Err() - size := buf.ReadBinaryLength(err) + size := ctx.ReadBinaryLength() length := size / 8 if ctx.HasError() { return @@ -838,7 +838,7 @@ func (s float16ArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeT func (s float16ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - size := buf.ReadBinaryLength(ctxErr) + size := ctx.ReadBinaryLength() length := size / 2 if ctx.HasError() { return @@ -912,7 +912,7 @@ func (s bfloat16ArraySerializer) Write(ctx *WriteContext, refMode RefMode, write func (s bfloat16ArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - size := buf.ReadBinaryLength(ctxErr) + size := ctx.ReadBinaryLength() length := size / 2 if ctx.HasError() { return diff --git a/go/fory/map.go b/go/fory/map.go index a26c43bafd..ace2c55973 100644 --- a/go/fory/map.go +++ b/go/fory/map.go @@ -305,7 +305,7 @@ func (s mapSerializer) ReadData(ctx *ReadContext, value reflect.Value) { } refResolver.Reference(value) - size := buf.ReadCollectionLength(ctxErr) + size := ctx.ReadCollectionLength() if size == 0 || ctx.HasError() { return } diff --git a/go/fory/map_primitive.go b/go/fory/map_primitive.go index 79622c89d2..16e40f5aef 100644 --- a/go/fory/map_primitive.go +++ b/go/fory/map_primitive.go @@ -69,8 +69,10 @@ func writeMapStringString(buf *ByteBuffer, m map[string]string, hasGenerics bool } // readMapStringString reads map[string]string using chunk protocol -func readMapStringString(buf *ByteBuffer, err *Error) map[string]string { - size := buf.ReadCollectionLength(err) +func readMapStringString(ctx *ReadContext) map[string]string { + err := ctx.Err() + buf := ctx.Buffer() + size := ctx.ReadCollectionLength() result := make(map[string]string, size) if size == 0 { return result @@ -172,8 +174,10 @@ func writeMapStringInt64(buf *ByteBuffer, m map[string]int64, hasGenerics bool) } // readMapStringInt64 reads map[string]int64 using chunk protocol -func readMapStringInt64(buf *ByteBuffer, err *Error) map[string]int64 { - size := buf.ReadCollectionLength(err) +func readMapStringInt64(ctx *ReadContext) map[string]int64 { + err := ctx.Err() + buf := ctx.Buffer() + size := ctx.ReadCollectionLength() result := make(map[string]int64, size) if size == 0 { return result @@ -246,8 +250,10 @@ func writeMapStringInt32(buf *ByteBuffer, m map[string]int32, hasGenerics bool) } // readMapStringInt32 reads map[string]int32 using chunk protocol -func readMapStringInt32(buf *ByteBuffer, err *Error) map[string]int32 { - size := buf.ReadCollectionLength(err) +func readMapStringInt32(ctx *ReadContext) map[string]int32 { + err := ctx.Err() + buf := ctx.Buffer() + size := ctx.ReadCollectionLength() result := make(map[string]int32, size) if size == 0 { return result @@ -320,8 +326,10 @@ func writeMapStringInt(buf *ByteBuffer, m map[string]int, hasGenerics bool) { } // readMapStringInt reads map[string]int using chunk protocol -func readMapStringInt(buf *ByteBuffer, err *Error) map[string]int { - size := buf.ReadCollectionLength(err) +func readMapStringInt(ctx *ReadContext) map[string]int { + err := ctx.Err() + buf := ctx.Buffer() + size := ctx.ReadCollectionLength() result := make(map[string]int, size) if size == 0 { return result @@ -394,8 +402,10 @@ func writeMapStringFloat64(buf *ByteBuffer, m map[string]float64, hasGenerics bo } // readMapStringFloat64 reads map[string]float64 using chunk protocol -func readMapStringFloat64(buf *ByteBuffer, err *Error) map[string]float64 { - size := buf.ReadCollectionLength(err) +func readMapStringFloat64(ctx *ReadContext) map[string]float64 { + err := ctx.Err() + buf := ctx.Buffer() + size := ctx.ReadCollectionLength() result := make(map[string]float64, size) if size == 0 { return result @@ -468,8 +478,10 @@ func writeMapStringBool(buf *ByteBuffer, m map[string]bool, hasGenerics bool) { } // readMapStringBool reads map[string]bool using chunk protocol -func readMapStringBool(buf *ByteBuffer, err *Error) map[string]bool { - size := buf.ReadCollectionLength(err) +func readMapStringBool(ctx *ReadContext) map[string]bool { + err := ctx.Err() + buf := ctx.Buffer() + size := ctx.ReadCollectionLength() result := make(map[string]bool, size) if size == 0 { return result @@ -547,8 +559,10 @@ func writeMapInt32Int32(buf *ByteBuffer, m map[int32]int32, hasGenerics bool) { } // readMapInt32Int32 reads map[int32]int32 using chunk protocol -func readMapInt32Int32(buf *ByteBuffer, err *Error) map[int32]int32 { - size := buf.ReadCollectionLength(err) +func readMapInt32Int32(ctx *ReadContext) map[int32]int32 { + err := ctx.Err() + buf := ctx.Buffer() + size := ctx.ReadCollectionLength() result := make(map[int32]int32, size) if size == 0 { return result @@ -621,8 +635,10 @@ func writeMapInt64Int64(buf *ByteBuffer, m map[int64]int64, hasGenerics bool) { } // readMapInt64Int64 reads map[int64]int64 using chunk protocol -func readMapInt64Int64(buf *ByteBuffer, err *Error) map[int64]int64 { - size := buf.ReadCollectionLength(err) +func readMapInt64Int64(ctx *ReadContext) map[int64]int64 { + err := ctx.Err() + buf := ctx.Buffer() + size := ctx.ReadCollectionLength() result := make(map[int64]int64, size) if size == 0 { return result @@ -695,8 +711,10 @@ func writeMapIntInt(buf *ByteBuffer, m map[int]int, hasGenerics bool) { } // readMapIntInt reads map[int]int using chunk protocol -func readMapIntInt(buf *ByteBuffer, err *Error) map[int]int { - size := buf.ReadCollectionLength(err) +func readMapIntInt(ctx *ReadContext) map[int]int { + err := ctx.Err() + buf := ctx.Buffer() + size := ctx.ReadCollectionLength() result := make(map[int]int, size) if size == 0 { return result @@ -752,7 +770,7 @@ func (s stringStringMapSerializer) ReadData(ctx *ReadContext, value reflect.Valu value.Set(reflect.MakeMap(value.Type())) } ctx.RefResolver().Reference(value) - result := readMapStringString(ctx.buffer, ctx.Err()) + result := readMapStringString(ctx) value.Set(reflect.ValueOf(result)) } @@ -787,7 +805,7 @@ func (s stringInt64MapSerializer) ReadData(ctx *ReadContext, value reflect.Value value.Set(reflect.MakeMap(value.Type())) } ctx.RefResolver().Reference(value) - result := readMapStringInt64(ctx.buffer, ctx.Err()) + result := readMapStringInt64(ctx) value.Set(reflect.ValueOf(result)) } @@ -822,7 +840,7 @@ func (s stringIntMapSerializer) ReadData(ctx *ReadContext, value reflect.Value) value.Set(reflect.MakeMap(value.Type())) } ctx.RefResolver().Reference(value) - result := readMapStringInt(ctx.buffer, ctx.Err()) + result := readMapStringInt(ctx) value.Set(reflect.ValueOf(result)) } @@ -857,7 +875,7 @@ func (s stringFloat64MapSerializer) ReadData(ctx *ReadContext, value reflect.Val value.Set(reflect.MakeMap(value.Type())) } ctx.RefResolver().Reference(value) - result := readMapStringFloat64(ctx.buffer, ctx.Err()) + result := readMapStringFloat64(ctx) value.Set(reflect.ValueOf(result)) } @@ -892,7 +910,7 @@ func (s stringBoolMapSerializer) ReadData(ctx *ReadContext, value reflect.Value) value.Set(reflect.MakeMap(value.Type())) } ctx.RefResolver().Reference(value) - result := readMapStringBool(ctx.buffer, ctx.Err()) + result := readMapStringBool(ctx) value.Set(reflect.ValueOf(result)) } @@ -927,7 +945,7 @@ func (s int32Int32MapSerializer) ReadData(ctx *ReadContext, value reflect.Value) value.Set(reflect.MakeMap(value.Type())) } ctx.RefResolver().Reference(value) - result := readMapInt32Int32(ctx.buffer, ctx.Err()) + result := readMapInt32Int32(ctx) value.Set(reflect.ValueOf(result)) } @@ -962,7 +980,7 @@ func (s int64Int64MapSerializer) ReadData(ctx *ReadContext, value reflect.Value) value.Set(reflect.MakeMap(value.Type())) } ctx.RefResolver().Reference(value) - result := readMapInt64Int64(ctx.buffer, ctx.Err()) + result := readMapInt64Int64(ctx) value.Set(reflect.ValueOf(result)) } @@ -997,7 +1015,7 @@ func (s intIntMapSerializer) ReadData(ctx *ReadContext, value reflect.Value) { value.Set(reflect.MakeMap(value.Type())) } ctx.RefResolver().Reference(value) - result := readMapIntInt(ctx.buffer, ctx.Err()) + result := readMapIntInt(ctx) value.Set(reflect.ValueOf(result)) } diff --git a/go/fory/set.go b/go/fory/set.go index d6477457f8..83a7b31719 100644 --- a/go/fory/set.go +++ b/go/fory/set.go @@ -295,7 +295,7 @@ func (s setSerializer) ReadData(ctx *ReadContext, value reflect.Value) { err := ctx.Err() type_ := value.Type() // ReadData collection length from buffer - length := buf.ReadCollectionLength(err) + length := ctx.ReadCollectionLength() if length == 0 { // Initialize empty set if length is 0 value.Set(reflect.MakeMap(type_)) diff --git a/go/fory/skip.go b/go/fory/skip.go index d524c2af35..64660dfc36 100644 --- a/go/fory/skip.go +++ b/go/fory/skip.go @@ -213,7 +213,7 @@ func readTypeInfoForSkip(ctx *ReadContext, fieldTypeId TypeId) *TypeInfo { // Uses context error state for deferred error checking. func skipCollection(ctx *ReadContext, fieldDef FieldDef) { err := ctx.Err() - length := uint32(ctx.buffer.ReadCollectionLength(err)) + length := uint32(ctx.ReadCollectionLength()) if ctx.HasError() || length == 0 { return } @@ -283,7 +283,7 @@ func skipCollection(ctx *ReadContext, fieldDef FieldDef) { // Uses context error state for deferred error checking. func skipMap(ctx *ReadContext, fieldDef FieldDef) { bufErr := ctx.Err() - length := uint32(ctx.buffer.ReadCollectionLength(bufErr)) + length := uint32(ctx.ReadCollectionLength()) if ctx.HasError() || length == 0 { return } @@ -601,31 +601,31 @@ func skipValue(ctx *ReadContext, fieldDef FieldDef, readRefFlag bool, isField bo _ = ctx.buffer.ReadBinary(int(size), err) } case BINARY: - length := uint32(ctx.buffer.ReadBinaryLength(err)) + length := uint32(ctx.ReadBinaryLength()) if ctx.HasError() { return } _ = ctx.buffer.ReadBinary(int(length), err) case BOOL_ARRAY, INT8_ARRAY, UINT8_ARRAY: - length := ctx.buffer.ReadBinaryLength(err) + length := ctx.ReadBinaryLength() if ctx.HasError() { return } _ = ctx.buffer.ReadBinary(length, err) case INT16_ARRAY, UINT16_ARRAY, FLOAT16_ARRAY, BFLOAT16_ARRAY: - length := ctx.buffer.ReadBinaryLength(err) + length := ctx.ReadBinaryLength() if ctx.HasError() { return } _ = ctx.buffer.ReadBinary(length*2, err) case INT32_ARRAY, UINT32_ARRAY, FLOAT32_ARRAY: - length := ctx.buffer.ReadBinaryLength(err) + length := ctx.ReadBinaryLength() if ctx.HasError() { return } _ = ctx.buffer.ReadBinary(length*4, err) case INT64_ARRAY, UINT64_ARRAY, FLOAT64_ARRAY: - length := ctx.buffer.ReadBinaryLength(err) + length := ctx.ReadBinaryLength() if ctx.HasError() { return } diff --git a/go/fory/slice.go b/go/fory/slice.go index a292fe0ae4..90b6ff14e9 100644 --- a/go/fory/slice.go +++ b/go/fory/slice.go @@ -264,7 +264,7 @@ func (s *sliceSerializer) ReadWithTypeInfo(ctx *ReadContext, refMode RefMode, ty func (s *sliceSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - length := buf.ReadCollectionLength(ctxErr) + length := ctx.ReadCollectionLength() isArrayType := value.Type().Kind() == reflect.Array if length == 0 { diff --git a/go/fory/slice_dyn.go b/go/fory/slice_dyn.go index 7c5b149d25..90a7b8cad1 100644 --- a/go/fory/slice_dyn.go +++ b/go/fory/slice_dyn.go @@ -261,7 +261,7 @@ func (s sliceDynSerializer) Read(ctx *ReadContext, refMode RefMode, readType boo func (s sliceDynSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - length := buf.ReadCollectionLength(ctxErr) + length := ctx.ReadCollectionLength() sliceType := value.Type() value.Set(reflect.MakeSlice(sliceType, length, length)) if length == 0 { diff --git a/go/fory/slice_primitive.go b/go/fory/slice_primitive.go index a6236964f1..dddc800697 100644 --- a/go/fory/slice_primitive.go +++ b/go/fory/slice_primitive.go @@ -74,7 +74,7 @@ func (s byteSliceSerializer) ReadWithTypeInfo(ctx *ReadContext, refMode RefMode, func (s byteSliceSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - length := buf.ReadBinaryLength(ctxErr) + length := ctx.ReadBinaryLength() ptr := (*[]byte)(value.Addr().UnsafePointer()) if length == 0 { *ptr = make([]byte, 0) @@ -642,7 +642,7 @@ func (s stringSliceSerializer) ReadWithTypeInfo(ctx *ReadContext, refMode RefMod func (s stringSliceSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - length := buf.ReadCollectionLength(ctxErr) + length := ctx.ReadCollectionLength() ptr := (*[]string)(value.Addr().UnsafePointer()) if length == 0 { *ptr = make([]string, 0) @@ -691,7 +691,7 @@ func WriteByteSlice(buf *ByteBuffer, value []byte) { // ReadByteSlice reads []byte from buffer using ARRAY protocol func ReadByteSlice(buf *ByteBuffer, err *Error) []byte { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) if size == 0 { return make([]byte, 0) } @@ -712,7 +712,7 @@ func WriteBoolSlice(buf *ByteBuffer, value []bool) { // ReadBoolSlice reads []bool from buffer using ARRAY protocol func ReadBoolSlice(buf *ByteBuffer, err *Error) []bool { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) if size == 0 { return make([]bool, 0) } @@ -733,7 +733,7 @@ func WriteInt8Slice(buf *ByteBuffer, value []int8) { // ReadInt8Slice reads []int8 from buffer using ARRAY protocol func ReadInt8Slice(buf *ByteBuffer, err *Error) []int8 { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) if size == 0 { return make([]int8, 0) } @@ -760,7 +760,7 @@ func WriteInt16Slice(buf *ByteBuffer, value []int16) { // ReadInt16Slice reads []int16 from buffer using ARRAY protocol func ReadInt16Slice(buf *ByteBuffer, err *Error) []int16 { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) length := size / 2 if length == 0 { return make([]int16, 0) @@ -794,7 +794,7 @@ func WriteInt32Slice(buf *ByteBuffer, value []int32) { // ReadInt32Slice reads []int32 from buffer using ARRAY protocol func ReadInt32Slice(buf *ByteBuffer, err *Error) []int32 { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) length := size / 4 if length == 0 { return make([]int32, 0) @@ -828,7 +828,7 @@ func WriteInt64Slice(buf *ByteBuffer, value []int64) { // ReadInt64Slice reads []int64 from buffer using ARRAY protocol func ReadInt64Slice(buf *ByteBuffer, err *Error) []int64 { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) length := size / 8 if length == 0 { return make([]int64, 0) @@ -862,7 +862,7 @@ func WriteUint16Slice(buf *ByteBuffer, value []uint16) { // ReadUint16Slice reads []uint16 from buffer using ARRAY protocol func ReadUint16Slice(buf *ByteBuffer, err *Error) []uint16 { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) length := size / 2 if length == 0 { return make([]uint16, 0) @@ -896,7 +896,7 @@ func WriteUint32Slice(buf *ByteBuffer, value []uint32) { // ReadUint32Slice reads []uint32 from buffer using ARRAY protocol func ReadUint32Slice(buf *ByteBuffer, err *Error) []uint32 { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) length := size / 4 if length == 0 { return make([]uint32, 0) @@ -930,7 +930,7 @@ func WriteUint64Slice(buf *ByteBuffer, value []uint64) { // ReadUint64Slice reads []uint64 from buffer using ARRAY protocol func ReadUint64Slice(buf *ByteBuffer, err *Error) []uint64 { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) length := size / 8 if length == 0 { return make([]uint64, 0) @@ -964,7 +964,7 @@ func WriteFloat32Slice(buf *ByteBuffer, value []float32) { // ReadFloat32Slice reads []float32 from buffer using ARRAY protocol func ReadFloat32Slice(buf *ByteBuffer, err *Error) []float32 { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) length := size / 4 if length == 0 { return make([]float32, 0) @@ -998,7 +998,7 @@ func WriteFloat64Slice(buf *ByteBuffer, value []float64) { // ReadFloat64Slice reads []float64 from buffer using ARRAY protocol func ReadFloat64Slice(buf *ByteBuffer, err *Error) []float64 { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) length := size / 8 if length == 0 { return make([]float64, 0) @@ -1071,7 +1071,7 @@ func (s float16SliceSerializer) ReadWithTypeInfo(ctx *ReadContext, refMode RefMo func (s float16SliceSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - size := buf.ReadBinaryLength(ctxErr) + size := ctx.ReadBinaryLength() length := size / 2 if ctx.HasError() { return @@ -1131,7 +1131,7 @@ func WriteIntSlice(buf *ByteBuffer, value []int) { // ReadIntSlice reads []int from buffer using ARRAY protocol func ReadIntSlice(buf *ByteBuffer, err *Error) []int { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) if strconv.IntSize == 64 { length := size / 8 if length == 0 { @@ -1196,7 +1196,7 @@ func WriteUintSlice(buf *ByteBuffer, value []uint) { // ReadUintSlice reads []uint from buffer using ARRAY protocol func ReadUintSlice(buf *ByteBuffer, err *Error) []uint { - size := buf.ReadBinaryLength(err) + size := buf.ReadLength(err) if strconv.IntSize == 64 { length := size / 8 if length == 0 { @@ -1253,7 +1253,7 @@ func WriteStringSlice(buf *ByteBuffer, value []string, hasGenerics bool) { // ReadStringSlice reads []string from buffer using LIST protocol func ReadStringSlice(buf *ByteBuffer, err *Error) []string { - length := buf.ReadCollectionLength(err) + length := buf.ReadLength(err) if length == 0 { return make([]string, 0) } @@ -1328,7 +1328,7 @@ func (s bfloat16SliceSerializer) ReadWithTypeInfo(ctx *ReadContext, refMode RefM func (s bfloat16SliceSerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() ctxErr := ctx.Err() - size := buf.ReadBinaryLength(ctxErr) + size := ctx.ReadBinaryLength() length := size / 2 if ctx.HasError() { return From cc4fea6b963d28ada96c817d5d38ecea767abe15 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Wed, 18 Mar 2026 18:38:32 +0530 Subject: [PATCH 10/11] fix: removed config calls from deserialize functions --- go/fory/array.go | 1 - go/fory/fory.go | 18 ------------------ 2 files changed, 19 deletions(-) diff --git a/go/fory/array.go b/go/fory/array.go index 44b26b1090..6cb1751f3f 100644 --- a/go/fory/array.go +++ b/go/fory/array.go @@ -365,7 +365,6 @@ func (s byteArraySerializer) Write(ctx *WriteContext, refMode RefMode, writeType func (s byteArraySerializer) ReadData(ctx *ReadContext, value reflect.Value) { buf := ctx.Buffer() - _ = ctx.Err() length := ctx.ReadCollectionLength() if ctx.HasError() { return diff --git a/go/fory/fory.go b/go/fory/fory.go index 37e6bad7d1..69691bdf2f 100644 --- a/go/fory/fory.go +++ b/go/fory/fory.go @@ -508,11 +508,6 @@ func (f *Fory) Serialize(value any) ([]byte, error) { // The target must be a pointer to the value to deserialize into. func (f *Fory) Deserialize(data []byte, v any) error { defer f.resetReadState() - - // Apply Fory config guardrails - f.readCtx.maxCollectionSize = f.config.MaxCollectionSize - f.readCtx.maxBinarySize = f.config.MaxBinarySize - f.readCtx.SetData(data) isNull := readHeader(f.readCtx) @@ -615,10 +610,6 @@ func (f *Fory) DeserializeFrom(buf *ByteBuffer, v any) error { // Reset contexts for each independent serialized object defer f.resetReadState() - // Apply Fory config guardrails - f.readCtx.maxCollectionSize = f.config.MaxCollectionSize - f.readCtx.maxBinarySize = f.config.MaxBinarySize - // Temporarily swap buffer origBuffer := f.readCtx.buffer f.readCtx.buffer = buf @@ -713,10 +704,6 @@ func (f *Fory) SerializeWithCallback(buffer *ByteBuffer, v any, callback func(Bu // DeserializeWithCallbackBuffers deserializes from buffer into the provided value (for streaming/cross-language use). // The third parameter is optional external buffers for out-of-band data (can be nil). func (f *Fory) DeserializeWithCallbackBuffers(buffer *ByteBuffer, v any, buffers []*ByteBuffer) error { - // Apply Fory config guardrails - f.readCtx.maxCollectionSize = f.config.MaxCollectionSize - f.readCtx.maxBinarySize = f.config.MaxBinarySize - // Reset context and use the provided buffer f.readCtx.buffer = buffer defer func() { @@ -1020,11 +1007,6 @@ func Serialize[T any](f *Fory, value T) ([]byte, error) { func Deserialize[T any](f *Fory, data []byte, target *T) error { // Reuse context, reset and set new data f.readCtx.Reset() - - // Apply Fory config guardrails - f.readCtx.maxCollectionSize = f.config.MaxCollectionSize - f.readCtx.maxBinarySize = f.config.MaxBinarySize - f.readCtx.SetData(data) // ReadData and validate header From bb6e0dbec4de5ff6781fa6b03e1126351c96265c Mon Sep 17 00:00:00 2001 From: ayush00git Date: Wed, 18 Mar 2026 22:28:58 +0530 Subject: [PATCH 11/11] fix: set default values of maxcollectionsize and maxbinarysize --- go/fory/fory.go | 8 +++++--- go/fory/reader.go | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/go/fory/fory.go b/go/fory/fory.go index 69691bdf2f..57da20c576 100644 --- a/go/fory/fory.go +++ b/go/fory/fory.go @@ -61,9 +61,11 @@ type Config struct { // defaultConfig returns the default configuration func defaultConfig() Config { return Config{ - TrackRef: false, // Match Java's default: reference tracking disabled - MaxDepth: 20, - IsXlang: false, + TrackRef: false, // Match Java's default: reference tracking disabled + MaxDepth: 20, + IsXlang: false, + MaxCollectionSize: 1_000_000, + MaxBinarySize: 64 * 1024 * 1024, } } diff --git a/go/fory/reader.go b/go/fory/reader.go index ceacc9f0f8..9c8b049ad2 100644 --- a/go/fory/reader.go +++ b/go/fory/reader.go @@ -246,7 +246,7 @@ func (c *ReadContext) ReadCollectionLength() int { if c.err.HasError() { return 0 } - if c.maxCollectionSize > 0 && length > c.maxCollectionSize { + if length > c.maxCollectionSize { c.SetError(MaxCollectionSizeExceededError(length, c.maxCollectionSize)) return 0 } @@ -260,7 +260,7 @@ func (c *ReadContext) ReadBinaryLength() int { if c.err.HasError() { return 0 } - if c.maxBinarySize > 0 && length > c.maxBinarySize { + if length > c.maxBinarySize { c.SetError(MaxBinarySizeExceededError(length, c.maxBinarySize)) return 0 }