mirror of
https://github.com/anchore/syft.git
synced 2026-05-20 12:15:27 +02:00
32 lines
1.1 KiB
Go
32 lines
1.1 KiB
Go
package file
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
const perFileReadLimit = 2 * GB
|
|
|
|
// safeCopy limits the copy from the reader. This is useful when extracting files from archives to
|
|
// protect against decompression bomb attacks.
|
|
func safeCopy(writer io.Writer, reader io.Reader) error {
|
|
numBytes, err := io.Copy(writer, io.LimitReader(reader, perFileReadLimit))
|
|
if numBytes >= perFileReadLimit {
|
|
return fmt.Errorf("zip read limit hit (potential decompression bomb attack)")
|
|
}
|
|
// Propagate decompression / read errors up to the caller. io.Copy
|
|
// on the happy path returns (n, nil); the only way err is non-nil
|
|
// here is that the underlying reader surfaced a real failure
|
|
// ("flate: corrupt input before offset X" on a mangled ZIP entry,
|
|
// a network-backed reader erroring mid-stream, etc.). The previous
|
|
// implementation dropped that error and the caller stored a
|
|
// partial / empty buffer as a "successful" extract, which silently
|
|
// downgraded Java cataloger output and caused SBOM scanners to
|
|
// miss known CVEs (#4806).
|
|
if err != nil && !errors.Is(err, io.EOF) {
|
|
return fmt.Errorf("failed to read archive entry: %w", err)
|
|
}
|
|
return nil
|
|
}
|