Unbounded recursion on nested parse may cause crashes

Author: mgajdaCreated Aug 2, 2026Updated Sep 3, 2026
Labelsc-libraryparser

Problem

Four functions in the core C library recurse once per level of tree nesting. A tiny, deeply nested document will overflow the stack and crash.

The functions are: ts_subtree__print_dot_graph, ts_node_child_with_descendant, ts_subtree_has_trailing_empty_descendant, ts_node_child_by_field_id.

ts_node_string has already been fixed in #5622.

For default stack depth of 8MiB this is unlikely, but my search script found four real-world examples that have 2-3k nesting levels:

Steps to reproduce

Build&run:

rust
use std::fs::File;
use tree_sitter::{Parser, Language};

fn main() {
    let language = Language::new(tree_sitter_javascript::LANGUAGE);
    let mut parser = Parser::new();
    parser.set_language(&language).unwrap();

    // ~200 KB of nested parentheses.
    let depth = 100_000;
    let source = format!("{}1{}", "(".repeat(depth), ")".repeat(depth));
    let tree = parser.parse(&source, None).unwrap();

    // stack overflow in print_dot_graph
    let file = File::create("/dev/null").unwrap();
    tree.print_dot_graph(&file);

}

Expected behavior

Printing the dot graph of any document should complete without overflowing the stack.

Tree-sitter version (tree-sitter --version)

master as of 2026-08-02 (963b5a5), version 0.27.0. Present in v0.26.11 as well.

Operating system/version

Linux (kernel 7.0.0-28-generic, x86_64).

Disclosure

This issue was written by human based on LLM-assisted PR. Numbers and links were generated by scripts generated by AI.