diff --git a/unmarshaler_test.go b/unmarshaler_test.go index 3e3b2a3..d832ea7 100644 --- a/unmarshaler_test.go +++ b/unmarshaler_test.go @@ -759,6 +759,62 @@ huey = 'dewey' } }, }, + { + desc: "basic string hex escape lowercase letter", + input: `A = "\x61"`, + gen: func() test { + type doc struct { + A string + } + + return test{ + target: &doc{}, + expected: &doc{A: "a"}, + } + }, + }, + { + desc: "basic string hex escape null byte", + input: `A = "\x00"`, + gen: func() test { + type doc struct { + A string + } + + return test{ + target: &doc{}, + expected: &doc{A: "\x00"}, + } + }, + }, + { + desc: "basic string hex escape max value", + input: `A = "\xFF"`, + gen: func() test { + type doc struct { + A string + } + + return test{ + target: &doc{}, + expected: &doc{A: "\u00FF"}, + } + }, + }, + { + desc: "multiline basic string hex escape", + input: `A = """\x61"""`, + gen: func() test { + type doc struct { + A string + } + + return test{ + target: &doc{}, + expected: &doc{A: "a"}, + } + }, + }, { desc: "spaces around dotted keys", input: "a . b = 1", @@ -3260,6 +3316,18 @@ world'`, desc: `invalid escape char basic multiline string`, data: `A = """\z"""`, }, + { + desc: `invalid hex escape non-hex character in basic string`, + data: `A = "\xGG"`, + }, + { + desc: `incomplete hex escape in basic string`, + data: `A = "\x6"`, + }, + { + desc: `invalid hex escape non-hex character in multiline basic string`, + data: `A = """\xGG"""`, + }, { desc: `invalid inf`, data: `A = ick`, diff --git a/unstable/parser.go b/unstable/parser.go index d48e07f..1a08397 100644 --- a/unstable/parser.go +++ b/unstable/parser.go @@ -785,6 +785,13 @@ func (p *Parser) parseMultilineBasicString(b []byte) ([]byte, []byte, []byte, er builder.WriteByte('\t') case 'e': builder.WriteByte(0x1B) + case 'x': + x, err := hexToRune(atmost(token[i+1:], 2), 2) + if err != nil { + return nil, nil, nil, err + } + builder.WriteRune(x) + i += 2 case 'u': x, err := hexToRune(atmost(token[i+1:], 4), 4) if err != nil { @@ -944,6 +951,13 @@ func (p *Parser) parseBasicString(b []byte) ([]byte, []byte, []byte, error) { builder.WriteByte('\t') case 'e': builder.WriteByte(0x1B) + case 'x': + x, err := hexToRune(token[i+1:len(token)-1], 2) + if err != nil { + return nil, nil, nil, err + } + builder.WriteRune(x) + i += 2 case 'u': x, err := hexToRune(token[i+1:len(token)-1], 4) if err != nil {