Skip to content

Commit c42c336

Browse files
authored
Support unmarshaling up to uint64 (#608)
1 parent b8ba995 commit c42c336

File tree

3 files changed

+31
-25
lines changed

3 files changed

+31
-25
lines changed

marshal.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *ref
11131113
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
11141114
}
11151115

1116-
if val.Convert(reflect.TypeOf(int(1))).Int() < 0 {
1116+
if val.Type().Kind() != reflect.Uint64 && val.Convert(reflect.TypeOf(int(1))).Int() < 0 {
11171117
return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String())
11181118
}
11191119
if reflect.Indirect(reflect.New(mtype)).OverflowUint(val.Convert(reflect.TypeOf(uint64(0))).Uint()) {

parser.go

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -293,42 +293,41 @@ func (p *tomlParser) parseRvalue() interface{} {
293293
return math.NaN()
294294
case tokenInteger:
295295
cleanedVal := cleanupNumberToken(tok.val)
296-
var err error
297-
var val int64
296+
base := 10
297+
s := cleanedVal
298+
checkInvalidUnderscore := numberContainsInvalidUnderscore
298299
if len(cleanedVal) >= 3 && cleanedVal[0] == '0' {
299300
switch cleanedVal[1] {
300301
case 'x':
301-
err = hexNumberContainsInvalidUnderscore(tok.val)
302-
if err != nil {
303-
p.raiseError(tok, "%s", err)
304-
}
305-
val, err = strconv.ParseInt(cleanedVal[2:], 16, 64)
302+
checkInvalidUnderscore = hexNumberContainsInvalidUnderscore
303+
base = 16
306304
case 'o':
307-
err = numberContainsInvalidUnderscore(tok.val)
308-
if err != nil {
309-
p.raiseError(tok, "%s", err)
310-
}
311-
val, err = strconv.ParseInt(cleanedVal[2:], 8, 64)
305+
base = 8
312306
case 'b':
313-
err = numberContainsInvalidUnderscore(tok.val)
314-
if err != nil {
315-
p.raiseError(tok, "%s", err)
316-
}
317-
val, err = strconv.ParseInt(cleanedVal[2:], 2, 64)
307+
base = 2
318308
default:
319309
panic("invalid base") // the lexer should catch this first
320310
}
321-
} else {
322-
err = numberContainsInvalidUnderscore(tok.val)
323-
if err != nil {
324-
p.raiseError(tok, "%s", err)
325-
}
326-
val, err = strconv.ParseInt(cleanedVal, 10, 64)
311+
s = cleanedVal[2:]
327312
}
313+
314+
err := checkInvalidUnderscore(tok.val)
328315
if err != nil {
329316
p.raiseError(tok, "%s", err)
330317
}
331-
return val
318+
319+
var val interface{}
320+
val, err = strconv.ParseInt(s, base, 64)
321+
if err == nil {
322+
return val
323+
}
324+
325+
if s[0] != '-' {
326+
if val, err = strconv.ParseUint(s, base, 64); err == nil {
327+
return val
328+
}
329+
}
330+
p.raiseError(tok, "%s", err)
332331
case tokenFloat:
333332
err := numberContainsInvalidUnderscore(tok.val)
334333
if err != nil {

parser_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,3 +1162,10 @@ str3 = """\
11621162
t.Errorf("expected '%s', got '%s'", expected, got)
11631163
}
11641164
}
1165+
1166+
func TestUint(t *testing.T) {
1167+
tree, err := Load("hello = 18446744073709551615")
1168+
assertTree(t, tree, err, map[string]interface{}{
1169+
"hello": uint64(math.MaxUint64),
1170+
})
1171+
}

0 commit comments

Comments
 (0)