From 32175374bae475582bdd2c4252716f79e4979d0d Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 25 Aug 2026 12:44:39 +0100 Subject: [PATCH] archive: fix "directory not found" for archive paths containing "./" or "//" GHSA-66hp-wgxq-6f5q The path inside the archive was compared against the cleaned entry names without being cleaned itself, so `archive.zip/sub/./dir` or `archive.zip/sub//dir` failed to list even though `archive.zip/sub/dir` worked. --- backend/archive/archive.go | 8 +++++-- backend/archive/archive_internal_test.go | 30 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/backend/archive/archive.go b/backend/archive/archive.go index 20cca571a..ec0e6c36c 100644 --- a/backend/archive/archive.go +++ b/backend/archive/archive.go @@ -185,8 +185,12 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (outFs fs foundArchive := subArchive(remote) if foundArchive != nil { fs.Debugf(nil, "Found archiver for %q remote %q", foundArchive.archiver.Extension, foundArchive.remote) - // Archive path - foundArchive.root = strings.Trim(remote[len(foundArchive.remote):], "/") + // Archive path, in canonical form so that it compares equal + // to the cleaned entry names inside the archive + foundArchive.root = strings.Trim(path.Clean(remote[len(foundArchive.remote):]), "/") + if foundArchive.root == "." { + foundArchive.root = "" + } // Path to the archive archiveRemote := remote[:len(foundArchive.remote)] // Remote is archive leaf name diff --git a/backend/archive/archive_internal_test.go b/backend/archive/archive_internal_test.go index 0866b7dec..f0ea6a253 100644 --- a/backend/archive/archive_internal_test.go +++ b/backend/archive/archive_internal_test.go @@ -3,6 +3,7 @@ package archive import ( + "archive/zip" "bytes" "context" "fmt" @@ -277,3 +278,32 @@ func TestArchiveSquashfsIssue9004(t *testing.T) { assert.True(t, bytes.HasPrefix(data, []byte("