mirror of
https://github.com/anchore/syft.git
synced 2026-10-30 22:12:28 +01:00
* fix(generic): recover from parser and processor panics - a panic while parsing one file becomes an unknown for that location instead of failing the whole SBOM - a panic in a package processor is logged as a warning and the unprocessed results are kept - stacks go to the trace log, not into the unknown text Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix(unknown): keep errors that unwrap to nil `sync.PanicError` with a non-error panic value (e.g. `panic("boom")`) unwraps to nil, and was being dropped entirely from the error graph instead of being kept as a leaf. Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix(task): don't put the stack trace in task panic errors Task panics are still fatal, but the error now reads `panic in task "<name>": <value>` and the stack goes to the debug log. Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * test(generic): cover chained processors when a later one panics Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix(file): recover from panics in the executable and file digest catalogers A panic while reading one file is now recorded as an unknown for that file instead of failing the whole SBOM, the same as generic catalogers. Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
41 lines
1.1 KiB
Go
41 lines
1.1 KiB
Go
package executable
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/anchore/syft/internal/unknown"
|
|
"github.com/anchore/syft/syft/file"
|
|
)
|
|
|
|
type panicReader struct{}
|
|
|
|
func (panicReader) Read([]byte) (int, error) { panic("boom") }
|
|
|
|
type panickingContentsResolver struct {
|
|
*file.MockResolver
|
|
}
|
|
|
|
func (r panickingContentsResolver) FilesByMIMEType(...string) ([]file.Location, error) {
|
|
return r.FilesByPath("cataloger_test.go")
|
|
}
|
|
|
|
func (r panickingContentsResolver) FileContentsByLocation(file.Location) (io.ReadCloser, error) {
|
|
return io.NopCloser(panicReader{}), nil
|
|
}
|
|
|
|
func TestCatalogCtx_panicBecomesUnknown(t *testing.T) {
|
|
resolver := panickingContentsResolver{file.NewMockResolverForPaths("cataloger_test.go")}
|
|
|
|
results, err := NewCataloger(DefaultConfig()).CatalogCtx(context.Background(), resolver)
|
|
|
|
require.Empty(t, results)
|
|
unknowns, remaining := unknown.ExtractCoordinateErrors(err)
|
|
require.NoError(t, remaining)
|
|
require.Len(t, unknowns, 1)
|
|
require.ErrorContains(t, unknowns[0].Reason, "recovered from panic while reading executable: boom")
|
|
}
|