fix(lib): check if an ERROR node is named before assuming it's the builtin error node

(cherry picked from commit b7f36a13ba)
This commit is contained in:
Amaan Qureshi 2025-08-28 14:47:20 -04:00 committed by Christian Clason
parent 1083795af6
commit 22fa144016
4 changed files with 47 additions and 2 deletions

View file

@ -17,7 +17,10 @@ use super::helpers::{
};
use crate::tests::{
generate_parser,
helpers::query_helpers::{collect_captures, collect_matches},
helpers::{
fixtures::get_test_fixture_language,
query_helpers::{collect_captures, collect_matches},
},
ITERATION_COUNT,
};
@ -5697,3 +5700,30 @@ fn test_query_with_predicate_causing_oob_access() {
(#set! injection.language \"regex\"))";
Query::new(&language, query).unwrap();
}
#[test]
fn test_query_with_anonymous_error_node() {
let language = get_test_fixture_language("anonymous_error");
let mut parser = Parser::new();
parser.set_language(&language).unwrap();
let source = "ERROR";
let tree = parser.parse(source, None).unwrap();
let query = Query::new(
&language,
r#"
"ERROR" @error
(document "ERROR" @error)
"#,
)
.unwrap();
let mut cursor = QueryCursor::new();
let matches = cursor.matches(&query, tree.root_node(), source.as_bytes());
let matches = collect_matches(matches, &query, source);
assert_eq!(
matches,
vec![(1, vec![("error", "ERROR")]), (0, vec![("error", "ERROR")])]
);
}

View file

@ -186,7 +186,7 @@ TSSymbol ts_language_symbol_for_name(
uint32_t length,
bool is_named
) {
if (!strncmp(string, "ERROR", length)) return ts_builtin_sym_error;
if (is_named && !strncmp(string, "ERROR", length)) return ts_builtin_sym_error;
uint16_t count = (uint16_t)ts_language_symbol_count(self);
for (TSSymbol i = 0; i < count; i++) {
TSSymbolMetadata metadata = ts_language_symbol_metadata(self, i);

View file

@ -0,0 +1,9 @@
======================
A simple error literal
======================
ERROR
---
(document)

View file

@ -0,0 +1,6 @@
module.exports = grammar({
name: 'anonymous_error',
rules: {
document: $ => repeat(choice('ok', 'ERROR')),
}
});