mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-23 15:37:50 -08:00
Signed-off-by: knqyf263 <knqyf263@gmail.com> Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Co-authored-by: DmitriyLewen <dmitriy.lewen@smartforce.io>
87 lines
2.2 KiB
Go
87 lines
2.2 KiB
Go
package packagesprops
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"strings"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/aquasecurity/trivy/pkg/dependency"
|
|
"github.com/aquasecurity/trivy/pkg/dependency/parser/utils"
|
|
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
|
|
xio "github.com/aquasecurity/trivy/pkg/x/io"
|
|
)
|
|
|
|
type Pkg struct {
|
|
Version string `xml:"Version,attr"`
|
|
UpdatePackageName string `xml:"Update,attr"`
|
|
IncludePackageName string `xml:"Include,attr"`
|
|
}
|
|
|
|
// https://github.com/dotnet/roslyn-tools/blob/b4c5220f5dfc4278847b6d38eff91cc1188f8066/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L150
|
|
type itemGroup struct {
|
|
PackageReferenceEntry []Pkg `xml:"PackageReference"`
|
|
PackageVersionEntry []Pkg `xml:"PackageVersion"`
|
|
}
|
|
|
|
type project struct {
|
|
XMLName xml.Name `xml:"Project"`
|
|
ItemGroups []itemGroup `xml:"ItemGroup"`
|
|
}
|
|
|
|
type Parser struct{}
|
|
|
|
func NewParser() *Parser {
|
|
return &Parser{}
|
|
}
|
|
|
|
func (p Pkg) Package() ftypes.Package {
|
|
// Update attribute is considered legacy, so preferring Include
|
|
name := p.UpdatePackageName
|
|
if p.IncludePackageName != "" {
|
|
name = p.IncludePackageName
|
|
}
|
|
|
|
name = strings.TrimSpace(name)
|
|
version := strings.TrimSpace(p.Version)
|
|
return ftypes.Package{
|
|
ID: dependency.ID(ftypes.NuGet, name, version),
|
|
Name: name,
|
|
Version: version,
|
|
}
|
|
}
|
|
|
|
func shouldSkipPkg(pkg ftypes.Package) bool {
|
|
if pkg.Name == "" || pkg.Version == "" {
|
|
return true
|
|
}
|
|
// *packages.props files don't contain variable resolution information.
|
|
// So we need to skip them.
|
|
if isVariable(pkg.Name) || isVariable(pkg.Version) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func isVariable(s string) bool {
|
|
return strings.HasPrefix(s, "$(") && strings.HasSuffix(s, ")")
|
|
}
|
|
|
|
func (p *Parser) Parse(r xio.ReadSeekerAt) ([]ftypes.Package, []ftypes.Dependency, error) {
|
|
var configData project
|
|
if err := xml.NewDecoder(r).Decode(&configData); err != nil {
|
|
return nil, nil, xerrors.Errorf("failed to decode '*.packages.props' file: %w", err)
|
|
}
|
|
|
|
var pkgs []ftypes.Package
|
|
for _, item := range configData.ItemGroups {
|
|
for _, pkg := range append(item.PackageReferenceEntry, item.PackageVersionEntry...) {
|
|
pkg := pkg.Package()
|
|
if !shouldSkipPkg(pkg) {
|
|
pkgs = append(pkgs, pkg)
|
|
}
|
|
}
|
|
}
|
|
return utils.UniquePackages(pkgs), nil, nil
|
|
}
|