Skip to content

fix: unescape escape sequences in double-quoted section header keys - #458

Open
gaoflow wants to merge 1 commit into
uiri:masterfrom
gaoflow:fix-section-key-unescape
Open

fix: unescape escape sequences in double-quoted section header keys#458
gaoflow wants to merge 1 commit into
uiri:masterfrom
gaoflow:fix-section-key-unescape

Conversation

@gaoflow

@gaoflow gaoflow commented Jun 24, 2026

Copy link
Copy Markdown

Bug

TOML spec §2.4 (Keys) says quoted keys follow
the same escaping rules as basic strings. The section-header parsing loop in
decoder.py stripped surrounding quotes from double-quoted key names but never
called _unescape(). As a result escape sequences like \t, \n, \r, and
\\ were left as literal backslash-letter pairs.

import toml, tomllib   # tomllib is the stdlib reference implementation

toml_str = '["a\\tb"]'  # key should contain a tab character

key_toml    = list(toml.loads(toml_str).keys())[0]
key_tomllib = list(tomllib.loads(toml_str).keys())[0]

print(len(key_toml))    # 4  ("a" + "\" + "t" + "b") — wrong
print(len(key_tomllib)) # 3  ("a" + TAB  + "b")       — correct

The same _unescape() call that load_line already makes for inline
double-quoted keys (line 769) was simply missing for section-header keys.

Fix

In toml/decoder.py, the quoted-key stripping inside the group-name loop
now calls _unescape() for double-quoted key names. Single-quoted keys
are left unchanged (TOML spec: literal, no escaping).

Tests

Added test_section_header_key_escape_sequences which checks \t, \n,
\r, and \\ against the stdlib tomllib reference. All 25 tests pass.

This pull request was prepared with the assistance of AI, under my direction and review.

TOML spec §2.4 (Keys) says quoted keys follow the same escaping rules as
basic strings.  The section-header parsing loop stripped surrounding quotes
from double-quoted key names (line 451 of decoder.py) but never called
`_unescape()`, leaving sequences like `\t`, `\n`, `\r`, and `\\` as
literal backslash-letter pairs instead of their decoded equivalents.

The same call to `_unescape()` that `load_line` already makes for inline
double-quoted keys (line 769) is now applied consistently to
section-header keys.  Single-quoted keys are unaffected: they remain
literal per TOML spec.

Fixes: double-quoted section header keys containing `\t`, `\n`, `\r`, or
`\\` returning the wrong string (one extra backslash character per escape
sequence compared to the correct stdlib `tomllib` result).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant