Fix correct pointer stride in Query predicate iteration#69
Merged
ObserverOfTime merged 2 commits intoMay 13, 2026
Merged
Conversation
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.
Summary
Maybe from v0.22.4,
Query.<init>innativeMainadvances theTSQueryPredicateStepcursor bynargsraw bytes instead of(nargs + 1) * sizeOf<TSQueryPredicateStep>(), missing both the struct stride (8 bytes on arm64/x86_64) and theDoneterminator. Any pattern with 2+ predicates reads a misaligned step, yielding a bogusvalue_idand throwingIndexOutOfBoundsExceptionagainstcaptureNames/stringValues(terminates the process via Kotlin/Native's unhandled-exception handler).JVM and Android consumers are unaffected. They go through the JNI
Java_..._Querypath which iterates predicates in C and never touches this Kotlin code.Changes
Fix multiplies the advance by
sizeOf<TSQueryPredicateStep>()and includes theDoneterminator, matching thej += nargs + 1Uindex advance one line above.How to reproduce
fwcd/tree-sitter-kotlin/queries/highlights.scmlines 235–246 (commitf66d290) is the only multi-predicate single-pattern block in that grammar's highlights query — and it is what triggers the crash for any downstream Kotlin Multiplatform project that consumestree-sitter-kotlinon an iOS / native target:(Single top-level S-expression rooted at
call_expression= one pattern; both#eq?predicates belong to it.)ts_query_predicates_for_patternreturns eight steps for this pattern (each#eq?isString("eq?") + 2 args + Done):The buggy advance after processing the first predicate puts
tokens3 bytes past the original cursor (instead of the required(3 + 1) * sizeof(TSQueryPredicateStep) = 32bytes), so the second-iteration read oftokens[0]overlaps the still-unread step's bytes and yields a junkvalue_id. Withtree-sitter-kotlin'scaptureNames.size == 84, the corruptedvalue_idhappens to land at 256, producing:Crash terminates the process with
SIGABRT(Kotlin/NativeterminateWithUnhandledException).256 / 84is grammar-specific. Other grammars produce different ratios but the sameIndexOutOfBoundsExceptionthrown againstcaptureNames[someBogusId].Unit Test
I added da6a728 and confirmed
./gradlew ktreesitter:macosArm64Test -qfailed. After fix: ccd2870, the test passed on local dev.