feat: add \xHH escape sequence support in basic strings

TOML v1.1.0 introduces the \xHH escape notation for basic strings,
allowing two-digit hex escapes for Unicode code points U+0000 to
U+00FF.

We keep emitting \u00XX for backwards compatibility.
This commit is contained in:
João Fernandes
2026-02-11 11:04:54 +00:00
parent 2edc61f171
commit 5794be6251
2 changed files with 82 additions and 0 deletions
+68
View File
@@ -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`,
+14
View File
@@ -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 {