github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/analyzer/language/dotnet/nuget/nuspec.go (about) 1 package nuget 2 3 import ( 4 "encoding/xml" 5 "fmt" 6 "os" 7 "path/filepath" 8 "strings" 9 10 "golang.org/x/xerrors" 11 12 "github.com/devseccon/trivy/pkg/log" 13 "github.com/devseccon/trivy/pkg/utils/fsutils" 14 ) 15 16 const nuspecExt = "nuspec" 17 18 // https://learn.microsoft.com/en-us/nuget/reference/nuspec 19 type Package struct { 20 Metadata Metadata `xml:"metadata"` 21 } 22 23 type Metadata struct { 24 License License `xml:"license"` 25 } 26 27 type License struct { 28 Text string `xml:",chardata"` 29 Type string `xml:"type,attr"` 30 } 31 32 type nuspecParser struct { 33 packagesDir string // global packages folder - https: //learn.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders 34 } 35 36 func newNuspecParser() nuspecParser { 37 // cf. https: //learn.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders 38 packagesDir := os.Getenv("NUGET_PACKAGES") 39 if packagesDir == "" { 40 packagesDir = filepath.Join(os.Getenv("HOME"), ".nuget", "packages") 41 } 42 43 if !fsutils.DirExists(packagesDir) { 44 log.Logger.Debugf("The nuget packages directory couldn't be found. License search disabled") 45 return nuspecParser{} 46 } 47 48 return nuspecParser{ 49 packagesDir: packagesDir, 50 } 51 } 52 53 func (p nuspecParser) findLicense(name, version string) ([]string, error) { 54 if p.packagesDir == "" { 55 return nil, nil 56 } 57 58 // package path uses lowercase letters only 59 // e.g. `$HOME/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.nuspec` 60 // for `Newtonsoft.Json` v13.0.3 61 name = strings.ToLower(name) 62 version = strings.ToLower(version) 63 64 nuspecFileName := fmt.Sprintf("%s.%s", name, nuspecExt) 65 path := filepath.Join(p.packagesDir, name, version, nuspecFileName) 66 67 f, err := os.Open(path) 68 if err != nil { 69 return nil, xerrors.Errorf("unable to open %q file: %w", path, err) 70 } 71 defer func() { _ = f.Close() }() 72 73 var pkg Package 74 if err = xml.NewDecoder(f).Decode(&pkg); err != nil { 75 return nil, xerrors.Errorf("unable to decode %q file: %w", path, err) 76 } 77 78 if license := pkg.Metadata.License; license.Type != "expression" || license.Text == "" { 79 return nil, nil 80 } 81 return []string{pkg.Metadata.License.Text}, nil 82 }