jonyoder opened a new issue, #3085:
URL: https://github.com/apache/fory/issues/3085

   ## Search before asking
   
   - [x] I searched the [issues](https://github.com/apache/fory/issues) and 
found no similar issues.
   
   ## Fory version
   
   Latest main branch (commit d2a155d5e0e7)
   
   ## Component(s)
   
   Go
   
   ## Minimal reproduce step
   
   ```go
   package main
   
   import (
        "fmt"
        "github.com/apache/fory/go/fory"
   )
   
   type Inner struct {
        Name     string
        Operator string
        Version  string
   }
   
   type Outer struct {
        Id    int32
        Name  string
        Items []Inner
   }
   
   func main() {
        for _, count := range []int{127, 128} {
                f := fory.New(fory.WithRefTracking(true))
                f.RegisterByName(&Inner{}, fmt.Sprintf("Inner_%d", count))
                f.RegisterByName(&Outer{}, fmt.Sprintf("Outer_%d", count))
   
                original := make([]Outer, count)
                for i := 0; i < count; i++ {
                        original[i] = Outer{
                                Id:   int32(i),
                                Name: fmt.Sprintf("item%d", i),
                                Items: []Inner{{Name: "dep1", Operator: ">=", 
Version: "1.0.0"}},
                        }
                }
   
                data, _ := f.Marshal(original)
                var loaded []Outer
                err := f.Unmarshal(data, &loaded)
                
                if err != nil {
                        fmt.Printf("%d items: FAILED - %v\n", count, err)
                } else {
                        fmt.Printf("%d items: OK\n", count)
                }
        }
   }
   ```
   
   ## What did you expect to see?
   
   Both 127 and 128 items should serialize and deserialize successfully:
   ```
   127 items: OK
   128 items: OK
   ```
   
   ## What did you see instead?
   
   ```
   127 items: OK
   128 items: FAILED - hash 117426198 is not consistent with -938065433 for 
type main.Inner
   ```
   
   ## Root Cause Analysis
   
   The bug is in `struct.go` line 548:
   
   ```go
   if int8(refID) < NotNullValueFlag {
   ```
   
   When `TryPreserveRefId` returns a reference ID >= 128, the `int8` cast 
causes integer overflow:
   - `int8(128)` = `-128` (two's complement overflow)
   - `-128 < -1` (NotNullValueFlag) = `TRUE`
   
   This incorrectly triggers the "reference found" branch, corrupting the 
buffer read position and causing subsequent struct hash reads to fail.
   
   ## Proposed Fix
   
   Change the comparison to use `int32` instead of casting to `int8`:
   
   ```go
   // Before (buggy):
   if int8(refID) < NotNullValueFlag {
   
   // After (fixed):
   if refID < int32(NotNullValueFlag) {
   ```
   
   ## Workaround
   
   Disable reference tracking:
   ```go
   f := fory.New(fory.WithRefTracking(false))
   ```
   
   ## Are you willing to submit a PR?
   
   - [x] I'm willing to submit a PR!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to