Check the -o path before looking for the mnemonic (closes #87) #89

Merged
clawbot merged 1 commits from issue-87-check-output-first into next 2026-10-14 23:07:08 +02:00
Collaborator

Fixes #87: age encrypt and age decrypt looked at the -o path only after the mnemonic had been obtained, so a path that could never be written still prompted for the mnemonic or ran the mnemonic command.

  • Both commands now call checkOutput before the key is derived, beside the checks #84 moved there. It refuses an -o path that is a directory or a symlink to one, one whose directory is missing or is not a directory, and a symlink that points at nothing.
  • checkOutput only looks at the path and creates nothing. output is unchanged and looks at the path again when it writes, so the file beside the target is made when it was before, and what a signal removes is as the README says.
  • A directory that is really a file shows up as ENOTDIR from os.Lstat on the -o path itself, so only a missing directory needs a look of its own.
  • A directory at the -o path is refused with EISDIR, the error opening it to write would give.
  • The new test sets KEYFUNC_MNEMONIC_COMMAND to a command that fails loudly and checks that each refusal comes back from both commands.
  • The README sentence listing what is checked before the mnemonic names the -o path and the cases refused there.

Left out, per the reading of the definition of done recorded on #87: a directory the tool may not write to is still found only after the mnemonic, since finding that out means trying to write.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/keyfunc/issues/87: `age encrypt` and `age decrypt` looked at the `-o` path only after the mnemonic had been obtained, so a path that could never be written still prompted for the mnemonic or ran the mnemonic command. - Both commands now call `checkOutput` before the key is derived, beside the checks https://git.eeqj.de/sneak/keyfunc/pulls/84 moved there. It refuses an `-o` path that is a directory or a symlink to one, one whose directory is missing or is not a directory, and a symlink that points at nothing. - `checkOutput` only looks at the path and creates nothing. `output` is unchanged and looks at the path again when it writes, so the file beside the target is made when it was before, and what a signal removes is as the README says. - A directory that is really a file shows up as `ENOTDIR` from `os.Lstat` on the `-o` path itself, so only a missing directory needs a look of its own. - A directory at the `-o` path is refused with `EISDIR`, the error opening it to write would give. - The new test sets `KEYFUNC_MNEMONIC_COMMAND` to a command that fails loudly and checks that each refusal comes back from both commands. - The README sentence listing what is checked before the mnemonic names the `-o` path and the cases refused there. Left out, per the reading of the definition of done recorded on https://git.eeqj.de/sneak/keyfunc/issues/87: a directory the tool may not write to is still found only after the mnemonic, since finding that out means trying to write. Model: opus-5-5
clawbot added the needs-review label 2026-10-14 21:49:04 +02:00
clawbot self-assigned this 2026-10-14 21:49:04 +02:00
Author
Collaborator

Review of #89: needs rework.

  1. internal/cli/age/age.go, checkOutput: an -o path that is itself a directory, or a symlink to one (-o /tmp), gets past the check, so the mnemonic is still prompted for or the mnemonic command run, and only then does the run fail with "is a directory". The reading of the definition of done on #87 puts this case in scope. Acceptable: checkOutput also refuses a directory at the -o path, following a symlink, before the mnemonic; the test in internal/cli/age_test.go covers it for both commands; the README sentence names it; the PR body no longer lists it as left out.

  2. README.md, the sentence on what is checked before the mnemonic: "anything else wrong with it shows only when the output is written" is not what the code does. A path the tool cannot look at, such as one inside a directory it may not search, is also refused before the mnemonic. Acceptable: drop that clause, or have the sentence say only what the code does.

Model: opus-5-5

Review of https://git.eeqj.de/sneak/keyfunc/pulls/89: needs rework. 1. `internal/cli/age/age.go`, `checkOutput`: an `-o` path that is itself a directory, or a symlink to one (`-o /tmp`), gets past the check, so the mnemonic is still prompted for or the mnemonic command run, and only then does the run fail with "is a directory". The reading of the definition of done on https://git.eeqj.de/sneak/keyfunc/issues/87 puts this case in scope. Acceptable: `checkOutput` also refuses a directory at the `-o` path, following a symlink, before the mnemonic; the test in `internal/cli/age_test.go` covers it for both commands; the README sentence names it; the PR body no longer lists it as left out. 2. `README.md`, the sentence on what is checked before the mnemonic: "anything else wrong with it shows only when the output is written" is not what the code does. A path the tool cannot look at, such as one inside a directory it may not search, is also refused before the mnemonic. Acceptable: drop that clause, or have the sentence say only what the code does. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-14 22:20:42 +02:00
clawbot force-pushed issue-87-check-output-first from 261c817750 to 2457a344d8 2026-10-14 22:34:10 +02:00 Compare
clawbot added 1 commit 2026-10-14 22:39:00 +02:00
age encrypt and age decrypt looked at the -o path only after the
mnemonic had been obtained, so a path that could never be written
still prompted for the mnemonic or ran the mnemonic command. Both now
refuse, before the key is derived, an -o path that is a directory or a
symlink to one, whose directory is missing or is not a directory, or
that is a symlink pointing at nothing. The check creates nothing;
output still looks at the path when it writes, so the file beside the
target is made when it was before. The README names the -o path among
what is checked first.

Model: opus-5-5
clawbot force-pushed issue-87-check-output-first from 2457a344d8 to 117dd70051 2026-10-14 22:39:00 +02:00 Compare
Author
Collaborator

Rework:

  1. checkOutput now also refuses an -o path that is a directory or a symlink to one, before the mnemonic; the test in internal/cli/age_test.go covers both for age encrypt and age decrypt, and the PR body no longer lists the case as left out.
  2. The README sentence names that case and drops the clause about anything else showing only when the output is written.

Rebased onto the current next.

Model: opus-5-5

Rework: 1. `checkOutput` now also refuses an `-o` path that is a directory or a symlink to one, before the mnemonic; the test in `internal/cli/age_test.go` covers both for `age encrypt` and `age decrypt`, and the PR body no longer lists the case as left out. 2. The README sentence names that case and drops the clause about anything else showing only when the output is written. Rebased onto the current `next`. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-14 22:46:00 +02:00
Author
Collaborator

Review of #89 passed: both earlier findings are fixed and the change meets the definition of done on #87.

Model: opus-5-5

Review of https://git.eeqj.de/sneak/keyfunc/pulls/89 passed: both earlier findings are fixed and the change meets the definition of done on https://git.eeqj.de/sneak/keyfunc/issues/87. Model: opus-5-5
clawbot merged commit 2fbc32fe75 into next 2026-10-14 23:07:08 +02:00
clawbot deleted branch issue-87-check-output-first 2026-10-14 23:07:09 +02:00
Sign in to join this conversation.