From d8cf223e2d2a62ab5bee277554e67f9de363af31 Mon Sep 17 00:00:00 2001 From: Wayne Starr Date: Tue, 31 Oct 2023 16:22:05 -0600 Subject: [PATCH] Use ToSlash / FromSlash to normalize filepaths --- src/pkg/layout/package.go | 14 +++++++++----- src/pkg/oci/manifest.go | 4 ++-- src/pkg/oci/pull.go | 11 +++++++++-- src/pkg/packager/create.go | 4 ++++ src/pkg/packager/sources/validate.go | 5 ++++- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/pkg/layout/package.go b/src/pkg/layout/package.go index af4dfe5eff..86da207cc3 100644 --- a/src/pkg/layout/package.go +++ b/src/pkg/layout/package.go @@ -177,7 +177,8 @@ func (pp *PackagePaths) SetFromLayers(layers []ocispec.Descriptor) { // SetFromPaths maps paths to package paths. func (pp *PackagePaths) SetFromPaths(paths []string) { for _, rel := range paths { - switch path := rel; { + // Convert from the standard '/' to the OS path separator for Windows support + switch path := filepath.FromSlash(rel); { case path == ZarfYAML: pp.ZarfYAML = filepath.Join(pp.Base, path) case path == Signature: @@ -186,11 +187,11 @@ func (pp *PackagePaths) SetFromPaths(paths []string) { pp.Checksums = filepath.Join(pp.Base, path) case path == SBOMTar: pp.SBOMs.Path = filepath.Join(pp.Base, path) - case path == strings.Join([]string{ImagesDir, OCILayout}, "/"): + case path == filepath.Join(ImagesDir, OCILayout): pp.Images.OCILayout = filepath.Join(pp.Base, path) - case path == strings.Join([]string{ImagesDir, IndexJSON}, "/"): + case path == filepath.Join(ImagesDir, IndexJSON): pp.Images.Index = filepath.Join(pp.Base, path) - case strings.HasPrefix(path, strings.Join([]string{ImagesDir, "blobs", "sha256"}, "/")): + case strings.HasPrefix(path, filepath.Join(ImagesDir, "blobs", "sha256")): if pp.Images.Base == "" { pp.Images.Base = filepath.Join(pp.Base, ImagesDir) } @@ -213,16 +214,19 @@ func (pp *PackagePaths) SetFromPaths(paths []string) { // Files returns a map of all the files in the package. func (pp *PackagePaths) Files() map[string]string { pathMap := make(map[string]string) + stripBase := func(path string) string { rel, _ := filepath.Rel(pp.Base, path) - return rel + return filepath.ToSlash(rel) } + add := func(path string) { if path == "" { return } pathMap[stripBase(path)] = path } + add(pp.ZarfYAML) add(pp.Signature) add(pp.Checksums) diff --git a/src/pkg/oci/manifest.go b/src/pkg/oci/manifest.go index 7c370e6864..1c954bd2c1 100644 --- a/src/pkg/oci/manifest.go +++ b/src/pkg/oci/manifest.go @@ -35,9 +35,9 @@ func NewZarfOCIManifest(manifest *ocispec.Manifest) *ZarfOCIManifest { } // Locate returns the descriptor for the first layer with the given path or digest. -func (m *ZarfOCIManifest) Locate(uri string) ocispec.Descriptor { +func (m *ZarfOCIManifest) Locate(pathOrDigest string) ocispec.Descriptor { return helpers.Find(m.Layers, func(layer ocispec.Descriptor) bool { - return layer.Annotations[ocispec.AnnotationTitle] == uri || layer.Digest.Encoded() == uri + return layer.Annotations[ocispec.AnnotationTitle] == filepath.ToSlash(pathOrDigest) || layer.Digest.Encoded() == pathOrDigest }) } diff --git a/src/pkg/oci/pull.go b/src/pkg/oci/pull.go index c109f8efd5..4b1d670810 100644 --- a/src/pkg/oci/pull.go +++ b/src/pkg/oci/pull.go @@ -32,7 +32,10 @@ var ( // FileDescriptorExists returns true if the given file exists in the given directory with the expected SHA. func (o *OrasRemote) FileDescriptorExists(desc ocispec.Descriptor, destinationDir string) bool { - destinationPath := filepath.Join(destinationDir, desc.Annotations[ocispec.AnnotationTitle]) + // Convert from the standard '/' to the OS path separator for Windows support + rel := filepath.FromSlash(desc.Annotations[ocispec.AnnotationTitle]) + destinationPath := filepath.Join(destinationDir, rel) + info, err := os.Stat(destinationPath) if err != nil { return false @@ -250,7 +253,11 @@ func (o *OrasRemote) PullLayer(desc ocispec.Descriptor, destinationDir string) e if err != nil { return err } - return utils.WriteFile(filepath.Join(destinationDir, desc.Annotations[ocispec.AnnotationTitle]), b) + + // Convert from the standard '/' to the OS path separator for Windows support + rel := filepath.FromSlash(desc.Annotations[ocispec.AnnotationTitle]) + + return utils.WriteFile(filepath.Join(destinationDir, rel), b) } // PullPackagePaths pulls multiple files from the remote repository and saves them to `destinationDir`. diff --git a/src/pkg/packager/create.go b/src/pkg/packager/create.go index 4f1f5854b0..292e51f7c0 100755 --- a/src/pkg/packager/create.go +++ b/src/pkg/packager/create.go @@ -598,6 +598,10 @@ func (p *Packager) generatePackageChecksums() (string, error) { if rel == layout.ZarfYAML || rel == layout.Checksums { continue } + + // Convert from the OS path separator to '/' for Windows support + rel = filepath.ToSlash(rel) + sum, err := utils.GetSHA256OfFile(abs) if err != nil { return "", err diff --git a/src/pkg/packager/sources/validate.go b/src/pkg/packager/sources/validate.go index bf4b259268..9e207846db 100644 --- a/src/pkg/packager/sources/validate.go +++ b/src/pkg/packager/sources/validate.go @@ -88,7 +88,10 @@ func ValidatePackageIntegrity(loaded *layout.PackagePaths, aggregateChecksum str err = lineByLine(checksumPath, func(line string) error { split := strings.Split(line, " ") sha := split[0] - rel := split[1] + + // Convert from the standard '/' to the OS path separator for Windows support + rel := filepath.FromSlash(split[1]) + if sha == "" || rel == "" { return fmt.Errorf("invalid checksum line: %s", line) }