mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 05:40:11 +01:00
feat: Add function to find product identification helpers inspecting the tree (#505)
* feat: Add function to find product identification helpers inspecting the tree Signed-off-by: juan131 <jariza@vmware.com> * fix: simplify unit tests Signed-off-by: juan131 <jariza@vmware.com> * fix: also iterate over relationships Signed-off-by: juan131 <jariza@vmware.com> * fix: adapt example to use new library function Signed-off-by: juan131 <jariza@vmware.com> * Separate collecting and visiting of the product id helpers. --------- Signed-off-by: juan131 <jariza@vmware.com> Co-authored-by: Sascha L. Teichmann <sascha.teichmann@intevation.de>
This commit is contained in:
parent
b457dc872f
commit
9073a8a282
3 changed files with 258 additions and 96 deletions
|
|
@ -9,9 +9,8 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/csaf-poc/csaf_distribution/v3/csaf"
|
||||
"github.com/csaf-poc/csaf_distribution/v3/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
@ -35,106 +34,26 @@ func main() {
|
|||
|
||||
// run prints PURLs belonging to the given Product IDs.
|
||||
func run(files []string, ids string) error {
|
||||
|
||||
uf := newURLFinder(strings.Split(ids, ","))
|
||||
|
||||
for _, file := range files {
|
||||
adv, err := csaf.LoadAdvisory(file)
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading %q failed: %w", file, err)
|
||||
}
|
||||
uf.findURLs(adv)
|
||||
uf.dumpURLs()
|
||||
uf.clear()
|
||||
|
||||
for _, id := range strings.Split(ids, ",") {
|
||||
already := util.Set[csaf.PURL]{}
|
||||
i := 0
|
||||
adv.ProductTree.FindProductIdentificationHelpers(
|
||||
csaf.ProductID(id),
|
||||
func(h *csaf.ProductIdentificationHelper) {
|
||||
if h.PURL != nil && !already.Contains(*h.PURL) {
|
||||
already.Add(*h.PURL)
|
||||
i++
|
||||
fmt.Printf("%d. %s\n", i, *h.PURL)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// urlFinder helps to find the URLs of a set of product ids in advisories.
|
||||
type urlFinder struct {
|
||||
ids []csaf.ProductID
|
||||
urls [][]csaf.PURL
|
||||
}
|
||||
|
||||
// newURLFinder creates a new urlFinder for given ids.
|
||||
func newURLFinder(ids []string) *urlFinder {
|
||||
uf := &urlFinder{
|
||||
ids: make([]csaf.ProductID, len(ids)),
|
||||
urls: make([][]csaf.PURL, len(ids)),
|
||||
}
|
||||
for i := range uf.ids {
|
||||
uf.ids[i] = csaf.ProductID(ids[i])
|
||||
}
|
||||
return uf
|
||||
}
|
||||
|
||||
// clear resets the url finder after a run on an advisory.
|
||||
func (uf *urlFinder) clear() {
|
||||
for i := range uf.urls {
|
||||
uf.urls[i] = uf.urls[i][:0]
|
||||
}
|
||||
}
|
||||
|
||||
// dumpURLs dumps the found URLs to stdout.
|
||||
func (uf *urlFinder) dumpURLs() {
|
||||
for i, urls := range uf.urls {
|
||||
if len(urls) == 0 {
|
||||
continue
|
||||
}
|
||||
fmt.Printf("Found URLs for %s:\n", uf.ids[i])
|
||||
for j, url := range urls {
|
||||
fmt.Printf("%d. %s\n", j+1, url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// findURLs find the URLs in an advisory.
|
||||
func (uf *urlFinder) findURLs(adv *csaf.Advisory) {
|
||||
tree := adv.ProductTree
|
||||
if tree == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// If we have found it and we have a valid URL add unique.
|
||||
add := func(idx int, h *csaf.ProductIdentificationHelper) {
|
||||
if idx != -1 && h != nil && h.PURL != nil &&
|
||||
!slices.Contains(uf.urls[idx], *h.PURL) {
|
||||
uf.urls[idx] = append(uf.urls[idx], *h.PURL)
|
||||
}
|
||||
}
|
||||
|
||||
// First iterate over full product names.
|
||||
if names := tree.FullProductNames; names != nil {
|
||||
for _, name := range *names {
|
||||
if name != nil && name.ProductID != nil {
|
||||
add(slices.Index(uf.ids, *name.ProductID), name.ProductIdentificationHelper)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second traverse the branches recursively.
|
||||
var recBranch func(*csaf.Branch)
|
||||
recBranch = func(b *csaf.Branch) {
|
||||
if p := b.Product; p != nil && p.ProductID != nil {
|
||||
add(slices.Index(uf.ids, *p.ProductID), p.ProductIdentificationHelper)
|
||||
}
|
||||
for _, c := range b.Branches {
|
||||
recBranch(c)
|
||||
}
|
||||
}
|
||||
for _, b := range tree.Branches {
|
||||
recBranch(b)
|
||||
}
|
||||
|
||||
// Third iterate over relationships.
|
||||
if tree.RelationShips != nil {
|
||||
for _, rel := range *tree.RelationShips {
|
||||
if rel != nil {
|
||||
if fpn := rel.FullProductName; fpn != nil && fpn.ProductID != nil {
|
||||
add(slices.Index(uf.ids, *fpn.ProductID), fpn.ProductIdentificationHelper)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue