fix: decode keys that are quoted because they contain = - #310
Open
MildlyMeticulous wants to merge 1 commit into
Open
fix: decode keys that are quoted because they contain =#310MildlyMeticulous wants to merge 1 commit into
MildlyMeticulous wants to merge 1 commit into
Conversation
encode() already quotes a key containing `=` via safe(), but decode()
matched the key with `[^=]+`, so it split on the `=` inside the quotes.
stringify -> parse silently corrupted both the key and the value:
ini.parse(ini.stringify({ "a=b": "c" })) // { "\"a": "b\"=c" }
Allow a fully-quoted string as the key alternative, falling back to the
old `[^=]+` when the quote is unterminated so unquoted keys are unchanged.
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.
What / Why
encode()anddecode()disagree about keys that contain=, sostringify→parsesilently corrupts both the key and the value.safe()already knows such a key needs quoting:But
decode()matches the key with[^=]+, which cannot cross the quotes:So the
=inside the quoted key is taken as the separator.Steps to Reproduce
Expected:
{ 'a=b': 'c' }Actual:
{ '"a': 'b"=c' }Same for any key containing
=:stringifyparseof that{ 'a=b': 'c' }"a=b"=c{ '"a': 'b"=c' }{ 'key=with=eq': 'v' }"key=with=eq"=v{ '"key': 'with=eq"=v' }{ '=lead': 'v' }"=lead"=v{ '"': 'lead"=v' }{ 'tr=': 'v' }"tr="=v{ '"tr': '"=v' }Keys containing
=are not hypothetical — Windows registry exports, connection strings andPATH-style entries all produce them, and #96 is the section-header form of the same root cause.The fix
Add a fully-quoted string as a first alternative for the key, keeping the group numbering unchanged:
unsafe()already strips the quotes andJSON.parses the result, so nothing else changes.Because the quoted alternative requires a closing quote, an unterminated quote falls through to
[^=]+and behaves exactly as before —'"a=b'still parses to{ '"a': 'b' }. Unquoted keys are untouched:a=b=cstill gives{ a: 'b=c' }.Verification
test/quoted-keys.jsadded: round-trip cases, the nested-section case, the unquoted-key case, and the unterminated-quote case.lib/ini.jsthe new file produces 12 failing assertions; with the fix all pass.npm run lintclean.