Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-4.14] OCPBUGS-30287: oc adm catalog mirror: use ToSlash and FromSlash to unify the path separators #1699

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 6 additions & 6 deletions pkg/cli/image/extract/extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ func (n *copyFromPattern) Alter(hdr *tar.Header) (bool, error) {
return false, nil
}
matchName = hdr.Name
if i := strings.Index(matchName, "/"); i != -1 {
if i := strings.Index(matchName, string(filepath.Separator)); i != -1 {
matchName = matchName[:i]
}
}
Expand All @@ -721,19 +721,19 @@ func changeTarEntryName(hdr *tar.Header, name string) bool {
}

func changeTarEntryParent(hdr *tar.Header, from string) bool {
if !strings.HasPrefix(hdr.Name, from) {
klog.V(5).Infof("Exclude %s due to missing prefix %s", hdr.Name, from)
if !strings.HasPrefix(filepath.ToSlash(hdr.Name), from) {
klog.V(5).Infof("Exclude %s due to missing prefix %s", filepath.ToSlash(hdr.Name), from)
return false
}
if len(hdr.Linkname) > 0 {
if strings.HasPrefix(hdr.Linkname, from) {
hdr.Linkname = strings.TrimPrefix(hdr.Linkname, from)
if strings.HasPrefix(filepath.ToSlash(hdr.Linkname), from) {
hdr.Linkname = filepath.FromSlash(strings.TrimPrefix(filepath.ToSlash(hdr.Linkname), from))
klog.V(5).Infof("Updated link to %s", hdr.Linkname)
} else {
klog.V(4).Infof("Name %s won't correctly point to %s outside of %s", hdr.Name, hdr.Linkname, from)
}
}
hdr.Name = strings.TrimPrefix(hdr.Name, from)
hdr.Name = filepath.FromSlash(strings.TrimPrefix(filepath.ToSlash(hdr.Name), from))
klog.V(5).Infof("Updated name %s", hdr.Name)
return true
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/image/imagesource/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (s *fileTagStore) Get(ctx context.Context, tag string) (distribution.Descri
return distribution.Descriptor{}, err
}
return distribution.Descriptor{
Digest: godigest.Digest(filepath.Base(target)),
Digest: godigest.Digest(reconstructDigest(filepath.Base(target))),
Size: fi.Size(),
}, nil
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/cli/image/imagesource/file_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ import "path/filepath"
func generateDigestPath(digest string, elem ...string) string {
return filepath.Join(append(elem, digest)...)
}

// reconstructDigest is a no-op on Unix. See file_windows.go for more details.
func reconstructDigest(digest string) string {
return digest
}
29 changes: 29 additions & 0 deletions pkg/cli/image/imagesource/file_windows.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package imagesource

import (
"fmt"
"path/filepath"
"strings"
)
Expand All @@ -14,3 +15,31 @@ func generateDigestPath(digest string, elem ...string) string {
dgst := strings.ReplaceAll(digest, ":", "-")
return filepath.Join(append(elem, dgst)...)
}

// reconstructDigest replaces ":" with "-" which makes the digest parsing nondeterministic.
// A digest regex corresponds to `[a-z0-9](?:[.+_-][a-z0-9])*:[a-zA-Z0-9=_-]+`.
// Making "sha256-sha256:659d863050ebd58ebd2ea4b4e89226b494ba39457932ebf11669763eea3b2ed0" a valid digest.
// After the ":" replacement the filename gets translated into
// "sha256-sha256-659d863050ebd58ebd2ea4b4e89226b494ba39457932ebf11669763eea3b2ed0" which has
// two matching digests:
// - sha256-sha256:659d863050ebd58ebd2ea4b4e89226b494ba39457932ebf11669763eea3b2ed0
// - sha256:sha256-659d863050ebd58ebd2ea4b4e89226b494ba39457932ebf11669763eea3b2ed0
//
// From https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests:
// digest ::= algorithm ":" encoded
// algorithm ::= algorithm-component (algorithm-separator algorithm-component)*
// algorithm-component ::= [a-z0-9]+
// algorithm-separator ::= [+._-]
// encoded ::= [a-zA-Z0-9=_-]+
//
// Given only sha256 and sha512 are currently supported (based on the linked descriptor.md#digests)
// we can parse these two cases and panic for the rest.
func reconstructDigest(digest string) string {
if strings.HasPrefix(digest, "sha256-") {
return "sha256:" + strings.TrimPrefix(digest, "sha256-")
}
if strings.HasPrefix(digest, "sha512-") {
return "sha512:" + strings.TrimPrefix(digest, "sha512-")
}
panic(fmt.Sprintf("Only 'sha256-' and 'sha512-' digest prefixes are supported on Windows. Got %q", digest))
}