From 71a8bd4c619876a9195e237ab6ea6b4b2a5d5467 Mon Sep 17 00:00:00 2001 From: x-hgg-x <39058530+x-hgg-x@users.noreply.github.com> Date: Mon, 4 May 2020 19:30:08 +0200 Subject: [PATCH] Prevent automatic conversion between int and float when unmarshaling (#390) Fixes #389 Co-authored-by: Thomas Pelletier --- marshal.go | 6 +++--- marshal_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/marshal.go b/marshal.go index c688532..e8b5db5 100644 --- a/marshal.go +++ b/marshal.go @@ -985,7 +985,7 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *ref } return reflect.ValueOf(d), nil } - if !val.Type().ConvertibleTo(mtype) { + if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Float64 { return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) } if reflect.Indirect(reflect.New(mtype)).OverflowInt(val.Convert(reflect.TypeOf(int64(0))).Int()) { @@ -995,7 +995,7 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *ref return val.Convert(mtype), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: val := reflect.ValueOf(tval) - if !val.Type().ConvertibleTo(mtype) { + if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Float64 { return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) } @@ -1009,7 +1009,7 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *ref return val.Convert(mtype), nil case reflect.Float32, reflect.Float64: val := reflect.ValueOf(tval) - if !val.Type().ConvertibleTo(mtype) { + if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Int64 { return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) } if reflect.Indirect(reflect.New(mtype)).OverflowFloat(val.Convert(reflect.TypeOf(float64(0))).Float()) { diff --git a/marshal_test.go b/marshal_test.go index cb9f7ee..1a51755 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -2023,6 +2023,43 @@ func TestUnmarshalCamelCaseKey(t *testing.T) { } } + +func TestUnmarshalNegativeUint(t *testing.T) { + type check struct{ U uint } + + tree, _ := Load("u = -1") + err := tree.Unmarshal(&check{}) + if err.Error() != "(1, 1): -1(int64) is negative so does not fit in uint" { + t.Error("expect err:(1, 1): -1(int64) is negative so does not fit in uint but got:", err) + } +} + +func TestUnmarshalCheckConversionFloatInt(t *testing.T) { + type conversionCheck struct { + U uint + I int + F float64 + } + + treeU, _ := Load("u = 1e300") + treeI, _ := Load("i = 1e300") + treeF, _ := Load("f = 9223372036854775806") + + errU := treeU.Unmarshal(&conversionCheck{}) + errI := treeI.Unmarshal(&conversionCheck{}) + errF := treeF.Unmarshal(&conversionCheck{}) + + if errU.Error() != "(1, 1): Can't convert 1e+300(float64) to uint" { + t.Error("expect err:(1, 1): Can't convert 1e+300(float64) to uint but got:", errU) + } + if errI.Error() != "(1, 1): Can't convert 1e+300(float64) to int" { + t.Error("expect err:(1, 1): Can't convert 1e+300(float64) to int but got:", errI) + } + if errF.Error() != "(1, 1): Can't convert 9223372036854775806(int64) to float64" { + t.Error("expect err:(1, 1): Can't convert 9223372036854775806(int64) to float64 but got:", errF) + } +} + func TestUnmarshalOverflow(t *testing.T) { type overflow struct { U8 uint8