Refuse a yarn lockfile the scanner stopped in, and a forge answer the cap cut
mesh/merge-gate pass: builds gitea → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer delivery to the same trunk took over its walk

Either was read as whole and could leave a pinned version unnamed (review of #128).
This commit is contained in:
jochen
2026-10-08 14:52:06 +02:00
parent d69c0db4fc
commit 10b5e8188a
4 changed files with 59 additions and 6 deletions
+9 -1
View File
@@ -78,6 +78,9 @@ func (f *Forge) password() (string, error) {
return strings.TrimSpace(string(raw)), nil
}
// maxBody is the largest answer read from the forge.
const maxBody = 32 << 20
// do sends one request and answers the body; 404 is errNotFound.
func (f *Forge) do(ctx context.Context, method, path string) ([]byte, error) {
password, err := f.password()
@@ -95,10 +98,15 @@ func (f *Forge) do(ctx context.Context, method, path string) ([]byte, error) {
return nil, fmt.Errorf("the forge did not answer %s %s: %w", method, path, err)
}
defer res.Body.Close()
body, err := io.ReadAll(io.LimitReader(res.Body, 32<<20))
// One byte past the cap is read, so a body the cap cut is told from one that fits it exactly: a
// cut body is refused, never parsed as if it were whole.
body, err := io.ReadAll(io.LimitReader(res.Body, maxBody+1))
if err != nil {
return nil, err
}
if len(body) > maxBody {
return nil, fmt.Errorf("the forge's answer to %s %s is larger than %d MiB and was not read whole", method, path, maxBody>>20)
}
switch {
case res.StatusCode == http.StatusNotFound:
return nil, fmt.Errorf("%s %s: %w", method, path, errNotFound)