aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/archive/zip/reader.go11
-rw-r--r--src/archive/zip/reader_test.go81
2 files changed, 91 insertions, 1 deletions
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
index 6b57f767fc..b2a4ed6042 100644
--- a/src/archive/zip/reader.go
+++ b/src/archive/zip/reader.go
@@ -834,7 +834,16 @@ func (r *Reader) initFileList() {
continue
}
- for dir := path.Dir(name); dir != "."; dir = path.Dir(dir) {
+ dir := name
+ for {
+ if idx := strings.LastIndex(dir, "/"); idx < 0 {
+ break
+ } else {
+ dir = dir[:idx]
+ }
+ if dirs[dir] {
+ break
+ }
dirs[dir] = true
}
diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
index cb8a0c2871..5ce994e4dd 100644
--- a/src/archive/zip/reader_test.go
+++ b/src/archive/zip/reader_test.go
@@ -9,6 +9,7 @@ import (
"encoding/binary"
"encoding/hex"
"errors"
+ "fmt"
"internal/obscuretestdata"
"io"
"io/fs"
@@ -1874,3 +1875,83 @@ func TestBaseOffsetPlusOverflow(t *testing.T) {
// as the section reader offset & size were < 0.
NewReader(bytes.NewReader(data), int64(len(data))+1875)
}
+
+func BenchmarkReaderOneDeepDir(b *testing.B) {
+ var buf bytes.Buffer
+ zw := NewWriter(&buf)
+
+ for i := range 4000 {
+ name := strings.Repeat("a/", i) + "data"
+ zw.CreateHeader(&FileHeader{
+ Name: name,
+ Method: Store,
+ })
+ }
+
+ if err := zw.Close(); err != nil {
+ b.Fatal(err)
+ }
+ data := buf.Bytes()
+
+ for b.Loop() {
+ zr, err := NewReader(bytes.NewReader(data), int64(len(data)))
+ if err != nil {
+ b.Fatal(err)
+ }
+ zr.Open("does-not-exist")
+ }
+}
+
+func BenchmarkReaderManyDeepDirs(b *testing.B) {
+ var buf bytes.Buffer
+ zw := NewWriter(&buf)
+
+ for i := range 2850 {
+ name := fmt.Sprintf("%x", i)
+ name = strings.Repeat("/"+name, i+1)[1:]
+
+ zw.CreateHeader(&FileHeader{
+ Name: name,
+ Method: Store,
+ })
+ }
+
+ if err := zw.Close(); err != nil {
+ b.Fatal(err)
+ }
+ data := buf.Bytes()
+
+ for b.Loop() {
+ zr, err := NewReader(bytes.NewReader(data), int64(len(data)))
+ if err != nil {
+ b.Fatal(err)
+ }
+ zr.Open("does-not-exist")
+ }
+}
+
+func BenchmarkReaderManyShallowFiles(b *testing.B) {
+ var buf bytes.Buffer
+ zw := NewWriter(&buf)
+
+ for i := range 310000 {
+ name := fmt.Sprintf("%v", i)
+ zw.CreateHeader(&FileHeader{
+ Name: name,
+ Method: Store,
+ })
+ }
+
+ if err := zw.Close(); err != nil {
+ b.Fatal(err)
+ }
+ data := buf.Bytes()
+
+ for b.Loop() {
+ zr, err := NewReader(bytes.NewReader(data), int64(len(data)))
+ if err != nil {
+ b.Fatal(err)
+ }
+ zr.Open("does-not-exist")
+ }
+}