mirror of
https://github.com/anchore/syft.git
synced 2026-10-31 22:46:36 +01:00
chore: centralize temp files and prefer streaming IO (#4668)
* chore: centralize temp files and prefer streaming IO Catalogers that create temp files ad-hoc can easily forget cleanup, leaking files on disk. Similarly, io.ReadAll is convenient but risks OOM on large or malicious inputs. Introduce internal/tmpdir to manage all cataloger temp storage under a single root directory with automatic cleanup. Prefer streaming parsers (bufio.Scanner, json/yaml.NewDecoder, io.LimitReader) over buffering entire inputs into memory. Add ruleguard rules to enforce both practices going forward. Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> * chore: go back to old release parsing Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> * simplify to limit reader in version check Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> * chore: regex change postponed Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> * simplify supplement release to limitreader Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> --------- Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -257,19 +256,12 @@ func getLicenseFromNpmRegistry(baseURL, packageName, version string) (string, er
|
||||
}
|
||||
}()
|
||||
|
||||
bytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to parse package from npm registry: %w", err)
|
||||
}
|
||||
|
||||
dec := json.NewDecoder(strings.NewReader(string(bytes)))
|
||||
|
||||
// Read "license" from the response
|
||||
var license struct {
|
||||
License string `json:"license"`
|
||||
}
|
||||
|
||||
if err := dec.Decode(&license); err != nil {
|
||||
if err := json.NewDecoder(resp.Body).Decode(&license); err != nil {
|
||||
return "", fmt.Errorf("unable to parse license from npm registry: %w", err)
|
||||
}
|
||||
|
||||
@@ -324,14 +316,8 @@ func parseLicensesFromLocation(l file.Location, resolver file.Resolver, pkgFile
|
||||
}
|
||||
defer internal.CloseAndLogError(contentReader, l.RealPath)
|
||||
|
||||
contents, err := io.ReadAll(contentReader)
|
||||
if err != nil {
|
||||
log.Debugf("error reading file contents for %s: %v", pkgFile, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pkgJSON packageJSON
|
||||
err = json.Unmarshal(contents, &pkgJSON)
|
||||
err = json.NewDecoder(contentReader).Decode(&pkgJSON)
|
||||
if err != nil {
|
||||
log.Debugf("error parsing %s: %v", pkgFile, err)
|
||||
return nil, err
|
||||
|
||||
@@ -179,7 +179,7 @@ func newPnpmLockfileParser(version float64) pnpmLockfileParser {
|
||||
|
||||
// parsePnpmLock is the main parser function for pnpm-lock.yaml files.
|
||||
func (a genericPnpmLockAdapter) parsePnpmLock(ctx context.Context, resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
data, err := io.ReadAll(reader)
|
||||
data, err := io.ReadAll(reader) //nolint:gocritic // multi-pass parse requires []byte
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to load pnpm-lock.yaml file: %w", err)
|
||||
}
|
||||
|
||||
@@ -166,7 +166,8 @@ func findDevOnlyPkgs(yarnPkgs []yarnPackage, prodDeps, devDeps map[string]string
|
||||
}
|
||||
|
||||
func parseYarnV1LockFile(reader io.ReadCloser) ([]yarnPackage, error) {
|
||||
content, err := io.ReadAll(reader)
|
||||
// TODO: refactor to use bufio.Scanner for streaming line-by-line parsing instead of reading the entire file
|
||||
content, err := io.ReadAll(reader) //nolint:gocritic // stateful multi-line parser; candidate for streaming refactor
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read yarn.lock file: %w", err)
|
||||
}
|
||||
@@ -265,7 +266,8 @@ func (a genericYarnLockAdapter) parseYarnLock(ctx context.Context, resolver file
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(reader)
|
||||
// TODO: refactor to detect version from the first line via bufio.Scanner, then dispatch to a streaming parser
|
||||
data, err := io.ReadAll(reader) //nolint:gocritic // two-pass parse: version detection then format-specific parsing
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to load yarn.lock file: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user