diff --git a/util/ocilayout/parse.go b/util/ocilayout/parse.go index 87796f7e08e7..2b716d48fe09 100644 --- a/util/ocilayout/parse.go +++ b/util/ocilayout/parse.go @@ -34,7 +34,7 @@ func Parse(s string) (Ref, bool, error) { } } - if i := strings.LastIndex(localPath, ":"); i >= 0 { + if i := strings.LastIndex(localPath, ":"); i >= 0 && !isWindowsDrivePath(localPath, i) { after := localPath[i+1:] if reference.TagRegexp.MatchString(after) { localPath, out.Tag = localPath[:i], after @@ -51,10 +51,18 @@ func Parse(s string) (Ref, bool, error) { func (r Ref) String() string { s := prefix + r.Path if r.Tag != "" { - return s + ":" + r.Tag + s += ":" + r.Tag } if r.Digest != "" { - return s + "@" + r.Digest.String() + s += "@" + r.Digest.String() } return s } + +func isWindowsDrivePath(path string, colon int) bool { + if colon != 1 || len(path) < 2 { + return false + } + c := path[0] + return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') +} diff --git a/util/ocilayout/parse_test.go b/util/ocilayout/parse_test.go index 1370d512dcd4..d2ecf5153430 100644 --- a/util/ocilayout/parse_test.go +++ b/util/ocilayout/parse_test.go @@ -3,6 +3,7 @@ package ocilayout import ( "testing" + digest "github.com/opencontainers/go-digest" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -39,6 +40,27 @@ func TestParse(t *testing.T) { path: "/path/to/oci/@/layout", tag: "latest", }, + { + s: `oci-layout://C:\path\to\oci\layout`, + path: `C:\path\to\oci\layout`, + tag: "latest", + }, + { + s: `oci-layout://C:\path\to\oci\layout:1.3`, + path: `C:\path\to\oci\layout`, + tag: "1.3", + }, + { + s: `oci-layout://C:\path\to\oci\layout@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`, + path: `C:\path\to\oci\layout`, + dgst: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + }, + { + s: `oci-layout://C:\path\to\oci\layout:1.3@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`, + path: `C:\path\to\oci\layout`, + tag: "1.3", + dgst: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + }, } { ref, ok, err := Parse(tt.s) require.True(t, ok) @@ -48,3 +70,13 @@ func TestParse(t *testing.T) { assert.Equal(t, tt.tag, ref.Tag, "comparing tag: %s", tt.s) } } + +func TestRefString(t *testing.T) { + ref := Ref{ + Path: "/path/to/oci/layout", + Tag: "1.3", + Digest: digest.Digest("sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), + } + + assert.Equal(t, "oci-layout:///path/to/oci/layout:1.3@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ref.String()) +}