fix(query): correct last_child_step_index in cases where a new step wasn't created.#4422
Merged
WillLillis merged 1 commit intotree-sitter:masterfrom May 3, 2025
Merged
Conversation
clason
approved these changes
May 2, 2025
wasn't created. This fixes an OOB access to `self.steps` when a last child anchor immediately follows a predicate.
amaanq
approved these changes
May 3, 2025
|
Successfully created backport PR for |
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.
The Problem
Not 100% confident I have the root cause, but here's the basic idea:
The full query:
(call_expression function: (scoped_identifier path: (scoped_identifier (identifier) @_regex (#any-of? @_regex "Regex" "RegexBuilder") .)) (#set! injection.language "regex"))For the stack frame that causes the OOB access, we're inside the for loop here:
tree-sitter/lib/src/query.c
Lines 2477 to 2487 in bfc5d11
and the start of the stream is pointing to
(#any-of? @_regex "Regex" "RegexBuilder")...... Further down in the loop's body,step_indexstores the value ofself-steps.sizehere:tree-sitter/lib/src/query.c
Lines 2518 to 2525 in bfc5d11
The recursive call to
ts_query__parse_patternimmediately after parses the predicate(#any-of? @_regex "Regex" "RegexBuilder"). Parsing the predicate did not push new entries toself->steps, so whenlast_child_step_indexis assigned tostep_indexfollowing that call, it now indexes past the end ofself->steps. The loop runs again, and this time it parses the anchor, here:tree-sitter/lib/src/query.c
Lines 2511 to 2516 in bfc5d11
After this, another recursive call to
ts_query__parse_patternreturns immediately withPARENT_DONE, since the stream now points to). The first 3ifconditions following the recursive call are satisfied, so we then use the out of boundslast_child_step_indexto index intoself->steps.contents, causing the UB.The Solution
Add a simple check for this case, decrementing
step_indexbefore its assignment tolast_child_step_indexif necessary.