file: escape written values the default reader would alter - #389
Open
gaoflow wants to merge 1 commit into
Open
Conversation
WriteTo emitted a value surrounded by matching quotes ("…" or '…')
verbatim, but the default reader strips surrounding quotes, so
Load(WriteTo(v)) != v. The same round-trip broke for values wrapping an
inner quote in whitespace and for values opening with """.
Route these to the raw-string wrapper the reader already inverts, so a
serialized value is read back byte-for-byte. Plain values are untouched.
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.
Describe the pull request
WriteTocan emit a value that its own default reader parses back as a different value, soLoad(WriteTo(v)) != v.writeKeyValuewraps a value only when it contains`/\n(→"""…"""),#/;(→ backtick), or has surrounding whitespace (→"…"). The comment above it says it covers", but there is no branch for a value that is itself surrounded by matching quotes. The default reader strips surrounding quotes (hasSurroundedQuoteinparser.go), so such a value comes back unquoted:This is one root cause — the writer produces a form the default reader re-interprets — with a few faces:
"or'("quoted",'123',"","a b", …) are unquoted on read;_"x"_) breaks the"…"branch, because the reader can't strip a"…"pair that contains another";"""is read as a multi-line wrapper.Fix
Route these through the raw-string (backtick) wrapper the reader already inverts verbatim, so a serialized value is read back byte-for-byte. Plain values, and values that merely contain an interior quote (e.g.
"one", "two"), are untouched.I checked this with a small round-trip census (
SetValue→WriteTo→Load, default options) over the value domain — plain, empty, numeric, leading/trailing space, interior/surrounding quotes,#/;/=,`/\n, and""". Onmain11 of 42 cases were corrupted; after the change 0 of 42 are, and no previously-correct case changed. The regression test covers the corrupt set plus the no-regression boundary (plain values and interior-quote values must stay unwrapped).Checklist