Reject keys that are invalid for an explicit bare or literal key type - #630
Open
choudhryfrompak wants to merge 1 commit into
Open
choudhryfrompak wants to merge 1 commit into
choudhryfrompak wants to merge 1 commit into
Conversation
SingleKey only escapes basic keys. When a caller passes t=KeyType.Bare or
t=KeyType.Literal, the key text was written between the delimiters as-is,
so a key containing a newline, "=", a quote or a dot changed the structure
of the dumped document instead of being one key:
doc.add(SingleKey('user = "x"\nadmin', KeyType.Bare), True)
dumps(doc) # 'user = "x"\nadmin = true\n'
Raise ValueError when the key cannot be written in the requested form:
bare keys must be non-empty and use only A-Za-z0-9_-, and literal keys
must not contain a single quote or a control character other than tab
(the same rule as single-line literal strings). Keys built by the parser
pass their original text and are not affected, nor are keys whose type
is chosen automatically.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SingleKeyonly escapes basic keys. If you passt=KeyType.Bareort=KeyType.Literalyourself, the key text goes between the delimiters as is. A newline,=, a quote or a dot in the key then changes the structure of the dumped document:That parses back as
{'user': 'x', 'admin': True, 'x': 1, 'evil': {'y': 2}}, not as two keys. Same on 0.15.1 from PyPI.With this change
SingleKeyraisesValueErrorwhen an explicit type can't represent the key. A bare key has to be non-empty and use onlyA-Za-z0-9_-. A literal key can't contain'or a control character other than tab, which is the ruleStringType.SLL.invalid_sequencesalready has for literal strings. Basic keys were already escaped and haven't changed. Keys from the parser passoriginaland skip the check, and so do keys whose type is picked automatically (tomlkit.key(),doc["..."],table.add("...")). I moved the bare character check into a small_is_bare_key()helper so the automatic choice and the new check use the same rule.This can break code that used
KeyType.Bareto write a dotted header on purpose, e.g.SingleKey("tool.poetry", t=KeyType.Bare). I found that in one small project on GitHub. It already gave an inconsistent document (doc.unwrap()has a"tool.poetry"key while the output parses as nested tables), andtable(is_super_table=True)gives the same[tool.poetry]header properly. If you'd rather keep dots allowed for bare keys, I can relax it.Tests are in
tests/test_items.py: invalid bare and literal keys raise, and valid keys of each explicit type round-trip throughparse. The 8 rejection cases fail on master. The full suite passes with the toml-test submodule checked out (1080 passed, 1068 before), and ruff and ruff-format are clean on the changed files.