Skip to content

Commit

Permalink
Merge pull request smacker#76 from smacker/fix-query-cursor-segfault
Browse files Browse the repository at this point in the history
Fix segfault in QueryCursor
  • Loading branch information
smacker authored Jun 28, 2022
2 parents 1191a82 + 7621c20 commit ac06e95
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
3 changes: 3 additions & 0 deletions bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,8 @@ func (q *Query) StringValueForId(id uint32) string {
type QueryCursor struct {
c *C.TSQueryCursor
t *Tree
// keep a pointer to the query to avoid garbage collection
q *Query

isClosed bool
}
Expand All @@ -832,6 +834,7 @@ func NewQueryCursor() *QueryCursor {

// Exec executes the query on a given syntax node.
func (qc *QueryCursor) Exec(q *Query, n *Node) {
qc.q = q
qc.t = n.t
C.ts_query_cursor_exec(qc.c, q.c, n.c)
}
Expand Down
30 changes: 30 additions & 0 deletions bindings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,36 @@ func TestLeakParseInput(t *testing.T) {
assert.Less(t, m.Alloc, uint64(1024*1024))
}

// see https://github.com/smacker/go-tree-sitter/issues/75
func TestCursorKeepsQuery(t *testing.T) {
source := bytes.Repeat([]byte("1 + 1"), 10000)

parser := NewParser()
parser.SetLanguage(getTestGrammar())

tree := parser.Parse(nil, source)
root := tree.RootNode()

for i := 0; i < 100; i++ {
query, _ := NewQuery(
[]byte("(number) @match"),
getTestGrammar(),
)

qc := NewQueryCursor()

qc.Exec(query, root)

for {
// ensure qc.NextMatch() doesn't cause a segfault
match, exists := qc.NextMatch()
if !exists || match == nil {
break
}
}
}
}

func BenchmarkParse(b *testing.B) {
ctx := context.Background()
parser := NewParser()
Expand Down

0 comments on commit ac06e95

Please sign in to comment.