diff --git a/CHANGELOG.md b/CHANGELOG.md index b8262f68..0ecd1756 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to sem are documented in this file. ## [Unreleased] +### Fixed + +- **Building a graph over Svelte components no longer crashes (SIGSEGV) on Linux/glibc.** `sem graph`/`context`/`orient` over `.svelte` files deterministically exited 139 from an invalid free in the `tree-sitter-htmlx-svelte` 0.1.8 grammar's scanner, hit during parallel graph construction (macOS's allocator tolerated the bad free, so it only showed on Linux). Bumped the grammar to 0.1.16, which carries the scanner fixes; the existing version constraint already permitted it, so this is a lock-only dependency update. Added a parallel-Svelte-graph regression test. Thanks @XF-FW for the exhaustive isolation and the verified fix (#471). + ## [0.21.0] - 2026-07-10 ### Added diff --git a/crates/Cargo.lock b/crates/Cargo.lock index ea86e8bf..48e3239e 100644 --- a/crates/Cargo.lock +++ b/crates/Cargo.lock @@ -2262,9 +2262,9 @@ dependencies = [ [[package]] name = "tree-sitter-htmlx-svelte" -version = "0.1.8" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3259693b6c5f6a7044de1a8142507aa1950406a4b124ffaab28c9050e30973dd" +checksum = "f3278db98d220cb32e1d82510036740786c817afc1224b3360658f499224e63c" dependencies = [ "cc", "tree-sitter", diff --git a/crates/sem-core/tests/graph_accuracy.rs b/crates/sem-core/tests/graph_accuracy.rs index cd3d3d6f..dd7f57e9 100644 --- a/crates/sem-core/tests/graph_accuracy.rs +++ b/crates/sem-core/tests/graph_accuracy.rs @@ -201,3 +201,73 @@ fn graph_accuracy_rust() { ); assert!(tp > 0, "Should find at least some expected edges"); } + +/// Regression for issue #471: building a graph over multiple Svelte components +/// in parallel triggered a SIGSEGV (invalid free) in the +/// tree-sitter-htmlx-svelte 0.1.8 grammar's scanner on Linux/glibc. Fixed by +/// bumping the grammar to 0.1.16. On macOS the bad free was tolerated by the +/// allocator, so this only fails on Linux/glibc CI; everywhere it at least +/// exercises the parallel Svelte parse path that used to crash. +#[test] +fn graph_svelte_parallel_no_crash_issue_471() { + let tmp = tempfile::tempdir().unwrap(); + let root = tmp.path(); + + for args in [ + vec!["init"], + vec!["config", "user.email", "test@test.com"], + vec!["config", "user.name", "Test"], + ] { + std::process::Command::new("git") + .args(&args) + .current_dir(root) + .output() + .unwrap(); + } + + // Enough components that the parallel (rayon) graph build parses several + // .svelte files concurrently, which is where the grammar crashed. + let component = r#" + + + + +"#; + let mut files = Vec::new(); + for i in 0..12 { + let name = format!("Component{i}.svelte"); + std::fs::write(root.join(&name), component).unwrap(); + files.push(name); + } + + std::process::Command::new("git") + .args(["add", "."]) + .current_dir(root) + .output() + .unwrap(); + std::process::Command::new("git") + .args(["commit", "-m", "init"]) + .current_dir(root) + .output() + .unwrap(); + + let registry = create_default_registry(); + // Reaching past this call at all means no SIGSEGV during parallel parsing. + let (graph, _) = EntityGraph::build(root, &files, ®istry); + + // Sanity: the components were actually parsed, not silently skipped. + assert!( + graph.entities.values().any(|e| e.name == "handleLogoClick"), + "expected handleLogoClick entity from parsed .svelte components" + ); +}