Skip to content

Commit e440017

Browse files
committed
Fix bugs and add tests for variant parsing
The following cases are now handled properly: - "false" (yeah, really) - integers in octal / hexadecimal format - empty dictionaries with inferred type information
1 parent 03f41e1 commit e440017

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

variant_lexer.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ func varLexNormal(l *varLexer) lexState {
155155
l.emit(tokBool)
156156
continue
157157
}
158-
} else if l.pos+5 <= len(l.input) {
158+
}
159+
if l.pos+5 <= len(l.input) {
159160
if l.input[l.pos:l.pos+5] == "false" {
160161
l.pos += 5
161162
l.emit(tokBool)

variant_parser.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,13 @@ func varNumAs(s string, sig Signature) (interface{}, error) {
220220
return nil, varTypeError{s, sig}
221221
}
222222
base := 10
223-
if strings.HasPrefix(s, "0") {
224-
base = 8
225-
}
226223
if strings.HasPrefix(s, "0x") {
227224
base = 16
225+
s = s[2:]
226+
}
227+
if strings.HasPrefix(s, "0") && len(s) != 1 {
228+
base = 8
229+
s = s[1:]
228230
}
229231
if isUnsigned {
230232
i, err := strconv.ParseUint(s, base, size)
@@ -615,8 +617,8 @@ func (n dictNode) Sigs() sigSet {
615617
func (n dictNode) Value(sig Signature) (interface{}, error) {
616618
set := n.Sigs()
617619
if set.Empty() {
618-
// no type intofmation -> empty dict
619-
return reflect.MakeMap(typeFor(sig.str)), nil
620+
// no type information -> empty dict
621+
return reflect.MakeMap(typeFor(sig.str)).Interface(), nil
620622
}
621623
if !set[sig] {
622624
return nil, varTypeError{n.String(), sig}

variant_test.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@ var variantParseTests = []struct {
3434
v interface{}
3535
}{
3636
{"1", int32(1)},
37-
{`"foo"`, "foo"},
3837
{"true", true},
38+
{"false", false},
3939
{"1.0", float64(1.0)},
40+
{"0x10", int32(16)},
41+
{"1e1", float64(10)},
42+
{`"foo"`, "foo"},
43+
{`"\a\b\f\n\r\t"`, "\x07\x08\x0c\n\r\t"},
44+
{`"\u00e4\U0001f603"`, "\u00e4\U0001f603"},
4045
{"[1]", []int32{1}},
4146
{"[1, 2, 3]", []int32{1, 2, 3}},
4247
{"@ai []", []int32{}},
@@ -48,11 +53,12 @@ var variantParseTests = []struct {
4853
{`[[], [""]]`, [][]string{{}, {""}}},
4954
{`@a{ss} {}`, map[string]string{}},
5055
{`{"foo": 1}`, map[string]int32{"foo": 1}},
56+
{`[{}, {"foo": "bar"}]`, []map[string]string{{}, {"foo": "bar"}}},
5157
{`{"a": <1>, "b": <"foo">}`,
5258
map[string]Variant{"a": MakeVariant(int32(1)), "b": MakeVariant("foo")}},
5359
{`b''`, []byte{0}},
5460
{`b"abc"`, []byte{'a', 'b', 'c', 0}},
55-
{`b"\x01\0002\n"`, []byte{1, 2, '\n', 0}},
61+
{`b"\x01\0002\a\b\f\n\r\t"`, []byte{1, 2, 0x7, 0x8, 0xc, '\n', '\r', '\t', 0}},
5662
{`[[0], b""]`, [][]byte{{0}, {0}}},
5763
{"int16 0", int16(0)},
5864
{"byte 0", byte(0)},

0 commit comments

Comments
 (0)