Skip to content

Commit 0d09867

Browse files
jainlakshyaspiffcs
andauthored
openvex: normalize Docker Hub aliases for repository_url matching (#3172)
--------- Signed-off-by: Lakshya Jain <lakshyajain1995@gmail.com> Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> Co-authored-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
1 parent 5fbfca8 commit 0d09867

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

grype/vex/openvex/implementation.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,30 @@ func productIdentifierFromVEX(doc *openvex.VEX) []string {
8383
return products
8484
}
8585

86+
func normalizeDockerHubRepositoryURL(repoURL string) string {
87+
repoURL = strings.TrimSpace(repoURL)
88+
if repoURL == "" {
89+
return repoURL
90+
}
91+
92+
repoURL = strings.TrimPrefix(repoURL, "https://")
93+
repoURL = strings.TrimPrefix(repoURL, "http://")
94+
95+
repoURL = strings.TrimSuffix(repoURL, "/")
96+
97+
host, rest, hasSlash := strings.Cut(repoURL, "/")
98+
99+
switch strings.ToLower(host) {
100+
case "docker.io", "index.docker.io", "registry-1.docker.io":
101+
host = "index.docker.io"
102+
}
103+
104+
if !hasSlash || rest == "" {
105+
return host
106+
}
107+
return host + "/" + rest
108+
}
109+
86110
func identifiersFromTags(tags []string, name string) []string {
87111
identifiers := []string{}
88112

@@ -130,11 +154,14 @@ func identifiersFromDigests(digests []string) []string {
130154
fmt.Sprintf("/%s", name),
131155
)
132156

157+
repoURL = normalizeDockerHubRepositoryURL(repoURL)
158+
133159
qMap := map[string]string{}
134160

135161
if repoURL != "" {
136162
qMap["repository_url"] = repoURL
137163
}
164+
138165
qs := packageurl.QualifiersFromMap(qMap)
139166
identifiers = append(identifiers, packageurl.NewPackageURL(
140167
"oci", "", name, shaString, qs, "",

grype/vex/openvex/implementation_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package openvex
22

33
import (
4+
"strings"
45
"testing"
56

7+
"github.com/anchore/packageurl-go"
68
openvex "github.com/openvex/go-vex/pkg/vex"
79
"github.com/stretchr/testify/require"
810

@@ -413,3 +415,53 @@ func TestProductIdentifiersFromContext(t *testing.T) {
413415
})
414416
}
415417
}
418+
419+
func TestIdentifiersFromDigests_NormalizesDockerHubRepositoryURL(t *testing.T) {
420+
const hash = "124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126"
421+
const digest = "docker.io/library/alpine@sha256:" + hash
422+
423+
ids := identifiersFromDigests([]string{digest})
424+
425+
var repoURL string
426+
for _, id := range ids {
427+
if !strings.HasPrefix(id, "pkg:oci/") {
428+
continue
429+
}
430+
431+
p, err := packageurl.FromString(id)
432+
require.NoError(t, err)
433+
434+
if p.Name == "alpine" && p.Version == "sha256:"+hash {
435+
repoURL = p.Qualifiers.Map()["repository_url"]
436+
break
437+
}
438+
}
439+
440+
require.NotEmpty(t, repoURL, "expected to find alpine purl in identifiers: %#v", ids)
441+
require.Equal(t, "index.docker.io/library", repoURL)
442+
}
443+
444+
func TestNormalizeDockerHubRepositoryURL(t *testing.T) {
445+
tests := []struct {
446+
input string
447+
expected string
448+
}{
449+
{"docker.io/library", "index.docker.io/library"},
450+
{"index.docker.io/library", "index.docker.io/library"},
451+
{"registry-1.docker.io/library", "index.docker.io/library"},
452+
{"https://docker.io/library", "index.docker.io/library"},
453+
{"http://docker.io/library", "index.docker.io/library"},
454+
{"gcr.io/myorg", "gcr.io/myorg"},
455+
{"", ""},
456+
{"DOCKER.IO/Library", "index.docker.io/Library"},
457+
{"docker.io", "index.docker.io"},
458+
{"docker.io/", "index.docker.io"},
459+
{" docker.io/library ", "index.docker.io/library"},
460+
}
461+
for _, tc := range tests {
462+
t.Run(tc.input, func(t *testing.T) {
463+
got := normalizeDockerHubRepositoryURL(tc.input)
464+
require.Equal(t, tc.expected, got)
465+
})
466+
}
467+
}

0 commit comments

Comments
 (0)