@@ -95,9 +95,31 @@ impl LayerData {
95
95
parser
96
96
. set_included_ranges ( & self . ranges )
97
97
. map_err ( |_| Error :: InvalidRanges ) ?;
98
- let tree = parser
99
- . parse ( source, self . parse_tree . as_ref ( ) )
100
- . ok_or ( Error :: Timeout ) ?;
98
+
99
+ // HACK:
100
+ // This is a workaround for a bug within the lexer (in the C library) or maybe within
101
+ // tree-sitter-markdown which needs more debugging. When adding a new range to a combined
102
+ // injection and passing the old tree, if the old tree doesn't already cover a wider range
103
+ // than the newly added range, some assumptions are violated in the lexer and it tries to
104
+ // access some invalid memory, resulting in a segfault. This workaround avoids that
105
+ // situation by avoiding passing the old tree when the old tree's range doesn't cover the
106
+ // total range of `self.ranges`.
107
+ //
108
+ // See <https://github.com/helix-editor/helix/pull/12972#issuecomment-2725410409>.
109
+ let tree = self . parse_tree . as_ref ( ) . filter ( |tree| {
110
+ let included_ranges_range = self . ranges . first ( ) . map ( |r| r. start_byte ) . unwrap_or ( 0 )
111
+ ..self . ranges . last ( ) . map ( |r| r. end_byte ) . unwrap_or ( u32:: MAX ) ;
112
+ // Allow re-parsing the root layer even though the range is larger. The root always
113
+ // covers `0..u32::MAX`:
114
+ if included_ranges_range == ( 0 ..u32:: MAX ) {
115
+ return true ;
116
+ }
117
+ let tree_range = tree. root_node ( ) . byte_range ( ) ;
118
+ tree_range. start <= included_ranges_range. start
119
+ && tree_range. end >= included_ranges_range. end
120
+ } ) ;
121
+
122
+ let tree = parser. parse ( source, tree) . ok_or ( Error :: Timeout ) ?;
101
123
self . parse_tree = Some ( tree) ;
102
124
Ok ( ( ) )
103
125
}
0 commit comments