mirror of
https://github.com/anchore/syft.git
synced 2026-11-04 08:26:38 +01:00
add gem analyzer
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package dpkg
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
@@ -9,51 +10,69 @@ import (
|
||||
"github.com/anchore/stereoscope/pkg/tree"
|
||||
)
|
||||
|
||||
var parserDispatch = map[string]parserFn{
|
||||
"/var/lib/dpkg/status": ParseDpkgStatusEntries,
|
||||
}
|
||||
|
||||
type parserFn func(io.Reader) ([]pkg.DpkgMetadata, error)
|
||||
|
||||
type Analyzer struct {
|
||||
selectedFiles []file.Reference
|
||||
parsers map[file.Reference]parserFn
|
||||
}
|
||||
|
||||
func NewAnalyzer() *Analyzer {
|
||||
return &Analyzer{}
|
||||
return &Analyzer{
|
||||
selectedFiles: make([]file.Reference, 0),
|
||||
parsers: make(map[file.Reference]parserFn),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Analyzer) Name() string {
|
||||
return "dpkg-analyzer"
|
||||
}
|
||||
|
||||
func (a *Analyzer) register(f file.Reference, parser parserFn) {
|
||||
a.selectedFiles = append(a.selectedFiles, f)
|
||||
a.parsers[f] = parser
|
||||
}
|
||||
|
||||
func (a *Analyzer) clear() {
|
||||
a.selectedFiles = make([]file.Reference, 0)
|
||||
a.parsers = make(map[file.Reference]parserFn)
|
||||
}
|
||||
|
||||
func (a *Analyzer) SelectFiles(trees []tree.FileTreeReader) []file.Reference {
|
||||
files := make([]file.Reference, 0)
|
||||
for _, tree := range trees {
|
||||
// TODO: extract into function/slice/etc
|
||||
file := tree.File("/var/lib/dpkg/status")
|
||||
if file != nil {
|
||||
files = append(files, *file)
|
||||
for exactPath, parser := range parserDispatch {
|
||||
match := tree.File(file.Path(exactPath))
|
||||
if match != nil {
|
||||
a.register(*match, parser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a.selectedFiles = files
|
||||
|
||||
return files
|
||||
return a.selectedFiles
|
||||
}
|
||||
|
||||
func (a *Analyzer) Analyze(contents map[file.Reference]string) ([]pkg.Package, error) {
|
||||
defer a.clear()
|
||||
|
||||
packages := make([]pkg.Package, 0)
|
||||
|
||||
for _, reference := range a.selectedFiles {
|
||||
content, ok := contents[reference]
|
||||
if !ok {
|
||||
// TODO: test case
|
||||
log.Errorf("analyzer '%s' file content missing: %+v", a.Name(), reference)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
entries, err := ParseEntries(strings.NewReader(content))
|
||||
entries, err := ParseDpkgStatusEntries(strings.NewReader(content))
|
||||
if err != nil {
|
||||
// TODO: test case
|
||||
log.Errorf("analyzer failed to parse entries (reference=%+v): %w", reference, err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
packages = append(packages, pkg.Package{
|
||||
Name: entry.Package,
|
||||
|
||||
@@ -12,12 +12,12 @@ import (
|
||||
|
||||
var errEndOfPackages = fmt.Errorf("no more packages to read")
|
||||
|
||||
func ParseEntries(reader io.Reader) ([]pkg.DpkgMetadata, error) {
|
||||
func ParseDpkgStatusEntries(reader io.Reader) ([]pkg.DpkgMetadata, error) {
|
||||
buffedReader := bufio.NewReader(reader)
|
||||
var entries = make([]pkg.DpkgMetadata, 0)
|
||||
|
||||
for {
|
||||
entry, err := parseEntry(buffedReader)
|
||||
entry, err := parseDpkgStatusEntry(buffedReader)
|
||||
if err != nil {
|
||||
if err == errEndOfPackages {
|
||||
break
|
||||
@@ -30,7 +30,7 @@ func ParseEntries(reader io.Reader) ([]pkg.DpkgMetadata, error) {
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func parseEntry(reader *bufio.Reader) (entry pkg.DpkgMetadata, err error) {
|
||||
func parseDpkgStatusEntry(reader *bufio.Reader) (entry pkg.DpkgMetadata, err error) {
|
||||
dpkgFields := make(map[string]string)
|
||||
var key string
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ func TestSinglePackage(t *testing.T) {
|
||||
|
||||
reader := bufio.NewReader(file)
|
||||
|
||||
entry, err := parseEntry(reader)
|
||||
entry, err := parseDpkgStatusEntry(reader)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to read file contents: ", err)
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func TestMultiplePackages(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
|
||||
entries, err := ParseEntries(file)
|
||||
entries, err := ParseDpkgStatusEntries(file)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to read file contents: ", err)
|
||||
}
|
||||
Reference in New Issue
Block a user