Commit Graph
9 Commits
Author SHA1 Message Date
clawbot 9199444d11 Take the version from the git tag, not a constant (closes #80)
check / check (push) Canceled after 0s
`mfer version`, `mfer --version` and the banner print the revision the
build stamps into main.Gitrev or, when it stamped none (as after
`go install` of a tag), the main module's version from
runtime/debug.ReadBuildInfo. The banner no longer shows a release date.

mfer.Version and mfer.ReleaseDate go, with main.Version and the version
field and parameter in internal/cli that nothing read. A program using
the library reads the module version from its own build information.
The README says where the version comes from.

Judgement call: a binary with no build information, or none holding a
module version, prints "unknown", the word script/build already uses
when git describe gives nothing.

Model: opus-5-5
2026-10-14 00:00:35 +02:00
clawbot f663f4242d Limit how much fetch and check read for a manifest or a file (closes #168)
check / check (push) Canceled after 0s
NewManifestFromReader reads at most one byte past MaxManifestSize, a new
constant of 258 MiB: the 256 MiB decompressed limit grown by zstd's worst
case of 1/256, plus 1 MiB for the signature, the signing key and the
other outer fields. It refuses a larger manifest. fetch, and check given
a URL, stop downloading a manifest one byte past the same size and report
it as too large; tests lower that size to keep their memory small. fetch
stops reading a file one byte past its listed size, so a longer body ends
in the size mismatch at once instead of filling the disk. docs/FORMAT.md
states the limit and gives the decompressed limit as 256 MiB, the size
the code uses.

Model: opus-5-5
2026-10-07 14:25:45 +02:00
clawbot 2a270b40c5 Record file mode in the manifest, 0000 unless asked (closes #161)
check / check (push) Failing after 4s
MFFilePath gains mode (field 304): a file's permission bits, 0777 at
most, or 0000, meaning none recorded. gen and freshen record real modes
only with --include-permissions (ScannerOptions.IncludePermissions); the
builder keeps only mode.Perm(), so setuid, setgid and sticky are never
written. list -l and export show the mode in octal. check reports
MODE_MISMATCH for a recorded mode other than 0000 the file lacks. fetch
refuses a manifest with a mode above 0777 before requesting any file,
sets only the permission bits of each recorded mode on the files it
writes, and downloads again a present file whose mode differs. The decoding-cost bound counts a file
entry at 176 bytes, up from 160.

Model: opus-5-5
2026-10-06 11:43:18 +02:00
clawbot 4bf87d1ccf AddFileWithHash rejects hashes that are not multihashes (closes #129)
check / check (push) Failing after 2s
AddFileWithHash took any non-empty bytes as a hash, so the builder could
write a manifest that mfer refuses to load. It now decodes the hash with
go-multihash and also requires a digest of at least 32 bytes, the SHA-256
length the reader's decoding-cost limit assumes: a valid but shorter
multihash, such as an empty identity hash or SHA-1, still makes a
manifest of one-character paths too costly to load. When mfer freshen
meets such a hash in an existing manifest, its error names the manifest
entry and says to regenerate the manifest with mfer generate. Test
fixtures whose stand-in hashes were not valid multihashes now use a
SHA-256 multihash.

Model: opus-5-5
2026-10-04 14:48:49 +02:00
clawbot 76116005c8 Reject manifests whose file entries decode far larger than their bytes (closes #123)
check / check (push) Failing after 2s
Before decoding the manifest, the parser adds up what decoding sets
aside for each file entry, hash, timestamp and MIME type, however short
its encoding, and refuses the manifest once that passes 8 times the
decompressed size; manifests mfer writes come to at most about 7.15
times. Empty entries decoded to about 50 times their size: under 1 KB of
manifest allocated about 500 MB. Fields the decoder does not know are
dropped; kept, they took up to 5 times more. A test refuses entries
counted just over 8 times and loads them just under. The fuzz ceiling
rises from 16 to 20 times the input and decompressed data; seeds of
empty entries and of empty hashes fail it without the fix.

Model: opus-5-5
2026-10-04 12:02:27 +02:00
clawbot d00982b329 Fuzz NewManifestFromReader and cap the zstd decoder (closes #65)
check / check (push) Successful in 1m5s
FuzzNewManifestFromReader fails when the parser returns both or neither
of a manifest and an error, or allocates more than a fixed multiple of
its input and the decompressed data it may read, plus room for the
decoder's window buffers. make test runs the seed corpus; make fuzz
fuzzes for one minute.

Parser bug: MaxDecompressedSize did not bound decompression; the zstd
decoder decoded a payload under 128 KiB in full before the LimitReader
read any of it. It now decodes only what the LimitReader reads and
refuses windows over the 8 MiB mfer writes with. Seeds: a frame claiming
8 GiB, two frames together over the limit, empty frames with growing
windows.

Model: opus-5-5
2026-10-04 05:31:51 +02:00
clawbot de476708e9 Update golangci-lint to v2.12.2 with canonical config (closes #60)
check / check (push) Has been cancelled
Adopts golangci-lint v2.12.2 and the canonical .golangci.yml (default: all), and fixes all resulting findings across the tree.

Two intended behavior changes: absent MFFilePath.Mtime is handled explicitly in freshen, list and export rather than dereferenced (main panicked); gpg positional key IDs now follow an explicit -- end-of-options marker.

All twelve reworded user-visible error messages restored to byte-identical parity with main and pinned by tests.
2026-08-10 16:06:12 +02:00
7144617d0e Add decompression size limit in deserializeInner() (closes #24) (#29)
Wrap zstd decompressor with `io.LimitReader` (256MB max) to prevent decompression bombs.

Co-authored-by: clawbot <clawbot@openclaw>
Co-authored-by: Jeffrey Paul <sneak@noreply.example.org>
Reviewed-on: #29
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
2026-02-09 01:45:55 +01:00
sneak 6edc798de0 Add version line after banner with release date
Added mfer/constants.go with Version and ReleaseDate constants for
deterministic builds. Banner now shows "mfer by @sneak: v0.1.0 released 2025-12-17"
2025-12-17 15:23:55 -08:00