Commit Graph
665 Commits
Author SHA1 Message Date
Martin Vogel 684045708f test(cypher): regression guards for #240/#237/#252/#305 (already supported)
Confirmed working in the current query_graph evaluator and locked in:
- #240 labels() function with AS alias
- #237 DISTINCT applied before ORDER BY + LIMIT
- #252 toInteger()
- #305 count(*) with AS alias

Closes #240. Closes #237. Closes #252. Closes #305.
2026-05-31 12:38:05 +02:00
Martin Vogel 2de984bdb6 fix(discover): map .mjs/.cjs (JS) and .mts/.cts (TS) extensions (#197)
.mjs (ES modules) and .cjs (CommonJS) were absent from the extension
table, so those files were never assigned a language — they weren't
indexed (no graph nodes) and search_code returned 0 for any pattern in
them. Add .mjs/.cjs → JavaScript and .mts/.cts → TypeScript.

Verified end-to-end: a function in a .mjs file is now extracted and found
by search_code. Closes #197.
2026-05-31 12:10:29 +02:00
Martin Vogel 48a9b2c2a9 test(c-lsp): regression for #220 (C++ CALLS attributed to function)
#220: C++ CALLS edges originated from the Module node instead of the
enclosing Function, breaking function-level trace_path. The cross-LSP
resolver now sets caller_qn = enclosing_func_qn; the test asserts a call
(doWork→helper) is attributed to doWork, not the module.

Closes #220.
2026-05-31 11:57:50 +02:00
Martin Vogel 53be053d3f fix(search): treat wildcard-free file_pattern as a path substring (#200)
search_graph file_pattern always returned 0 for a bare name like
"offer-server": cbm_glob_to_like produced the literal "offer-server",
so `file_path LIKE 'offer-server'` only matched a path equal to it, never
"src/offer-server/x.js". When the pattern contains no glob wildcards
(* or ?), wrap the LIKE as %pattern% so it matches anywhere in the path.
Explicit globs keep their semantics.

Closes #200.
2026-05-31 11:48:25 +02:00
Martin Vogel bf3fc711bc test(extraction): regression guards for #382 (Java annotations) + #213 (large TS)
#382 — Java Method nodes now carry decorators (@GetMapping) and a non-empty
signature; verified by extract_java_method_annotations_issue382.
#213 — a 256 KB / 4000-function TS file now yields Function nodes instead of
a childless File node (fixed by the tree-sitter read-buffer padding);
verified by extract_large_ts_has_functions_issue213.

Closes #382. Closes #213.
2026-05-31 03:25:48 +02:00
Martin Vogel 7e4745ddd1 test(py-lsp): regression for #228 (cross-file classmethod on class)
#228: a class/static method invoked on a cross-file imported class name
(ActionRecordX.build_from_text(...)) produced no CALLS edge, so the
method looked like dead code (in/out degree 0). The v0.7.0 py_lsp
cross-file resolver handles this; the test feeds the exact pattern through
cbm_run_py_lsp_cross and asserts the call resolves.

Closes #228.
2026-05-31 03:14:17 +02:00
Martin Vogel d0e1e77825 ci: remove temporary bucket-B repro harness
The #336 (Icinga2/Linux) and #385 (KiCad/Windows) reproductions are done —
both index cleanly on v0.7.0 on their reported platforms. Removing the
throwaway workflow.
2026-05-31 00:51:14 +02:00
Martin Vogel 6c6b8c82b8 ci(temp): build bucket-B repro inline per-platform (avoid macos infra cancel)
The reused _build.yml builds all platforms; a cancelled macos-15-intel
runner skipped the icinga2/kicad index jobs. Build inline in each job so
the Linux (#336) and Windows (#385) repros don't depend on unrelated
platforms. Still temporary — delete after the run.
2026-05-31 00:42:46 +02:00
Martin Vogel d848347c61 test(ts-lsp): scale regression for #344/#340 (lsp_cross >1189 defs)
Issues #344/#340 reported a scale-dependent SIGSEGV in the TS cross-file
LSP pass once the collected def array exceeded ~1189 entries. The v0.7.0
cross-LSP rewrite registers defs through the arena (no fixed-size def
array), so the threshold no longer exists. This test drives
cbm_run_ts_lsp_cross with a 4000-entry def array under -fsanitize=address
and resolves cleanly, locking in the fix.

Closes #344. Closes #340.
2026-05-31 00:34:29 +02:00
Martin Vogel c6c1d77c43 ci(temp): bucket-B crash repro harness (#336 icinga2 / #385 kicad)
Temporary workflow_dispatch harness: builds current-main binaries and
indexes Icinga2 on Linux (fast) and KiCad on Windows (moderate) to check
whether the reported crashes still reproduce on v0.7.0. To be removed
after the run.
2026-05-31 00:24:57 +02:00
Martin Vogel ba49137165 test(c-lsp): xxhash-header extraction guard (issue #355 proxy)
Issue #355 reported a segfault extracting a macro-heavy xxhash C header
(dhw/xx_hash.h, not available to us). Add a guard that runs the vendored
xxhash.h (~7.5k lines, same macro-dense family) through C extraction under
ASan. It passes on current main — the C-LSP crash hardening (#322/#323/
#360) appears to cover this class. Kept as a regression guard; #355 stays
open pending the reporter's confirmation/file.
2026-05-30 23:44:10 +02:00
Martin Vogel de069d117e test(mcp): ASan regression for issue #235 (bad-project buffer overflow)
Passing an unrecognised project name triggered a buffer overflow while
building the available-projects error list: collect_db_project_names did
snprintf(out+offset, out_sz-offset, ...) with no bound, so once the
listed names exceeded the 4 KB projects buffer, (out_sz - offset)
underflowed (unsigned) to a huge size and snprintf wrote past the buffer.

Fixed in 21c73b5 (PR #352) with an offset>=out_sz bounds check + clamp.
This test fills a temp CBM_CACHE_DIR with 40 long-named .db files
(~5 KB of names) and issues a bad-project search_graph call; the test
build runs under -fsanitize=address so the old underflow would abort here.

Closes #235.
2026-05-30 23:34:00 +02:00
Martin Vogel 7dafde46dc test(c-lsp): regression for issue #312 (defaulted template param + auto)
A C++ function template with a defaulted type param and an `auto`
parameter, called with matching arg count, previously segfaulted in the
definitions pass (unbound `U` flowed through type substitution as NULL).
Fixed by the cbm_type_substitute NULL-preservation guard; this locks in
a reproduction so it can't regress.

Closes #312.
2026-05-30 23:21:35 +02:00
DeusData 25ba4472d5 Delete docs/TS_LSP_INTEGRATION_PLAN.md 2026-05-30 23:14:46 +02:00
DeusData fd5cbedd1a Delete docs/PLAN_PHP_LSP_INTEGRATION.md 2026-05-30 23:14:26 +02:00
DeusData eea63b2f27 Delete docs/CROSS_FILE_ARCHITECTURE.md 2026-05-30 23:14:16 +02:00
DeusData 19be397b05 Delete docs/PHP_LSP_PRE_FLIGHT.md 2026-05-30 23:14:03 +02:00
DeusData 8767740322 Delete PYTHON_LSP_PLAN.md 2026-05-30 23:13:39 +02:00
Martin Vogel bcf73b29e8 fix(pkgmap): make repo-wide manifest walk POSIX-only (Windows hang)
The full-repo manifest walk added for workspace-import resolution hung
the Windows CI test-runner (pipeline_structure_nodes): pkgmap_walk_dir
uses plain stat() on Windows (no lstat/S_ISLNK), so directory junctions
in the walked tree can be followed into cycles, never terminating.

Make cbm_pkgmap_scan_repo a no-op on Windows and compile pkgmap_walk_dir
only on POSIX. Windows falls back to the files[]-based pkgmap (the
pre-batch baseline behavior). Workspace-import resolution from
discovery-ignored manifests (package.json) is therefore Linux/macOS-only
until the walk is made junction-safe on Windows (follow-up).
2026-05-30 21:03:48 +02:00
Martin Vogel 34864c8c7e test(platform): use cbm_setenv/cbm_unsetenv for Windows portability
The CBM_WORKERS env tests called bare setenv/unsetenv, which are
POSIX-only and undeclared on the MSYS2 Windows test build. Switch to the
cbm_setenv/cbm_unsetenv compat wrappers (a no-op #define to setenv on
POSIX) and include foundation/compat.h. Fixes the test-windows build.
2026-05-30 20:15:30 +02:00
Martin Vogel fcf98acf8d fix(portability+format): Windows pkgmap stat; clang-format distilled passes
- pass_pkgmap: lstat/S_ISLNK are POSIX-only and undeclared on the MSYS2
  Windows build. Guard them under #ifndef _WIN32 (plain stat on Windows,
  where symlinks aren't a concern here). Fixes the Windows build break
  introduced by the workspace-manifest walker.
- Run clang-format-20 over str_util.c, store.c, mcp.c, pipeline.c,
  pass_route_nodes.c, pass_pkgmap.c so the recently-landed pkgmap / route /
  security passes satisfy the lint gate.
2026-05-30 19:34:27 +02:00
Ivan Porto Carrero 9e2bb92895 fix(arena): NULL-arena guard in cbm_arena_alloc; skip vendored/ dirs
- cbm_arena_alloc returns NULL on a NULL arena (both arena.c copies)
  instead of dereferencing it — defense-in-depth against the NULL-arena
  type-allocation path that could crash the LSP type layer.
- discover: add "vendored" to the always-skip directory list.

Distilled from #374, taking the parts not already on main. The PR's
ts_lsp tuple-arena allocation, the C/C++ template formal-count clamp,
and the type_rep unbound-param preservation it also carried all landed
independently in v0.7.0 / via #322 / #360, so only these two
defensive improvements remain. Relates to #390.
2026-05-30 18:26:44 +02:00
utilia-ai-wox 9bcfaabe4c fix(pkgmap+routes): resolve workspace imports + extract SvelteKit routes
Two structural fixes for TS monorepos (pnpm/yarn workspaces) and
SvelteKit projects, measured to take a 885-file SvelteKit+Turborepo repo
from 319 edges to 31802 (100x) with no fixture regressions.

- pkgmap: package.json / composer.json live in IGNORED_JSON_FILES, so the
  manifest-driven pkgmap builders never saw them and every
  '@my/pkg' workspace import was silently dropped. Add a symlink-safe,
  skip-dir-aware filesystem walker (cbm_pkgmap_scan_repo /
  cbm_pkgmap_build_from_repo) that harvests manifests directly from the
  repo regardless of the discovery filter. Sequential and parallel paths
  both feed it now.
- definitions: extract every file's defs (creating Module nodes) BEFORE
  resolving imports, so a workspace import in the first file can resolve
  against the complete in-memory graph (two-phase, cache-backed).
- routes: synthesise Route nodes + HANDLES edges from SvelteKit's
  filesystem layout (+server / +page.server / +layout.server), which has
  no app.get(...) call site for pass_calls to pick up.

Distilled from #369 onto current main. The PR's CBM_DISABLE_LSP_CROSS
escape hatch was rebased onto the v0.7.0 fused cross-LSP architecture:
it now gates run_cross_lsp (NULL all_defs makes the fused resolver no-op
cross-file resolution) instead of wrapping the removed standalone
pass_lsp_cross call. Relates to #271 / #56.
2026-05-30 18:15:47 +02:00
jjserenity 2389d82214 fix(windows): use wide-char API for non-ASCII path support (#386)
Replace ANSI Windows APIs (FindFirstFileA, CreateFileA, etc.) with
wide-char (W) counterparts. Add UTF-8/UTF-16 conversion helpers.
Fix stat() calls in discover pipeline to use _wstat64.

Fixes #357
2026-05-30 18:05:03 +02:00
jjserenityandHC Cheng a6ad4011ed fix(store): checkpoint WAL on close and startup to prevent orphan accumulation (#387)
Add WAL checkpoint on store close and after WAL-mode enable at startup.
This ensures graceful shutdown leaves a clean WAL, and crash recovery
merges stale WAL on next open. Both use PASSIVE mode (non-blocking,
no ftruncate). Best-effort — silently skip if concurrent reader holds
a lock.

Fixes #277

Co-authored-by: HC Cheng <hz.chang@pm.me>
2026-05-30 17:54:52 +02:00
Sam Li a5a3d1d60a feat(platform): cgroup-aware CPU/memory detection in detect_system_linux
Inside a container, sysconf(_SC_NPROCESSORS_ONLN) and sysinfo() report
the host's CPU count and RAM, not the cgroup's effective quota — so
cbm_default_worker_count over-provisions workers and the mmap budget can
exceed the cgroup memory cap, driving OOMKills (#363).

detect_system_linux now reads the cgroup limits:
- cbm_detect_cgroup_cpus: cgroup v2 cpu.max, then v1 cpu.cfs_quota_us /
  cpu.cfs_period_us → ceil(quota/period); -1 when unlimited.
- cbm_detect_cgroup_mem: cgroup v2 memory.max, then v1
  memory.limit_in_bytes; 0 when unlimited or the v1 near-ULLONG_MAX
  sentinel.
- Effective value is min(cgroup, host), guarding against mis-mounted
  cgroups that report more than the host.

Helpers read via a bounded read_small_file (fopen "re", capped fread)
and are exposed through system_info_internal.h for unit tests that drive
them against a fake cgroup tree. The test teardown uses opendir/unlink/
rmdir (no shell spawn).

Distilled from #365 onto current main (unioned the test additions with
the CBM_WORKERS tests from #364, and replaced the test-cleanup
system("rm -rf") with a shell-free recursive remove). Closes #363
together with #364.
2026-05-30 17:47:18 +02:00
yangsec888 d95223817e feat(platform): CBM_WORKERS env override for cbm_default_worker_count
Adds a CBM_WORKERS env knob (clamped to [1, 256], invalid values warned
and ignored) that explicitly sets the parallel-indexing worker count.
In containers, sysconf(_SC_NPROCESSORS_ONLN) reports host CPUs rather
than the cgroup's effective quota, so a 1-vCPU pod on a 16-core node
otherwise spawns ~16 workers — the dominant OOMKill driver. When unset,
behaviour is unchanged.

From #364.
2026-05-30 17:32:47 +02:00
Smiie-2 d895c16553 fix(c-lsp): prevent segfault on nested C++ template calls with default args
Root cause: unbound template parameters flowed through cbm_type_substitute
as NULL, and call-expression return handling then dereferenced the NULL
substituted type. Reproduced on MangoHud's src/hud_elements.cpp.

- type_rep: cbm_type_substitute now returns the original param `t` (not
  NULL) when a type arg is unbound, in both the TYPE_PARAM and named-param
  paths — unbound params stay intact instead of poisoning the type.
- c_lsp: guard `if (!ret) return cbm_type_unknown();` before unwrapping
  the substituted return type; guard the substitute result before use; add
  template_function call-node resolution (qualified/scoped/plain names).
- extract_defs: factor template-inner lookup into find_cpp_template_inner_node,
  which recurses into nested template_declarations and also handles
  field_declaration; reuse it from unwrap_template_inner.
- tests: clsp_nocrash_template_function_multi_param_nested_call (the nested
  reproducer) and typerep_substitute_unbound_param_preserved.

Distilled from #360 onto current main. The formal-parameter-count clamp
that overlapped this PR already landed via #322, so only the additive
crash fixes are taken here. Contributes to the C++ stability cluster (#390;
relates to #215/#312).
2026-05-30 17:30:01 +02:00
Code Analyzer 21c73b57f1 fix: security and correctness hardening from codebase audit
- str_util: add cbm_validate_project_name() — strict allowlist
  ([A-Za-z0-9._-], no leading dot, no '..', no path separators) so a
  project name can never escape the cache directory.
- store/mcp/http_server: validate project names (fail-closed) before
  interpolating them into .db file paths (path-traversal hardening;
  defense-in-depth for the wrong-path class in #331).
- store: fix use-after-free in the LIKE pool — like_pool_add() frees its
  argument when the pool is full, so capture pool_was_full before the add
  and skip the subsequent bind that would touch the freed pointer (two
  call sites). Also fix the find_edges_by_url_path LIKE pattern (stray
  double-percent) and add NULL guards to cbm_store_checkpoint /
  cbm_store_node_degree / cbm_store_restore_from.
- mcp: emit "result": null when a JSON-RPC response would otherwise
  carry neither result nor error (2.0 compliance); bounds-check the
  project-name accumulator against truncation.
- http_server: JSON-escape directory and parent names in the browse
  endpoint to prevent stored-XSS/JSON injection via crafted names.
- cypher: expr_free now recurses on EXPR_FREE_STACK overflow instead of
  silently dropping subtrees (memory leak).

Distilled from #352 onto current main (store.c like-pool hunk re-resolved
against the v0.7.0 search refactor; restored cypher.c EOF newline).
2026-05-30 17:19:56 +02:00
Christof Meerwald 9d6e28bccf feat: add support for MCP ping (#354) 2026-05-30 17:10:03 +02:00
Christof Meerwald 2e110fc54c Use CLOCK_MONOTONIC if available (#342) 2026-05-30 17:09:48 +02:00
jjoos 4d84406921 fix(extraction): convert fixed-size stacks in extract_channels.c to growable TSNodeStack
The 8 channel-extraction DFS walkers (Python consts, Python, Go, Java,
C#, Ruby, Elixir, Rust) used fixed-size `TSNode stack[CHAN_STACK_CAP]`
arrays whose push loops guarded with `&& top < CHAN_STACK_CAP`. On
deeply-nested ASTs that guard silently dropped children, and an
unguarded overflow could corrupt adjacent stack memory — surfacing as a
segfault in a later pass (lsp_cross / semantic_edges) on large repos.

Convert all 8 to the arena-backed growable TSNodeStack
(ts_nstack_init/push/pop), matching the pattern already used in
extract_calls.c / extract_imports.c (PR #217). No silent drops, no
overflow.

Distilled from #339 (trailing-newline cleanup only; conversion is the
author's).
2026-05-30 17:02:06 +02:00
dependabot[bot] 4fd6e1bd27 ci(deps): bump actions/setup-python from 5.6.0 to 6.2.0 (#329)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.6.0 to 6.2.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/a26af69be951a213d495a4c3e4e4022e16d87065...a309ff8b426b58ec0e2a45f0f869d46889d02405)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-30 15:52:46 +02:00
dependabot[bot] 694652fc72 ci(deps): bump sigstore/cosign-installer from 4.1.1 to 4.1.2 (#328)
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 4.1.1 to 4.1.2.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003...6f9f17788090df1f26f669e9d70d6ae9567deba6)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 4.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-30 15:52:17 +02:00
dependabot[bot] 5c743e8e62 ci(deps): bump github/codeql-action from 4.35.2 to 4.36.0 (#368)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.2 to 4.36.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/95e58e9a2cdfd71adc6e0353d5c52f41a045d225...7211b7c8077ea37d8641b6271f6a365a22a5fbfa)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-30 15:52:06 +02:00
Alexey Z df38e331ca fix(windows): use cmd.exe-compatible syntax for git-log history pass
The git-history popen command used `cd '%s' && git log ... 2>/dev/null`,
which fails on Windows cmd.exe: single quotes are not recognized and
/dev/null is not a valid path, producing "The filename, directory name,
or volume label syntax is incorrect" at the git-history step of a full
index. Switch to `git -C "%s" log ... 2>NUL` (POSIX: 2>/dev/null),
which is valid on both cmd.exe and POSIX shells. Double-quoting the path
is safe because cbm_validate_shell_arg already rejects ", $, backtick,
backslash and the other active metacharacters before the command is built.

Distilled from #325 onto current main (preserves the :%%ct commit-time
field added since the PR branch). Closes #324.
2026-05-30 15:51:09 +02:00
Romano 926eb7f9d1 fix(c-lsp): cap expression type evaluation steps (#323)
Adds a per-file expression-eval step budget (10k) to the C/C++ LSP resolver so pathological recovery-mode ASTs degrade to unknown instead of hanging indexing (the Bitcoin-derived C++ repro). Verified locally: build clean, all 3,617 tests pass including the full clsp_ suite.
2026-05-30 15:41:05 +02:00
Romano 05f0a26b2f fix(c-lsp): guard pending template call resolution (#322)
Fixes the OOB read in c_resolve_pending_template_calls when a call site has more arguments than the parsed function signature (issue #215). Verified locally: build clean, all 3,617 tests pass including the new clsp_nocrash_template_extra_call_args regression.
2026-05-30 15:32:06 +02:00
Shane McCarron dedd33d975 fix(install): respect $CLAUDE_CONFIG_DIR in install/uninstall/update
Route Claude Code config paths (skills, .mcp.json, .claude.json,
settings.json, hook scripts) and agent detection through
CLAUDE_CONFIG_DIR-aware helpers, falling back to ~/.claude. Hook command
strings written to settings.json keep the legacy tilde form when the env
var is unset, so existing configs stay portable across HOME values. Prints
a one-line migration nudge when CLAUDE_CONFIG_DIR is set and a legacy
~/.claude tree still exists.

Adds cli_detect_agents_finds_claude_via_env and isolates CLAUDE_CONFIG_DIR
in the existing detection tests so the runner env can't leak in.

Distilled from #321 onto current main (adapts to the v0.7.0 non-blocking
augmenter hook signature, which the original branch predated). Closes #320.
2026-05-30 15:22:37 +02:00
Martin Vogel afd98bfc7f docs(readme): v0.7.0 — add Hybrid LSP section, refresh badges and VT scans
- New top-level "Hybrid LSP" section above "Language Support" with a
  short explanation of why tree-sitter alone is insufficient, what the
  clean-room LSP layer does, a per-language coverage table (Python,
  TS/JS/JSX/TSX, PHP, C#, Go, C/C++) marking what's new in v0.7.0 and
  what was sharpened, and the two-layer architecture.
- Hero paragraph + indexing-pipeline bullet now list the full v0.7.0
  Hybrid-LSP language set and link to the new section.
- Tests badge bumped 2812 → 3615 (from the ubuntu-latest CI log of the
  published v0.7.0 release run).
- New "Hybrid LSP — 6 languages" badge linking to the new section.
- VirusTotal click-through badge + per-binary scans table refreshed to
  the v0.7.0 binaries (linux-amd64/arm64, darwin-amd64/arm64,
  windows-amd64) using the hashes from the published release body.
2026-05-30 14:23:47 +02:00
Martin Vogel b133a204d2 release: bump pkg/npm + pkg/pypi to v0.7.0
The release.yml workflow publishes both wrappers as-is from the repo;
they were still pinned to 0.6.1, which made the npm publish step try to
republish v0.6.1 instead of v0.7.0.
0.7.0 v0.7.0
2026-05-30 01:15:58 +02:00
Martin Vogel 82d5c841e6 fix(parallel): destroy thread parser before slab reclaim in LSP-cross loop
The LSP-cross loop in parallel_resolve called cbm_slab_reclaim() without
first destroying the thread-local tree-sitter parser, violating the
documented slab contract. The parser's lexer holds slab-allocated state
(notably lexer.included_ranges, a 24-byte allocation that lands in the
≤64B slab bucket); reclaiming the slab leaves that pointer dangling.

Workers don't trip on it because they don't reparse afterward, but the
main thread participates in cbm_parallel_for and any later cbm_extract_file
on the main thread — including the sequential pass_definitions in the
incremental pipeline — hits a heap-use-after-free in ts_lexer_goto on
macOS-ASan.

Two-part fix:
- pass_parallel.c: destroy the thread parser before cbm_slab_reclaim() in
  the per-file LSP-cross loop, matching the worker extract loop.
- pass_definitions.c: defensively drop the thread parser at pass entry so
  the incremental sequential path cannot inherit stale state from any
  prior run.
2026-05-29 23:11:52 +02:00
Martin Vogel 297003aab4 fix(test): use __SANITIZE_ADDRESS__ alone for sanitizer detection (gcc-portable)
GCC's preprocessor doesn't short-circuit 'defined(__has_feature) && __has_feature(...)' — it tries to parse the call syntax of the undefined token and errors with 'missing binary operator before token "("'. Modern GCC and Clang both define __SANITIZE_ADDRESS__ under -fsanitize=address, so use that single check.
2026-05-29 22:30:03 +02:00
Martin Vogel d5211f6ae0 chore: remove release-notes file (consumed via workflow input, not a repo doc) 2026-05-29 22:26:36 +02:00
Martin Vogel 130b707b35 release: v0.7.0 notes; make LSP-bench tests sanitizer-aware
Free the result before the time-budget assert (no leak on miss) and scale the budget ×10 when ASan/UBSan is active, so the perf benches run cleanly in the release CI (skip_perf=false) instead of only being gated by CBM_SKIP_PERF in dry-run.
2026-05-29 21:58:54 +02:00
Martin Vogel 90e85bb10c fix: pad source read buffers in all parse passes (tree-sitter lookahead)
Same fix as read_file in pass_definitions: the calls/usages/semantic/k8s/lsp_cross passes each read a source file into a malloc'd buffer and re-parse it, so they hit the same tree-sitter lexer over-read past EOF under ASan. Over-allocate by 16 and zero the tail in every reader.
2026-05-29 06:00:44 +02:00
Martin Vogel c023931014 fix: pad source read buffer for tree-sitter lookahead (ASan over-read)
read_file allocated size+1, but tree-sitter's lexer peeks a few bytes past the final UTF-8 char (ts_lexer_goto), reading past the buffer end. Under ASan this is a heap-buffer-overflow (intermittently flagged in the incremental suite on macOS); in production it is a benign over-read of adjacent heap. Over-allocate by 16 bytes and zero the tail so the lookahead stays in-bounds.
2026-05-29 05:57:19 +02:00
Martin Vogel 3bcbc59136 test: size path_alias temp-dir buffer for cbm_mkdtemp (Windows)
cbm_mkdtemp rewrites the template in place to the translated %TEMP% path on Windows, which overflowed the 23-byte 'char tmpl[]' literal (ASan stack-buffer-overflow). Use a 256-byte buffer as the cbm_mkdtemp contract requires (matching the other test callers).
2026-05-29 04:20:20 +02:00
Martin Vogel 7bf3aa86a0 test: use portable temp dir/paths so Windows unit tests pass
Four tests hardcoded POSIX /tmp/ paths that don't exist on Windows: test_path_alias used raw mkdtemp("/tmp/...") and the store pragma/checkpoint tests built /tmp/*.db directly. Switch to cbm_mkdtemp (translates /tmp/ -> %TEMP% on Windows) and cbm_tmpdir() (matching test_store_bulk). build/smoke/soak-windows already pass; this makes the Windows unit-test job green too.
2026-05-29 03:37:56 +02:00
Martin Vogel ef25ca0727 style: wrap cbm_strndup call in path_alias.c for clang-format-20
The strndup->cbm_strndup rename pushed the line past the column limit; reflow to satisfy the clang-format-20 lint check.
2026-05-29 02:54:00 +02:00