mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-11 23:53:19 -10:00
8f7e4a0748094de92aa17e534bf54839b2cecaab
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d4e11410cb |
perf(gitcmd): skip the driver listing for plumbing that converts no content
Every hardened invocation listed the repository's filter and merge drivers with a second git process first, doubling the process count of host git work. On Windows, where a process start is expensive, that pushed the worktree suite past its 8-minute limit. rev-parse, rev-list, merge-base, the ref commands, write-tree and commit-tree never pass content through a filter or merge driver and never honour submodule.recurse, so any overrides the listing produced were inert for them. They now run without it; every subcommand that can convert content keeps the listing and still fails closed on an unaddressable driver name. |
||
|
|
ec866730e0 |
fix(gitcmd): host git never runs repository-configured programs
Every git invocation the host makes goes through gitcmd, and each one must leave the programs a repository's own configuration names unexecuted: filter and merge drivers, textconv and external diff, fsmonitor, hooks, signature verifiers, submodule-boundary programs and lazy-fetch transport. Driver neutralization now covers every subcommand, not diff alone, and takes driver names from git itself rather than from a separate reading of .git/config. - Fixed keys are overridden with -c: core.fsmonitor (empty, not "false", which git before 2.35.2 reads as a hook name), core.hooksPath, log.showSignature, merge.verifySignatures, diff.submodule, gc.auto and maintenance.auto and safe.bareRepository=explicit; submodule.recurse=false for checkout, switch, restore, reset, merge and read-tree (host branch switches and merges never update submodules, whatever the user's global submodule.recurse), and elsewhere only where the repository's own config sets it. GIT_NO_LAZY_FETCH=1 stops a missing object becoming a fetch through the repository's remote (git 2.44+); a historical patch that fails for that reason returns gitcmd.ErrObjectNotLocal, decided by git's own --missing=print listing. - diff, log and show carry --no-ext-diff and --no-textconv; status and diff carry --ignore-submodules=dirty. The subcommand is found past global options, so a call passing -C inside args is hardened too. - Filter and merge drivers defined at local or worktree scope are listed by git itself before each invocation (includes followed) and overridden empty; user and system scope stay live; a name -c cannot address fails closed (ErrRepositoryDrivers). - worktree add uses --no-checkout and populates through gitcmd inside the new worktree, so a conditional include keyed on the new gitdir or branch is seen by the driver listing there rather than run by the add's checkout. The reset takes the worktree-mutation timeout, and a failed reset removes both the worktree and the branch the add created. worktree remove uses --force after the existing hardened clean-tree check, so git does not run status inside the linked worktree with its config. - Launcher ls-remote runs Detached with gitcmd's environment (only PATH is taken from the launcher's declared env), requires an https://, ssh:// or git:// remote (case-insensitive; http:// and local paths are refused), and passes the remote and ref past -- so a leading-dash value is an operand. - worktree git calls with extra environment keep gitcmd's environment. - Repository identity is resolved once, when a session opens: boot runs gitcmd.Open (rev-parse --absolute-git-dir --git-common-dir --show-toplevel) before any command, the controller carries the resulting gitcmd.Repo, and a rebuild of the same workspace passes it on. Every later host call runs through the Repo with GIT_DIR, GIT_COMMON_DIR and GIT_WORK_TREE set, so a nested .git, a commondir file, a rewritten .git file or a damaged HEAD written afterwards cannot substitute another repository or its config; a damaged HEAD fails closed. Threaded through the TUI status line, cli review (resolved once before the review agent runs), the desktop changes panel, change detail, history, commit detail, branch list/checkout/create and tab branch label (the tab session's identity; a tab with no session yet resolves at display), worktree Inspect/Create/RollbackCreate, and the whole merge-back flow: the source and worktree identities are recorded in the merge metadata at creation (the worktree's resolved right after worktree add) in metadata.repo.json beside metadata.json, whose shape older builds decode strictly and so is unchanged; every inspect, auto-commit, merge and cleanup call runs against them, and a worktree without that file resolves them from the roots. InspectMerge finds the allocation root from the managed layout instead of asking git in the worktree. - Repo.Verify applies Open's test to a stored identity; the identities read from metadata.repo.json are verified before the merge flow uses them. - Auto-commit staging uses gitcmd Repo.StageAll: gitlinks present as directories and untracked nested repositories are excluded with :(exclude,literal) pathspecs, because add -A checks a submodule by running git inside it under its own config. A gitlink keeps the commit the index records; an untracked nested repository leaves the worktree unverifiable and the auto-commit refuses. The worktree state token no longer runs git inside a changed nested repository. - Open accepts only a git dir belonging to the work tree that holds the directory: the work tree's own .git (sharing no other common dir) or a linked worktree's admin dir under <common>/worktrees whose gitdir file names that work tree's .git. A .git file or core.worktree pointing at another checkout is ErrNotRepository. Submodule checkouts and --separate-git-dir repositories opened directly are therefore treated as not version-controlled. Regression tests use real git with payload scripts: the gitcmd config-key matrix (signatures, lazy fetch, submodule boundary), the worktree call sites (conditional includes on Create, linked-worktree config on RollbackCreate), the status readout, the launcher's non-URL remote rejection, identity pinning after a nested .git, a commondir file and a damaged HEAD (config origin and filter marker), Open refusing another checkout's git dir (.git file, core.worktree, foreign admin dir), StageAll with nested repositories named like pathspec magic or globs, metadata.json read by a strict older decoder, merge-back without the identity file, StageAll and merge-back auto-commit past a gitlink with its own filter, merge-back after the worktree's .git file is pointed at another git dir, the status line and desktop changes panel of a workspace that later gains its own .git, and a global submodule.recurse=true against host checkout and reset. The list-then-run race is left to a follow-up that denies sandboxed writes to .git config and hooks. |
||
|
|
a54659c2c5 |
fix(security): enforce serve Host allowlist, preview confinement, and gitcmd clean-filter neutralization / 封堵 serve DNS 重绑定、预览越界读与 git clean 过滤器执行 (#9599)
* fix(security): enforce serve Host allowlist, preview confinement, and gitcmd clean-filter neutralization
Problem:
Six privately reported boundary gaps were confirmed against main-v2:
1. `reasonix serve` validated neither Host nor Origin, so a DNS-rebinding
page became same-origin with the unauthenticated loopback listener and
could drive POST /bypass, POST /submit, and read GET /history past the
application/json CSRF guard.
2. write_file / edit_file / multi_edit Preview() read model-supplied
absolute paths with no confinement, leaking out-of-workspace file
contents into approval cards and session logs even though Execute
would refuse the write.
3. gitcmd diff invocations still executed repository-configured
filter.<driver>.clean commands via .gitattributes — the residual the
package itself documents (--no-ext-diff/--no-textconv do not cover it).
4. install_source's SSRF dial guard validated only the proxy address when
an HTTP/HTTPS proxy was configured; blocked IP-literal destinations
were forwarded unchecked (web_fetch already checks its proxy path).
5. The bash indirect-execution classifier missed awk/gawk/mawk/nawk, so
`awk 'BEGIN{system("...")}'` fell into the reusable-approval class.
6. The legacy read-only prefix table still listed `cargo check`/`cargo
doc` as permission readers although cargo executes build.rs for both.
Root cause:
Each was a gap in a boundary the codebase already enforces elsewhere:
no Host allowlist next to the existing CSRF/auth middleware chain,
confinePreview missing on three of five previewers, a fixed-key config
baseline that cannot express per-driver filter names, a dial-time-only
SSRF check, an interpreter allowlist missing one family, and a stale
legacy table disagreeing with the effect classifier.
Fix:
- serve: hostGuard middleware (421 for non-loopback, non-listen Host),
listen address plumbed via setListenAddr from all Run entry points;
behind_proxy and wildcard/non-loopback binds exempt; the plaintext
non-loopback startup warning now also fires loudest for auth=none.
- builtin: the three previews apply confinePreview after resolveIn,
matching delete_range/delete_symbol.
- gitcmd: diff invocations neutralize every filter driver defined in the
repository-local .git/config (clean= emptied, required forced off;
worktree-linked .git followed). gitstatus runGit passes cwd through
gitcmd's dir parameter so the lookup sees the right repository.
- installsource: ssrfRequestGuard RoundTripper rejects blocked IP-literal
destinations before any proxy forwarding, matching web_fetch's boundary.
- permission: awk-family inline programs (not -f/--file) classified as
indirect execution like python -c.
- shellsafe: cargo check/doc removed from readOnlyPrefixes (search stays).
Verification:
- go test ./internal/gitcmd ./internal/shellsafe ./internal/permission
./internal/installsource ./internal/tool/builtin ./internal/serve
./internal/cli — all pass on a clean origin/main-v2 worktree.
- New regression tests reproduce each report end-to-end: the rebind
Host is rejected before csrfGuard; confined previews error on
out-of-roots paths; a filter.pwn clean+required marker payload does
not run during diff while the diff still renders the working-tree
change; a recording proxy sees zero blocked destinations; awk
system()/getline shapes require human approval.
* refactor(serve): keep repolint budgets while adding the Host guard
Move hostGuard, hostGateState, setListenAddr, and csrfGuard into the new
internal/serve/hostguard.go and condense the added comment blocks in
gitcmd, installsource, permission, and preview so every repolint essay and
file-size budget stays at its existing baseline. serve.go ends 17 lines
smaller than main-v2. Behavior is unchanged; the moved guards keep their
tests and wiring.
Verification: go run ./tools/repolint -> clean (1257 baselined findings);
go test ./internal/serve ./internal/gitcmd ./internal/installsource
./internal/permission ./internal/tool/builtin all pass.
* fix(security): close hardening review bypasses
Problem:
Several review probes still crossed the intended Host, preview, Git filter, and reusable-shell approval boundaries.
Root cause:
The proxy Host exemption ignored auth mode; Git filter neutralization omitted process drivers and linked-worktree config; previews treated managed config as readable before approval; and awk option matching folded -F into -f.
Fix:
Require token/password auth for the proxy exemption, blank clean/process filter commands from common and worktree configs, keep previews inside write roots, and parse awk program-source options case-sensitively.
Verification:
- go test -count=1 ./...
- go test -race -count=1 ./internal/serve ./internal/gitcmd ./internal/tool/builtin ./internal/permission
- go run ./tools/repolint
- latest main-v2 merged tree: go test -count=1 ./... and repolint
|
||
|
|
37e9547d38 |
fix(desktop): stabilize rendering, workspace, catalog, and WebView2 / 系统治理桌面端显示稳定性 (#8827)
* fix(desktop): stabilize display ownership and recovery Problem: Desktop conversations could flicker, jump, clip content, retain stale workspace data, hide partially indexed sessions, flash background command windows, and fail to recover cleanly from WebView2 renderer failures. Root cause: Scroll position, workspace freshness, catalog completeness, process visibility, DPI synchronization, and WebView2 recovery each had multiple competing owners or treated incomplete refresh state as empty authoritative state. Fix: Centralize transcript scrolling in a deterministic Virtuoso coordinator; add keyed stale-while-revalidate workspace resources, responsive overlay layout, bounded code views, and secure Markdown media resolution; expose partial catalog projections with per-directory completeness and authoritative persist indexing; and add hidden-by-default Windows commands plus a rebased WebView2 integration with single-owner DPI synchronization and tiered crash recovery. Verification: - pnpm test:all - pnpm test:transcript-browser - pnpm build - go test ./... - cd desktop && go test ./... - go test -race ./internal/sessioncatalog ./internal/history ./internal/control ./internal/proc - cd desktop && go test -race . -count=1 - go run ./tools/repolint - Windows amd64 cross-compilation for desktop, proc, update-helper, windows-resource, and WebView2 edge Co-authored-by: ttmouse <[email protected]> * fix(desktop): close display stability review gaps Problem: The initial stability integration still cleared restored workspace selections, replaced working-tree data on refresh failures, allowed background command constructors outside desktop/ to bypass the Windows hidden-window policy, and could serve a media token after its authorized file was replaced. Critical renderer failures could also be dropped behind auxiliary WebView2 diagnostics, while cold Windows CI combined two slow suites under one timeout. Root cause: Workspace refresh and project restoration still had overlapping reset paths; the process gate covered only the desktop directory; media tokens were bound only to a path; the diagnostics queue treated recovery and telemetry equally; and the Windows job shared one aggregate test budget. Fix: Extract a keyed workspace-changes SWR hook and preserve per-project selections, bind media tokens to the authorized file identity with restrictive response headers, extend proc constructors and static enforcement across desktop-used internal packages, preserve hidden flags for batch commands, prioritize renderer recovery, fix upstream formatting/lint findings, and split the Windows vendor test budget without skipping coverage. Verification: - go test ./... - cd desktop && go test ./... - root concurrency-package race suite - cd desktop && go test -race ./... - golangci-lint on native, Linux, and Windows targets - pnpm test:workspace - pnpm test:transcript - pnpm test:all - pnpm build - go run ./tools/repolint - actionlint .github/workflows/ci.yml - Windows cross-compilation for desktop, hook, and WebView2 edge tests * chore(security): document intentional command boundary * chore(deps): update Go toolchain to 1.26.6 --------- Co-authored-by: ttmouse <[email protected]> |
||
|
|
674be729bb |
refactor(git): drop computed allocation hints in argument building
Capacity hints derived from input lengths tripped the allocation-overflow analyzer for no benefit — these lists hold a handful of entries. Uses slices.Contains for the flag check while here. |
||
|
|
129caed9e8 |
refactor(git): build every internal git invocation in one place
Reasonix shells out to git from five places: the CLI status readout, the desktop workspace probe, the remote workbench, worktree management, and plugin source checkouts. Each one assembled its own argument list, so the invocation baseline drifted — three sites disabled fsmonitor and auto maintenance, two did not, and the environment differed at every site. internal/gitcmd now builds them all. Call sites keep their own preferences (core.quotepath for the workbench, core.autocrlf for plugin checkouts) by layering config on top of the shared baseline rather than replacing it, and the environment is uniform: credential variables filtered out of git subprocesses, optional locks off, no interactive credential prompts on a terminal the TUI owns. Also folds in the settings that keep repository-supplied configuration from selecting a program for git to run during inspection — diff-side external and textconv drivers alongside the existing fsmonitor and maintenance settings — since a repository's config is authored by whoever produced the repository, not chosen by the user. Covered by a test that inspects a repository configured that way and asserts nothing ran; the package comment records which drivers this cannot reach. Argument-construction tests move from internal/worktree to the new package with the code they cover. |