Skip to content

Start the NOP skip of Advance and AdvanceIter at the NOP - #10

Merged
asp24 merged 1 commit into
masterfrom
fix-nop-skip
Oct 11, 2026
Merged

asp24 merged 1 commit into
masterfrom
fix-nop-skip

Conversation

@asp24

@asp24 asp24 commented Oct 11, 2026

Copy link
Copy Markdown
Member

Advance and AdvanceIter skipped one word too many after a NOP. #9 found this error and did not change it. This PR corrects it.

The error

DeleteElems, SetNull and Deserialize write NOPs. They count the skip of a NOP from the NOP itself. AdvanceInto, PeekNext, NextElementBytes and MarshalJSON read it in the same way. Advance and AdvanceIter counted it from the word after the NOP.

Because of this, ForEach, Interface, FindKey and the helpers of Array lost or misread elements after a NOP:

document edit read with Array.ForEach before after
[1,2,3,4] DeleteElems removes 2 [1] [1,3,4]
[true,false,null,true] DeleteElems removes false [true,true] [true,null,true]
[1.5,2,3] SetNull on 1.5 the value word of 2 read as a tag [null,2,3]

Upstream has the same code.

The change

  • Advance and advanceIter, the slow path of AdvanceIter, start the skip at the NOP.
  • A skip of 0 now comes back to the same NOP. Advance cannot return an error, and it goes to the end, as AdvanceInto does. AdvanceIter already returned an error for it.
  • The common path of each function does not change, because it does not read NOPs.
  • The README adds the correction to the list of differences from upstream.

Testing

nop_skip_test.go edits documents with DeleteElems and SetNull, also after a round trip through Serialize and Deserialize. It reads each document through Advance, AdvanceIter, ForEach, Interface, FindKey and Array.MarshalJSON. It compares each result with encoding/json. MarshalJSON of the document and Object.Map were correct before, and they are the control.

  • Before this change, the test failed on all readers except the control.
  • Four intentional errors in the correction each made a test fail. Without the check for a skip of 0, the test stops at its timeout.
  • The references in advance_diff_test.go had the same error, and they get the same correction.
  • FuzzParse, FuzzCorrect and FuzzSerialize ran for one minute each, with no failure.

🤖 Generated with Claude Code

DeleteElems, SetNull and Deserialize write NOPs. They count the skip of a
NOP from the NOP itself. AdvanceInto, PeekNext, NextElementBytes and
MarshalJSON read it in the same way. Advance and AdvanceIter counted it
from the word after the NOP, and they skipped one word too many.

Because of this, ForEach, Interface, FindKey and the helpers of Array lost
or misread elements after a NOP. For example, DeleteElems removed 2 from
[1,2,3,4], and then Array.ForEach gave only 1. SetNull on the first value
of [1.5,2,3] made Advance read the value word of 2 as a tag. Upstream has
the same code.

A skip of 0 now comes back to the same NOP. Advance cannot return an
error, and it goes to the end, as AdvanceInto does. AdvanceIter already
returned an error for it.

nop_skip_test.go edits documents with DeleteElems and SetNull, also after
a round trip through Serialize and Deserialize. It reads them through
Advance, AdvanceIter, ForEach, Interface, FindKey and Array.MarshalJSON,
and compares each result with encoding/json. MarshalJSON of the document
and Object.Map were correct before, and they are the control. Before this
change, the test failed on all of the other readers. Four intentional
errors in the correction each made a test fail.

The references in advance_diff_test.go had the same error, and they get
the same correction. In foreach_diff_test.go, the write that replaces a
NOP now counts its skip from the NOP too.

The common path of each function does not change, because it does not
read NOPs.
@asp24
asp24 merged commit 69998b2 into master Oct 11, 2026
11 checks passed
@asp24
asp24 deleted the fix-nop-skip branch October 11, 2026 19:43
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