Files
trivy/pkg/dependency/parser/nuget/packagesprops/parse.go
Teppei Fukuda 3eecfc6b6e refactor: unify Library and Package structs (#6633)
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>
2024-05-07 12:25:52 +00:00

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
}