]> git.eshelyaron.com Git - emacs.git/commit
Fix treesit crash (bug#71681)
authorYuan Fu <casouri@gmail.com>
Sat, 29 Jun 2024 07:16:36 +0000 (00:16 -0700)
committerEshel Yaron <me@eshelyaron.com>
Mon, 1 Jul 2024 07:49:25 +0000 (09:49 +0200)
commit54ad478bad32ec34c5eea9a912195f446f72f571
tree80e4e8a543a7b9bb77cb5dc30780518460763674
parent6499d583601b4a01cdbc8c4e2ebd2add06dc1e47
Fix treesit crash (bug#71681)

To reproduce the problem:

0. emacs -Q
1. eval: (add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
2. C-x v L
3. in the *vc-change-log* buffer move point to the commit 20af58d3a13
4. type D
5. crash caused by diff-font-lock-syntax fontification that uses treesit

Emacs: 6f2036243f2 (2024-06-23, latest master)
Tree-sitter: 3da7deed (2024-06-08, version 0.22.6)

The immediate cause of the crash is that tree-sitter accessed a node's
tree, but the tree is already deleted.  Commenting out the
ts_tree_delete line in treesit_ensure_parsed can "fix" the crash.

What happended, I think, is this:

1. Buffer modified, parser->need_reparse set to true,
parser->timestamp incremented.
2. A node is created from the parser, this node has the old tree but
the new timestamp (bad!).
3. Parser re-parses (treesit_ensure_parsed), new tree created, old
tree deleted.
4. Ftreesit_query_capture accessed the old node, and the old tree,
crash.

We shouldn't bump the parser timestamp when we set
parser->need_reparse to true; instead, we should bump the timestamp
when we actually reparsed and created a new tree.

* src/treesit.c (treesit_record_change): Don't bump parser timestamp.
(treesit_sync_visible_region): Don't bump parser timestamp.
(Ftreesit_parser_set_included_ranges): Don't bump parser timestamp.
(treesit_ensure_parsed): Bump parser timestamp.
(Ftreesit_query_capture): Add node check.

(cherry picked from commit 8819e5a45d503b62c38e6310ceda9266606cd6d1)
src/treesit.c