diff --git a/decode.go b/decode.go index b5423d1c..54b02604 100644 --- a/decode.go +++ b/decode.go @@ -651,12 +651,12 @@ func (d *decoder) scalar(n *Node, out reflect.Value) bool { return true } case float64: - if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { + if !isDuration && resolved >= math.MinInt64 && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { out.SetInt(int64(resolved)) return true } case string: - if out.Type() == durationType { + if isDuration { d, err := time.ParseDuration(resolved) if err == nil { out.SetInt(int64(d)) @@ -682,7 +682,7 @@ func (d *decoder) scalar(n *Node, out reflect.Value) bool { return true } case float64: - if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { + if resolved >= 0 && resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { out.SetUint(uint64(resolved)) return true } diff --git a/decode_test.go b/decode_test.go index 4ec7893c..fc0c9ffe 100644 --- a/decode_test.go +++ b/decode_test.go @@ -441,6 +441,22 @@ var unmarshalTests = []struct { "int_overflow: 9223372036854775808", // math.MaxInt64 + 1 map[string]int{}, }, + { + "int_max_float: 2147483647.0", + map[string]int{"int_max_float": math.MaxInt32}, + }, + { + "int_min_float: -2147483648.0", + map[string]int{"int_min_float": math.MinInt32}, + }, + { + "int_overflow_float: 9223372036854777856.0", // math.Nextafter(math.MaxInt64, math.Inf(1)) + map[string]int{}, + }, + { + "int_underflow_float: -9223372036854777856.0", // math.Nextafter(math.MinInt64, math.Inf(-1)) + map[string]int{}, + }, // int64 { @@ -496,7 +512,11 @@ var unmarshalTests = []struct { map[string]uint64{"uint64_maxint64": math.MaxInt64}, }, { - "uint64_underflow: -1", + "uint64_underflow_int: -1", + map[string]uint64{}, + }, + { + "uint64_underflow_float: -1.0", map[string]uint64{}, },