Labels: bug
Priority: should-fix
Source: claude
Summary
clean --older-than N never checks that N is a number. A non-numeric value
produces a nonsense heading, silently finds nothing, and exits 0 — invalid
input is indistinguishable from a successful clean run.
Evidence
cmd_clean takes the value with no pattern check (git-trees:417), then
interpolates it into both the heading and find:
git-trees:481 — echo "== worktrees untouched >${days}d =="
git-trees:491 — find "$wt" -maxdepth 0 -mtime +"$days" 2>/dev/null
Observed:
$ git trees clean --older-than abc
== branches with gone upstream ==
== branches merged into main ==
== worktrees untouched >abcd ==
(report only — pass --apply to execute)
$ echo $?
0
find rejects -mtime +abc, but its stderr is discarded by 2>/dev/null, so
the failure is invisible. The user is told nothing is stale when in fact
nothing was ever checked.
Not an injection vector: "$days" is quoted, so a value like
30 -exec rm -rf {} ; is passed to find as one argument and rejected. This
is a correctness and trust bug, not a security one.
Proposed fix
Validate after parsing, alongside the existing empty check at git-trees:477:
case "$days" in
''|*[!0-9]*)
echo "git trees clean: --older-than needs a non-negative integer (days)" >&2
return 1 ;;
esac
This replaces the current [ -z "$days" ] check and also rejects -1, 3.5,
and abc. 0 remains valid and means "everything older than today".
Test plan
Labels: bug
Priority: should-fix
Source: claude
Summary
clean --older-than Nnever checks thatNis a number. A non-numeric valueproduces a nonsense heading, silently finds nothing, and exits 0 — invalid
input is indistinguishable from a successful clean run.
Evidence
cmd_cleantakes the value with no pattern check (git-trees:417), theninterpolates it into both the heading and
find:git-trees:481—echo "== worktrees untouched >${days}d =="git-trees:491—find "$wt" -maxdepth 0 -mtime +"$days" 2>/dev/nullObserved:
findrejects-mtime +abc, but its stderr is discarded by2>/dev/null, sothe failure is invisible. The user is told nothing is stale when in fact
nothing was ever checked.
Not an injection vector:
"$days"is quoted, so a value like30 -exec rm -rf {} ;is passed tofindas one argument and rejected. Thisis a correctness and trust bug, not a security one.
Proposed fix
Validate after parsing, alongside the existing empty check at
git-trees:477:This replaces the current
[ -z "$days" ]check and also rejects-1,3.5,and
abc.0remains valid and means "everything older than today".Test plan
--older-than abc,--older-than -1,--older-than 3.5exit nonzerowith a clear message
--older-than 30reports and applies exactly as today--older-than 0behaves sensibly (or is rejected, if that's preferred —just be deliberate)