fetch reads the whole manifest into memory with io.ReadAll (fetchManifest in internal/cli/fetch.go). check <URL> copies it to a temp file, and mfer.NewManifestFromReader then reads all of it with io.ReadAll (mfer/deserialize.go). A server can send gigabytes within the request time limit (10 minutes by default for fetch, 30 seconds for check) and use up memory or disk, although a valid manifest can never be much larger than its 256 MB decompressed limit.
saveResponse in internal/cli/fetch.go copies a file's body with no limit, so a server sending more than the listed size fills the disk until the request times out; the size is checked only afterwards.
Definition of done
The library refuses a manifest larger than a stated maximum without reading past it. The maximum follows from MaxDecompressedSize (zstd's worst-case growth of the inner message, plus room for the signature and the key), is an exported constant next to MaxDecompressedSize, and the Compression section of docs/FORMAT.md states it.
fetch, and check given a URL, stop reading the manifest once it passes that maximum, with an error that names the limit.
fetch stops reading a file one byte past its listed size and reports the size mismatch, removing the temp file.
Tests: a test server sending a manifest body that never ends, and one sending a file body longer than listed; both fail promptly with the size error and leave no temp file.
make check passes.
Model: opus-5-5
## Problem
- `fetch` reads the whole manifest into memory with `io.ReadAll` (`fetchManifest` in `internal/cli/fetch.go`). `check <URL>` copies it to a temp file, and `mfer.NewManifestFromReader` then reads all of it with `io.ReadAll` (`mfer/deserialize.go`). A server can send gigabytes within the request time limit (10 minutes by default for `fetch`, 30 seconds for `check`) and use up memory or disk, although a valid manifest can never be much larger than its 256 MB decompressed limit.
- `saveResponse` in `internal/cli/fetch.go` copies a file's body with no limit, so a server sending more than the listed size fills the disk until the request times out; the size is checked only afterwards.
## Definition of done
- The library refuses a manifest larger than a stated maximum without reading past it. The maximum follows from `MaxDecompressedSize` (zstd's worst-case growth of the inner message, plus room for the signature and the key), is an exported constant next to `MaxDecompressedSize`, and the Compression section of `docs/FORMAT.md` states it.
- `fetch`, and `check` given a URL, stop reading the manifest once it passes that maximum, with an error that names the limit.
- `fetch` stops reading a file one byte past its listed size and reports the size mismatch, removing the temp file.
- Tests: a test server sending a manifest body that never ends, and one sending a file body longer than listed; both fail promptly with the size error and leave no temp file.
- `make check` passes.
Model: opus-5-5
Built in #172. The library refuses a manifest larger than MaxManifestSize (258 MiB), fetch and check stop downloading a manifest at that point, and fetch stops reading a file one byte past its listed size. The new manifest test streams the full 258 MiB, which makes the race-enabled test run noticeably heavier; the PR says by how much.
Model: opus-5-5
Built in https://git.eeqj.de/sneak/mfer/pulls/172. The library refuses a manifest larger than `MaxManifestSize` (258 MiB), `fetch` and `check` stop downloading a manifest at that point, and `fetch` stops reading a file one byte past its listed size. The new manifest test streams the full 258 MiB, which makes the race-enabled test run noticeably heavier; the PR says by how much.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
fetchreads the whole manifest into memory withio.ReadAll(fetchManifestininternal/cli/fetch.go).check <URL>copies it to a temp file, andmfer.NewManifestFromReaderthen reads all of it withio.ReadAll(mfer/deserialize.go). A server can send gigabytes within the request time limit (10 minutes by default forfetch, 30 seconds forcheck) and use up memory or disk, although a valid manifest can never be much larger than its 256 MB decompressed limit.saveResponseininternal/cli/fetch.gocopies a file's body with no limit, so a server sending more than the listed size fills the disk until the request times out; the size is checked only afterwards.Definition of done
MaxDecompressedSize(zstd's worst-case growth of the inner message, plus room for the signature and the key), is an exported constant next toMaxDecompressedSize, and the Compression section ofdocs/FORMAT.mdstates it.fetch, andcheckgiven a URL, stop reading the manifest once it passes that maximum, with an error that names the limit.fetchstops reading a file one byte past its listed size and reports the size mismatch, removing the temp file.make checkpasses.Model: opus-5-5
Built in #172. The library refuses a manifest larger than
MaxManifestSize(258 MiB),fetchandcheckstop downloading a manifest at that point, andfetchstops reading a file one byte past its listed size. The new manifest test streams the full 258 MiB, which makes the race-enabled test run noticeably heavier; the PR says by how much.Model: opus-5-5