diff --git a/cty/value_ops.go b/cty/value_ops.go index 8c37535c..8c42e795 100644 --- a/cty/value_ops.go +++ b/cty/value_ops.go @@ -1283,9 +1283,7 @@ func (val Value) AsBigFloat() *big.Float { } // Copy the float so that callers can't mutate our internal state - ret := *(val.v.(*big.Float)) - - return &ret + return new(big.Float).Copy(val.v.(*big.Float)) } // AsValueSlice returns a []cty.Value representation of a non-null, non-unknown diff --git a/cty/value_ops_test.go b/cty/value_ops_test.go index 4261a35d..6ae36e63 100644 --- a/cty/value_ops_test.go +++ b/cty/value_ops_test.go @@ -3432,3 +3432,18 @@ func TestHasWhollyKnownType(t *testing.T) { }) } } + +func TestFloatCopy(t *testing.T) { + // ensure manipulating floats does not modify the cty.Value + v := NumberFloatVal(1.9) + vString := v.GoString() + + // do something that will modify the internal big.Float mantissa + f := v.AsBigFloat() + i, _ := f.Int(nil) + f.SetInt(i) + + if vString != v.GoString() { + t.Fatalf("original value changed from %s to %#v", vString, v) + } +}