Commit Graph
7 Commits
Author SHA1 Message Date
SivanColaandJuly-X 174ea10844 refactor: harden parsers with maintained libraries
Replace several hand-rolled parsers and text processors with maintained libraries while preserving Reasonix-specific policy boundaries and fallbacks.

Add focused regression coverage for shell argv policy, HTML extraction, frontmatter decoding, dotenv parsing, glob matching, diff output, grapheme clipping, and optional tree-sitter code indexing.

Co-authored-by: July-X <[email protected]>
2026-07-04 01:11:34 +08:00
SivanCola 7377f46239 fix(diff): avoid input-derived Myers allocation arithmetic (#3777) 2026-06-09 21:27:49 -07:00
YHHandreasonix f55aa476c5 fix(diff): clamp the Myers edit-distance operands to bound the allocation (#3775)
Follow-up to #3773: that cleared the n+m addition alert, but CodeQL still
flagged the 2*maxD allocation (go/allocation-size-overflow) because it
doesn't propagate maxD's bound through the guarded sum. Clamp each line
count to maxDiffEdits before summing, so the sum and the 2*maxD allocation
both have constant-bounded operands. maxD stays min(n+m, maxDiffEdits).

Co-authored-by: reasonix <[email protected]>
2026-06-09 20:54:58 -07:00
YHHandreasonix 1fe5f2c69e fix(diff): compute the Myers n+m bound only when it can't overflow (#3773)
CodeQL go/allocation-size-overflow (high) flagged `n + m` flowing into
`make([]int, 2*maxD+1)`: a pathological line count could overflow the
addition before the downstream clamp. The result was already safe (the
clamp caught a wrapped-negative maxD), but the addition itself still
tripped the query. Restructure to maxD = min(n+m, maxDiffEdits) with the
sum taken only when n and m are within the cap — no overflow at the
operation, identical bound.

Co-authored-by: reasonix <[email protected]>
2026-06-09 20:43:55 -07:00
YHHandreasonix 175d43d43d fix(security): resolve open code-scanning alerts (archive extraction, command injection, untrusted checkout, integer bounds) (#3718)
* @
fix(codegraph): resolve symlinks when extracting third-party bundle

The lexical tar/zip-slip guard missed the symlink-redirect escape: an
in-bounds symlink extracted as a parent component lets a later entry be
written through it to land outside the cache dir. Resolve the real parent
with EvalSymlinks before validating, and judge a symlink target from its
resolved location. Closes the go/unsafe-unzip-symlink + go/zipslip alerts.
@

* @
fix(scripts): run gh without a shell in backfill-issue-labels

execSync built a shell command string from interpolated values; switch to
execFileSync with an argv array so label and issue arguments can never be
parsed as shell. Closes the js/command-line-injection alert.
@

* @
ci(e2e-bot): gate untrusted PR-head run behind an environment

Running PR-head code with the provider secret was guarded only by the
author_association check. Add an `e2e-bot` deployment environment (configure
required reviewers to force per-run approval) and pin the checkout to the
head commit resolved at trigger time, detached, so a mid-run force-push
cannot swap in different code. Addresses actions/untrusted-checkout-toctou.
@

* @
fix: bound integer conversions flagged by code scanning

parseHexColor parses single bytes; parse them as 8-bit unsigned and return
int so the per-channel value is provably in range, dropping the
int64->int conversions at the call sites. Clamp the Myers maxD against a
negative n+m overflow too, so make() can never see a wrapped size.
@

---------

Co-authored-by: reasonix <[email protected]>
2026-06-09 17:02:45 -07:00
reasonix 731875700f fix(diff): cap Myers edit distance so a large rewrite can't OOM the preview
The Myers trace stores O(D) snapshots of an O(D)-wide vector, so the edit
distance D drives O(D²) ≈ O(N²) time and memory: a full rewrite of a 3000-line
file allocated ~565 MB, ~6 GB at 10k lines — enough to OOM the synchronous
write-preview/checkpoint diff. Cap D at 2000 edits: small changes converge well
below it (so a tiny edit in a huge file still gets a real diff), while a near-
total rewrite falls back to cheap order-insensitive tallies and an omitted-diff
marker instead of a gigabyte allocation. A 6000-line rewrite now costs 63 MB.
2026-06-01 06:29:01 -07:00
esengine fc60496676 feat(core): desktop-harness foundations — diff preview, introspection, config writes, per-agent workdir
Four reusable harness capabilities a desktop front-end needs, all additive and
independent of the agent loop / TUI (agent.go, chat_tui.go, cli.go untouched):

- diff: Myers line-diff engine (internal/diff) + a tool.Previewer optional
  capability. write_file/edit_file/multi_edit can now compute the change a call
  WOULD make (unified diff, +N/-M, create/modify) without touching disk, for
  approval cards and changed-files panels. A consistency test asserts the
  preview matches what Execute persists, so the two can't drift.

- inspect: read-only projection of providers (with key readiness), tools
  (builtin vs mcp, read-only, previewable, schema), MCP servers/prompts/
  resources, and slash commands into JSON-ready structs for a settings UI.

- config: programmatic, validated mutation surface (SetDefaultModel,
  Upsert/RemoveProvider, SetPlannerModel, permission-rule edits, Upsert/
  RemovePlugin) plus an atomic SaveTo, separate from the init wizard.

- builtin.Workspace: binds the built-in tools to a working directory so
  concurrent agents (e.g. desktop tabs on different projects) get independent
  path roots. A zero workDir is byte-identical to today's process-cwd behavior.
2026-05-29 19:23:44 -07:00