Refuse a yarn lockfile the scanner stopped in, and a forge answer the cap cut
Either was read as whole and could leave a pinned version unnamed (review of #128).
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user