From 658a88a30991d05ae6386f21834a4058584ab863 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 10 Aug 2023 16:10:38 -0400 Subject: [PATCH] fix(math): defend NewIntFromBigInt argument mutation (#17352) --- math/CHANGELOG.md | 1 + math/int.go | 4 +++- math/int_test.go | 13 +++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/math/CHANGELOG.md b/math/CHANGELOG.md index 6f4d90e3e271..19e2b4f65eab 100644 --- a/math/CHANGELOG.md +++ b/math/CHANGELOG.md @@ -43,6 +43,7 @@ Ref: https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.j ### Bug Fixes +* [#17352](https://github.com/cosmos/cosmos-sdk/pull/17352) Ensure that modifying the argument to `NewIntFromBigInt` doesn't mutate the returned value. * [#16266](https://github.com/cosmos/cosmos-sdk/pull/16266) fix: legacy dec power mut zero exponent precision. ## [math/v1.0.1](https://github.com/cosmos/cosmos-sdk/releases/tag/math/v1.0.1) - 2023-05-15 diff --git a/math/int.go b/math/int.go index b94a38f8352f..e32b8ef3e0e8 100644 --- a/math/int.go +++ b/math/int.go @@ -106,6 +106,7 @@ func NewIntFromUint64(n uint64) Int { // NewIntFromBigInt constructs Int from big.Int. If the provided big.Int is nil, // it returns an empty instance. This function panics if the bit length is > 256. +// Note, the caller can safely mutate the argument after this function returns. func NewIntFromBigInt(i *big.Int) Int { if i == nil { return Int{} @@ -114,7 +115,8 @@ func NewIntFromBigInt(i *big.Int) Int { if i.BitLen() > MaxBitLen { panic("NewIntFromBigInt() out of bound") } - return Int{i} + + return Int{new(big.Int).Set(i)} } // NewIntFromString constructs Int from string diff --git a/math/int_test.go b/math/int_test.go index d9f54da11520..e76cafc577d7 100644 --- a/math/int_test.go +++ b/math/int_test.go @@ -43,6 +43,19 @@ func (s *intTestSuite) TestFromUint64() { } } +func (s *intTestSuite) TestNewIntFromBigInt() { + i := math.NewIntFromBigInt(nil) + s.Require().True(i.IsNil()) + + r := big.NewInt(42) + i = math.NewIntFromBigInt(r) + s.Require().Equal(r, i.BigInt()) + + // modify r and ensure i doesn't change + r = r.SetInt64(100) + s.Require().NotEqual(r, i.BigInt()) +} + func (s *intTestSuite) TestIntPanic() { // Max Int = 2^256-1 = 1.1579209e+77 // Min Int = -(2^256-1) = -1.1579209e+77