Skip to content
Open
9 changes: 8 additions & 1 deletion math/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,14 @@ func (i *Int) MarshalTo(data []byte) (n int, err error) {
// Unmarshal implements the gogo proto custom type interface.
func (i *Int) Unmarshal(data []byte) error {
if len(data) == 0 {
i = nil
if i == nil {
return errors.New("cannot unmarshal Int into nil receiver")
}
if i.i == nil {
i.i = new(big.Int)
} else {
i.i.SetInt64(0)
}
return nil
}

Expand Down
16 changes: 16 additions & 0 deletions math/int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -692,3 +692,19 @@ func BenchmarkIntOverflowCheckTime(b *testing.B) {
}
sink = nil
}

// TestIntUnmarshalEmpty demonstrates the bug where Unmarshal with empty bytes
// doesn't reset the Int value to zero
func TestIntUnmarshalEmpty(t *testing.T) {
// Create an Int with a non-zero value
i := math.NewInt(12345)
require.Equal(t, int64(12345), i.Int64(), "initial value should be 12345")

// Unmarshal empty bytes - should reset to zero
err := i.Unmarshal([]byte{})
require.NoError(t, err)

// With the bug: i still has value 12345
// After fix: i should be 0
require.True(t, i.IsZero(), "after unmarshaling empty bytes, Int should be zero, but got: %s", i.String())
}