Support unmarshaling up to uint64 (#608)

This commit is contained in:
Wendell Sun
2021-09-28 07:11:21 +08:00
committed by GitHub
parent b8ba995eaa
commit c42c3365f3
3 changed files with 31 additions and 25 deletions
+1 -1
View File
@@ -1113,7 +1113,7 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *ref
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
} }
if val.Convert(reflect.TypeOf(int(1))).Int() < 0 { if val.Type().Kind() != reflect.Uint64 && val.Convert(reflect.TypeOf(int(1))).Int() < 0 {
return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String()) return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String())
} }
if reflect.Indirect(reflect.New(mtype)).OverflowUint(val.Convert(reflect.TypeOf(uint64(0))).Uint()) { if reflect.Indirect(reflect.New(mtype)).OverflowUint(val.Convert(reflect.TypeOf(uint64(0))).Uint()) {
+23 -24
View File
@@ -293,42 +293,41 @@ func (p *tomlParser) parseRvalue() interface{} {
return math.NaN() return math.NaN()
case tokenInteger: case tokenInteger:
cleanedVal := cleanupNumberToken(tok.val) cleanedVal := cleanupNumberToken(tok.val)
var err error base := 10
var val int64 s := cleanedVal
checkInvalidUnderscore := numberContainsInvalidUnderscore
if len(cleanedVal) >= 3 && cleanedVal[0] == '0' { if len(cleanedVal) >= 3 && cleanedVal[0] == '0' {
switch cleanedVal[1] { switch cleanedVal[1] {
case 'x': case 'x':
err = hexNumberContainsInvalidUnderscore(tok.val) checkInvalidUnderscore = hexNumberContainsInvalidUnderscore
if err != nil { base = 16
p.raiseError(tok, "%s", err)
}
val, err = strconv.ParseInt(cleanedVal[2:], 16, 64)
case 'o': case 'o':
err = numberContainsInvalidUnderscore(tok.val) base = 8
if err != nil {
p.raiseError(tok, "%s", err)
}
val, err = strconv.ParseInt(cleanedVal[2:], 8, 64)
case 'b': case 'b':
err = numberContainsInvalidUnderscore(tok.val) base = 2
if err != nil {
p.raiseError(tok, "%s", err)
}
val, err = strconv.ParseInt(cleanedVal[2:], 2, 64)
default: default:
panic("invalid base") // the lexer should catch this first panic("invalid base") // the lexer should catch this first
} }
} else { s = cleanedVal[2:]
err = numberContainsInvalidUnderscore(tok.val)
if err != nil {
p.raiseError(tok, "%s", err)
}
val, err = strconv.ParseInt(cleanedVal, 10, 64)
} }
err := checkInvalidUnderscore(tok.val)
if err != nil { if err != nil {
p.raiseError(tok, "%s", err) p.raiseError(tok, "%s", err)
} }
return val
var val interface{}
val, err = strconv.ParseInt(s, base, 64)
if err == nil {
return val
}
if s[0] != '-' {
if val, err = strconv.ParseUint(s, base, 64); err == nil {
return val
}
}
p.raiseError(tok, "%s", err)
case tokenFloat: case tokenFloat:
err := numberContainsInvalidUnderscore(tok.val) err := numberContainsInvalidUnderscore(tok.val)
if err != nil { if err != nil {
+7
View File
@@ -1162,3 +1162,10 @@ str3 = """\
t.Errorf("expected '%s', got '%s'", expected, got) t.Errorf("expected '%s', got '%s'", expected, got)
} }
} }
func TestUint(t *testing.T) {
tree, err := Load("hello = 18446744073709551615")
assertTree(t, tree, err, map[string]interface{}{
"hello": uint64(math.MaxUint64),
})
}