Overflow checks
This commit is contained in:
+67
-10
@@ -2,6 +2,7 @@ package toml
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -196,18 +197,70 @@ func setBool(t target, v bool) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const maxInt = int64(^uint(0) >> 1)
|
||||||
|
const minInt = -maxInt - 1
|
||||||
|
|
||||||
func setInt64(t target, v int64) error {
|
func setInt64(t target, v int64) error {
|
||||||
f := t.get()
|
f := t.get()
|
||||||
|
|
||||||
switch f.Kind() {
|
switch f.Kind() {
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int64:
|
||||||
// TODO: overflow checks
|
return t.setInt64(v)
|
||||||
converted := reflect.ValueOf(v).Convert(f.Type())
|
case reflect.Int32:
|
||||||
return t.set(converted)
|
if v < math.MinInt32 || v > math.MaxInt32 {
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
return fmt.Errorf("integer %d does not fit in an int32", v)
|
||||||
// TODO: overflow checks
|
}
|
||||||
converted := reflect.ValueOf(v).Convert(f.Type())
|
return t.set(reflect.ValueOf(int32(v)))
|
||||||
return t.set(converted)
|
case reflect.Int16:
|
||||||
|
if v < math.MinInt16 || v > math.MaxInt16 {
|
||||||
|
return fmt.Errorf("integer %d does not fit in an int16", v)
|
||||||
|
}
|
||||||
|
return t.set(reflect.ValueOf(int16(v)))
|
||||||
|
case reflect.Int8:
|
||||||
|
if v < math.MinInt8 || v > math.MaxInt8 {
|
||||||
|
return fmt.Errorf("integer %d does not fit in an int8", v)
|
||||||
|
}
|
||||||
|
return t.set(reflect.ValueOf(int8(v)))
|
||||||
|
case reflect.Int:
|
||||||
|
if v < minInt || v > maxInt {
|
||||||
|
return fmt.Errorf("integer %d does not fit in an int", v)
|
||||||
|
}
|
||||||
|
return t.set(reflect.ValueOf(int(v)))
|
||||||
|
|
||||||
|
case reflect.Uint64:
|
||||||
|
if v < 0 {
|
||||||
|
return fmt.Errorf("negative integer %d cannot be stored in an uint64", v)
|
||||||
|
}
|
||||||
|
return t.set(reflect.ValueOf(uint64(v)))
|
||||||
|
case reflect.Uint32:
|
||||||
|
if v < 0 {
|
||||||
|
return fmt.Errorf("negative integer %d cannot be stored in an uint32", v)
|
||||||
|
}
|
||||||
|
if v > math.MaxUint32 {
|
||||||
|
return fmt.Errorf("integer %d cannot be stored in an uint32", v)
|
||||||
|
}
|
||||||
|
return t.set(reflect.ValueOf(uint32(v)))
|
||||||
|
case reflect.Uint16:
|
||||||
|
if v < 0 {
|
||||||
|
return fmt.Errorf("negative integer %d cannot be stored in an uint16", v)
|
||||||
|
}
|
||||||
|
if v > math.MaxUint16 {
|
||||||
|
return fmt.Errorf("integer %d cannot be stored in an uint16", v)
|
||||||
|
}
|
||||||
|
return t.set(reflect.ValueOf(uint16(v)))
|
||||||
|
case reflect.Uint8:
|
||||||
|
if v < 0 {
|
||||||
|
return fmt.Errorf("negative integer %d cannot be stored in an uint8", v)
|
||||||
|
}
|
||||||
|
if v > math.MaxUint8 {
|
||||||
|
return fmt.Errorf("integer %d cannot be stored in an uint8", v)
|
||||||
|
}
|
||||||
|
return t.set(reflect.ValueOf(uint8(v)))
|
||||||
|
case reflect.Uint:
|
||||||
|
if v < 0 {
|
||||||
|
return fmt.Errorf("negative integer %d cannot be stored in an uint", v)
|
||||||
|
}
|
||||||
|
return t.set(reflect.ValueOf(uint(v)))
|
||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
return t.set(reflect.ValueOf(v))
|
return t.set(reflect.ValueOf(v))
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
@@ -228,9 +281,13 @@ func setFloat64(t target, v float64) error {
|
|||||||
f := t.get()
|
f := t.get()
|
||||||
|
|
||||||
switch f.Kind() {
|
switch f.Kind() {
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float64:
|
||||||
// TODO: overflow checks
|
|
||||||
return t.setFloat64(v)
|
return t.setFloat64(v)
|
||||||
|
case reflect.Float32:
|
||||||
|
if v > math.MaxFloat32 {
|
||||||
|
return fmt.Errorf("float %f cannot be stored in a float32", v)
|
||||||
|
}
|
||||||
|
return t.set(reflect.ValueOf(float32(v)))
|
||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
return t.set(reflect.ValueOf(v))
|
return t.set(reflect.ValueOf(v))
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
|
|||||||
Reference in New Issue
Block a user