A manifest recording a mode above 0777 loads; check then fails every such file as MODE_MISMATCH #225

Closed
opened 2026-10-14 02:22:00 +02:00 by clawbot · 2 comments
Collaborator

docs/FORMAT.md (File Mode) says mode holds the nine permission bits and is never above 0777, and fetch refuses a manifest recording a larger mode before requesting any file (fetchManifest in internal/cli/fetch.go). Loading does not check it: deserializeInner in mfer/deserialize.go validates paths and hashes only. So check loads such a manifest, and Checker.checkFile in mfer/checker.go compares info.Mode().Perm(), at most 0777, with the recorded value, so a file whose permission bits are exactly the recorded ones is reported MODE_MISMATCH (mode mismatch): the message blames the file for a manifest that is out of range. list -l prints the mode as 4755 and export as "4755"; freshen rewrites it as the permission bits alone (mode.Perm() in AddFileWithHash), changing the entry without a word.

Reproduce on v1.0.0-rc1, in package mfer: build an MFFile with one entry recording Mode: 0o4755 and write it through manifest.generate; NewManifestFromReader loads it; NewChecker and Check against a file with mode 0755 give MODE_MISMATCH a.txt (mode mismatch).

Correct: a mode above 0777 is refused when the manifest is loaded, as a path that breaks the path rules is, so check, list, export, freshen and fetch refuse it with one message, and docs/FORMAT.md says readers reject it. fetchManifest's own check is then unreachable and goes, with its test moved to the loader.

Severity: minor

Definition of done

  • Failing test first: NewManifestFromReader refuses a manifest whose entry records mode 04755, naming the path and the mode.
  • The fix in mfer/deserialize.go; internal/cli/fetch.go loses the check the loader now makes.
  • docs/FORMAT.md File Mode says readers reject a mode above 0777.
  • make check passes.

Model: fable-5-1

`docs/FORMAT.md` (File Mode) says `mode` holds the nine permission bits and is never above `0777`, and `fetch` refuses a manifest recording a larger mode before requesting any file (`fetchManifest` in `internal/cli/fetch.go`). Loading does not check it: `deserializeInner` in `mfer/deserialize.go` validates paths and hashes only. So `check` loads such a manifest, and `Checker.checkFile` in `mfer/checker.go` compares `info.Mode().Perm()`, at most `0777`, with the recorded value, so a file whose permission bits are exactly the recorded ones is reported `MODE_MISMATCH (mode mismatch)`: the message blames the file for a manifest that is out of range. `list -l` prints the mode as `4755` and `export` as `"4755"`; `freshen` rewrites it as the permission bits alone (`mode.Perm()` in `AddFileWithHash`), changing the entry without a word. Reproduce on `v1.0.0-rc1`, in package `mfer`: build an `MFFile` with one entry recording `Mode: 0o4755` and write it through `manifest.generate`; `NewManifestFromReader` loads it; `NewChecker` and `Check` against a file with mode `0755` give `MODE_MISMATCH a.txt (mode mismatch)`. Correct: a mode above `0777` is refused when the manifest is loaded, as a path that breaks the path rules is, so `check`, `list`, `export`, `freshen` and `fetch` refuse it with one message, and `docs/FORMAT.md` says readers reject it. `fetchManifest`'s own check is then unreachable and goes, with its test moved to the loader. Severity: minor ## Definition of done - Failing test first: `NewManifestFromReader` refuses a manifest whose entry records mode `04755`, naming the path and the mode. - The fix in `mfer/deserialize.go`; `internal/cli/fetch.go` loses the check the loader now makes. - `docs/FORMAT.md` File Mode says readers reject a mode above `0777`. - `make check` passes. Model: fable-5-1
clawbot self-assigned this 2026-10-14 02:22:00 +02:00
Author
Collaborator

Plan: built as the issue says, after #224 lands, since both change mfer/deserialize.go and docs/FORMAT.md. Loading refuses a mode above 0777, naming the path and the mode; fetch drops its own check and its test moves to the loader. One PR to next through an independent review. Worker rules: #99 (comment), without the TODO.md step.

Model: opus-5-5

Plan: built as the issue says, after https://git.eeqj.de/sneak/mfer/issues/224 lands, since both change `mfer/deserialize.go` and `docs/FORMAT.md`. Loading refuses a mode above `0777`, naming the path and the mode; `fetch` drops its own check and its test moves to the loader. One PR to `next` through an independent review. Worker rules: https://git.eeqj.de/sneak/mfer/issues/99#issuecomment-115880, without the `TODO.md` step. Model: opus-5-5
Author
Collaborator

Built in #230 as planned above. Loading a manifest now refuses an entry recording a mode above 0777, naming the path and the mode, so every command that reads a manifest refuses it with the same message. The check fetch had for this is gone, and its test is now in package mfer's loading tests. docs/FORMAT.md File Mode says readers reject such a mode.

Model: opus-5-5

Built in https://git.eeqj.de/sneak/mfer/pulls/230 as planned above. Loading a manifest now refuses an entry recording a mode above `0777`, naming the path and the mode, so every command that reads a manifest refuses it with the same message. The check `fetch` had for this is gone, and its test is now in package `mfer`'s loading tests. `docs/FORMAT.md` File Mode says readers reject such a mode. Model: opus-5-5
Sign in to join this conversation.