Return errors when decoding negative numbers to unsigned integers.
diff --git a/mapstructure.go b/mapstructure.go index 381ba5d..9fceaef 100644 --- a/mapstructure.go +++ b/mapstructure.go
@@ -51,6 +51,7 @@ // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F, // FALSE, false, False. Anything else is an error) // - empty array = empty map and vice versa + // - negative numbers to overflowed uint values (base 10) // WeaklyTypedInput bool @@ -319,11 +320,21 @@ switch { case dataKind == reflect.Int: - val.SetUint(uint64(dataVal.Int())) + i := dataVal.Int() + if i < 0 && !d.config.WeaklyTypedInput { + return fmt.Errorf("cannot parse '%s', %d overflows uint", + name, i) + } + val.SetUint(uint64(i)) case dataKind == reflect.Uint: val.SetUint(dataVal.Uint()) case dataKind == reflect.Float32: - val.SetUint(uint64(dataVal.Float())) + f := dataVal.Float() + if f < 0 && !d.config.WeaklyTypedInput { + return fmt.Errorf("cannot parse '%s', %f overflows uint", + name, f) + } + val.SetUint(uint64(f)) case dataKind == reflect.Bool && d.config.WeaklyTypedInput: if dataVal.Bool() { val.SetUint(1)
diff --git a/mapstructure_test.go b/mapstructure_test.go index 036e6b5..1444b13 100644 --- a/mapstructure_test.go +++ b/mapstructure_test.go
@@ -658,6 +658,42 @@ if derr.Errors[0] != "'Vstring' expected type 'string', got unconvertible type 'int'" { t.Errorf("got unexpected error: %s", err) } + + inputNegIntUint := map[string]interface{}{ + "vuint": -42, + } + + err = Decode(inputNegIntUint, &result) + if err == nil { + t.Fatal("error should exist") + } + + derr, ok = err.(*Error) + if !ok { + t.Fatalf("error should be kind of Error, instead: %#v", err) + } + + if derr.Errors[0] != "cannot parse 'Vuint', -42 overflows uint" { + t.Errorf("got unexpected error: %s", err) + } + + inputNegFloatUint := map[string]interface{}{ + "vuint": -42.0, + } + + err = Decode(inputNegFloatUint, &result) + if err == nil { + t.Fatal("error should exist") + } + + derr, ok = err.(*Error) + if !ok { + t.Fatalf("error should be kind of Error, instead: %#v", err) + } + + if derr.Errors[0] != "cannot parse 'Vuint', -42.000000 overflows uint" { + t.Errorf("got unexpected error: %s", err) + } } func TestMetadata(t *testing.T) {