Skip to content

Commit 5d4fada

Browse files
committed
claircore: add Alias type
This provides a standardized way to identify aliases and cross-references between vulnerabilities. See-also: https://issues.redhat.com/browse/CLAIRDEV-85 Change-Id: I7255300dddb328dcb5b579523c8efcffe1a560f0 Signed-off-by: Hank Donnay <hdonnay@redhat.com>
1 parent 909e410 commit 5d4fada

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

alias.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package claircore
2+
3+
import (
4+
"strings"
5+
"unique"
6+
)
7+
8+
// Alias is an identifier for the same conceptual vulnerability.
9+
// An alias has two parts: the namespace and the name.
10+
//
11+
// The namespace has no format restrictions, but is almost certainly in one of two
12+
// formats:
13+
// - URI (https://example.com/)
14+
// - short prefix (EX)
15+
//
16+
// The name has no format restrictions and is only assumed to be unique within
17+
// the namespace.
18+
type Alias struct {
19+
Space unique.Handle[string]
20+
Name string
21+
}
22+
23+
// String implements [fmt.Stringer].
24+
func (a Alias) String() string {
25+
space := a.Space.Value()
26+
27+
var b strings.Builder
28+
b.WriteString(space)
29+
if strings.Contains(space, "://") { // If URI-ish:
30+
b.WriteByte('#')
31+
} else {
32+
b.WriteByte('-')
33+
}
34+
b.WriteString(a.Name)
35+
36+
return b.String()
37+
}
38+
39+
// Equal reports if two Aliases are the same alias.
40+
func (a Alias) Equal(b Alias) bool {
41+
return a.Space == b.Space && a.Name == b.Name
42+
}
43+
44+
// Valid reports if the receiver is a valid alias.
45+
//
46+
// A invalid alias is one with a missing or empty Space or Name.
47+
func (a Alias) Valid() bool {
48+
return a.Space != unique.Handle[string]{} && a.Space.Value() != "" && a.Name != ""
49+
}

alias_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package claircore
2+
3+
import (
4+
"fmt"
5+
"unique"
6+
)
7+
8+
func alias(space, name string) Alias {
9+
return Alias{
10+
Space: unique.Make(space),
11+
Name: name,
12+
}
13+
}
14+
15+
func ExampleAlias_uri() {
16+
fmt.Println(alias("https://example.com/", "CVE-2014-0160"))
17+
// Output:
18+
// https://example.com/#CVE-2014-0160
19+
}
20+
21+
func ExampleAlias_cve() {
22+
fmt.Println(alias("CVE", "2014-0160"))
23+
// Output:
24+
// CVE-2014-0160
25+
}
26+
27+
func ExampleAlias_Equal() {
28+
a, b := alias("CVE", "2014-0160"), alias("CVE", "2014-0160")
29+
fmt.Println("equal:", a.Equal(b))
30+
// Output:
31+
// equal: true
32+
}

vulnerability.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ type Vulnerability struct {
3838
// ArchOperation indicates how the affected Package's "arch" should be
3939
// compared.
4040
ArchOperation ArchOp `json:"arch_op,omitempty"`
41+
42+
// Self is an Alias that is the "identity" for this Vulnerability.
43+
//
44+
// This should be a system-wide, external identifier.
45+
Self Alias
46+
// Aliases is a set of aliases for the same abstract software flaw.
47+
//
48+
// For example, GHSA advisories frequently also reference CVE identifiers.
49+
//
50+
// This may contain the "Self" alias.
51+
Aliases []Alias
4152
}
4253

4354
// CheckVulnernableFunc takes a vulnerability and an indexRecord and checks if the record is

0 commit comments

Comments
 (0)