This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new 62b0d91fc fix(go): added maxBinarySize limit to decimal 
deserialization (#3623)
62b0d91fc is described below

commit 62b0d91fc1bea1a34c15e3416c0b1f0bc7540437
Author: Ayush Kumar <[email protected]>
AuthorDate: Mon Apr 27 15:24:16 2026 +0530

    fix(go): added maxBinarySize limit to decimal deserialization (#3623)
    
    ## Why?
    the deserialization of arbitrary-precision DECIMAL numbers involves
    reading a magnitude payload byte array. The length of this payload is
    derived from the header's metadata and is completely
    attacker-controlled.
    
    ## What does this PR do?
    use `ctx.ReadBinaryLength()` which correctly enforces `maxBinarySize`
    guardrails.
    
    
    ## Related issues
    
    
    ## AI Contribution Checklist
    
    
    
    - [ ] Substantial AI assistance was used in this PR: `yes` / `no`
    - [ ] If `yes`, I included a completed [AI Contribution
    
Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs)
    in this PR description and the required `AI Usage Disclosure`.
    - [ ] If `yes`, my PR description includes the required `ai_review`
    summary and screenshot evidence of the final clean AI review results
    from both fresh reviewers on the current PR diff or current HEAD after
    the latest code changes.
    
    
    
    ## Does this PR introduce any user-facing change?
    
    
    
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    ## Benchmark
---
 go/fory/decimal.go      |  6 +++++-
 go/fory/decimal_test.go | 24 ++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/go/fory/decimal.go b/go/fory/decimal.go
index d7acd27c9..92d6e15be 100644
--- a/go/fory/decimal.go
+++ b/go/fory/decimal.go
@@ -134,10 +134,14 @@ func readDecimalParts(ctx *ReadContext) (int32, *big.Int) 
{
 
        meta := header >> 1
        length := meta >> 1
-       if length == 0 || length > uint64(MaxInt32) {
+       if length == 0 {
                ctx.SetError(DeserializationErrorf("invalid decimal magnitude 
length %d", length))
                return 0, nil
        }
+       if length > uint64(ctx.maxBinarySize) {
+               ctx.SetError(MaxBinarySizeExceededError(int(length), 
ctx.maxBinarySize))
+               return 0, nil
+       }
        payload := ctx.buffer.ReadBytes(int(length), err)
        if ctx.HasError() {
                return 0, nil
diff --git a/go/fory/decimal_test.go b/go/fory/decimal_test.go
index 0acd9fbcc..a54e7907d 100644
--- a/go/fory/decimal_test.go
+++ b/go/fory/decimal_test.go
@@ -18,6 +18,7 @@
 package fory
 
 import (
+       "bytes"
        "math/big"
        "testing"
 
@@ -131,3 +132,26 @@ func TestDecimalRejectsNonCanonicalBigPayload(t 
*testing.T) {
        require.Error(t, err)
        require.Contains(t, err.Error(), "trailing zero byte")
 }
+
+func TestDecimalOOM(t *testing.T) {
+       maliciousLength := uint64(2000000000)
+
+       buffer := NewByteBuffer(nil)
+       buffer.WriteByte_(XLangFlag)
+       buffer.WriteInt8(NotNullValueFlag)
+       buffer.WriteUint8(uint8(DECIMAL))
+       buffer.WriteVarint32(0)
+
+       meta := (maliciousLength << 1) | 0
+       header := (meta << 1) | 1
+       buffer.WriteVarUint64(header)
+
+       data := buffer.Bytes()
+
+       f := New(WithXlang(true), WithMaxBinarySize(1024*1024))
+
+       var decoded Decimal
+       err := f.DeserializeFromReader(bytes.NewReader(data), &decoded)
+       require.Error(t, err)
+       require.Contains(t, err.Error(), "max binary size exceeded")
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to