archive: fix zip entry named "." hiding every other file GHSA-66hp-wgxq-6f5q

A zip containing a file entry whose name refers to the archive's own
root (".", "/" or "") was presented as a single file called "." and
all its other entries disappeared. A file at the root can only be the
archive member the backend was pointed at, so with no root such an
entry is skipped like any other unsafe name.
This commit is contained in:
Nick Craig-Wood
2026-09-04 19:00:22 +01:00
parent 7a00e13cd0
commit 45391c04ff
2 changed files with 32 additions and 0 deletions
+8
View File
@@ -163,6 +163,14 @@ func (f *Fs) readZip() (singleObject bool, err error) {
dt.AddDir(dir)
} else {
if remote == "" {
// A file at the root itself can only be the
// archive member f.root points at - with no root
// it is a crafted name for the archive's own
// directory, which can't be a file
if f.root == "" {
skipped++
continue
}
remote = path.Base(f.root)
singleObject = true
dt = dirtree.New()
+24
View File
@@ -104,3 +104,27 @@ func TestReadZipRootBoundary(t *testing.T) {
remotes := allRemotes(t, f)
assert.Equal(t, []string{"a.txt"}, remotes)
}
// A file entry whose name refers to the archive's own root (".", "/",
// "./" or "") must be skipped, not turn the whole archive into a single
// file which hides every other entry.
func TestReadZipRootNamedEntry(t *testing.T) {
ctx := context.Background()
dir := t.TempDir()
name := writeZip(t, dir, "dot.zip",
".",
"/",
"./",
"",
"good.txt",
)
localFs, err := cache.Get(ctx, dir)
require.NoError(t, err)
f, err := New(ctx, localFs, name, "", "")
require.NoError(t, err)
remotes := allRemotes(t, f)
assert.Equal(t, []string{"good.txt"}, remotes)
}