Repository navigation
Fix Delete matching keys that contain a backslash - #293
Open
waw666waw666 wants to merge 1 commit into
Open
waw666waw666 wants to merge 1 commit into
waw666waw666 wants to merge 1 commit into
Conversation
findKeyStart, which Delete uses to find the key of the last path element,
JSON-unescaped the path key before comparing it with the (unescaped) keys
in the document. Get, Set and EachKey compare the path as is, so for a
path with a backslash Delete looked for a different key than Get:
Delete(`{"a\\b":1}`, `a\b`) left the key in place, because `\b` became a
backspace.
Worse, the unescaped path key lived in the same stack buffer that is
then used to unescape each escaped key in the document, so the first
escaped key of the same length overwrote it and compared equal to
itself. Delete then cut from that earlier key to the end of the real
value: Delete(`{"\"q":1,"keep":0,"a\\b":2}`, `a\b`) returned {}.
Compare the path key as is, like searchKeys does.
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.
Description:
DeleteandDeleteFoundtreat a path key that contains a backslash differently fromGet,SetandEachKey, and in one case delete the wrong part of the document.Cause:
findKeyStartConfig, whichDeleteuses for the last path element, JSON-unescapes the path key before comparing it with the document's keys.searchKeys(used byGet,Set,EachKey) compares the path as is against the unescaped document key, and the existing Get tests rely on that ({"a\\b":1}is found with the patha\b). So inDelete,\bin the path turned into a backspace and the key was not found.The unescaped path key was also stored in the same
stackbufthat is then used to unescape each escaped key of the document. The first escaped key of the same length overwrote the path key and so compared equal to itself, andfindKeyStartreturned its offset. The value end still came frominternalGetwith the real path, soDeletecut from the earlier key through the end of the matched value, removing every member in between.Fix: compare the path key as is in
findKeyStartConfig, likesearchKeysdoes. That removes both the mismatch and the shared buffer.Tests: added cases to
deleteTests(escaped key, Unicode-escaped key, an earlier escaped key of the same length at top level and nested, and a path that only equals the escaped form of a key). Three of them fail on master and pass with this change.go vetshows no new findings andgofmtis clean for the changed lines. The fullgo test ./...result is the same as on master:TestOracleSetPr286Regressionalready fails on master, and #290 looks related.Benchmark before change:
Benchmark after change:
(
go test -bench JsonParserDel -benchmem ./benchmark/, arm64. The time numbers are noisy on this machine. The drop in allocations is consistent:stackbufno longer escapes, because the path key isn't stored in it anymore.)