github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/archive/zip/zip_test.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Tests that involve both reading and writing. 6 7 package zip 8 9 import ( 10 "bytes" 11 "fmt" 12 "io" 13 "io/ioutil" 14 "strings" 15 "testing" 16 "time" 17 ) 18 19 func TestOver65kFiles(t *testing.T) { 20 if testing.Short() { 21 t.Skip("slow test; skipping") 22 } 23 buf := new(bytes.Buffer) 24 w := NewWriter(buf) 25 const nFiles = (1 << 16) + 42 26 for i := 0; i < nFiles; i++ { 27 _, err := w.Create(fmt.Sprintf("%d.dat", i)) 28 if err != nil { 29 t.Fatalf("creating file %d: %v", i, err) 30 } 31 } 32 if err := w.Close(); err != nil { 33 t.Fatalf("Writer.Close: %v", err) 34 } 35 s := buf.String() 36 zr, err := NewReader(strings.NewReader(s), int64(len(s))) 37 if err != nil { 38 t.Fatalf("NewReader: %v", err) 39 } 40 if got := len(zr.File); got != nFiles { 41 t.Fatalf("File contains %d files, want %d", got, nFiles) 42 } 43 for i := 0; i < nFiles; i++ { 44 want := fmt.Sprintf("%d.dat", i) 45 if zr.File[i].Name != want { 46 t.Fatalf("File(%d) = %q, want %q", i, zr.File[i].Name, want) 47 } 48 } 49 } 50 51 func TestModTime(t *testing.T) { 52 var testTime = time.Date(2009, time.November, 10, 23, 45, 58, 0, time.UTC) 53 fh := new(FileHeader) 54 fh.SetModTime(testTime) 55 outTime := fh.ModTime() 56 if !outTime.Equal(testTime) { 57 t.Errorf("times don't match: got %s, want %s", outTime, testTime) 58 } 59 } 60 61 func testHeaderRoundTrip(fh *FileHeader, wantUncompressedSize uint32, wantUncompressedSize64 uint64, t *testing.T) { 62 fi := fh.FileInfo() 63 fh2, err := FileInfoHeader(fi) 64 if err != nil { 65 t.Fatal(err) 66 } 67 if got, want := fh2.Name, fh.Name; got != want { 68 t.Errorf("Name: got %s, want %s\n", got, want) 69 } 70 if got, want := fh2.UncompressedSize, wantUncompressedSize; got != want { 71 t.Errorf("UncompressedSize: got %d, want %d\n", got, want) 72 } 73 if got, want := fh2.UncompressedSize64, wantUncompressedSize64; got != want { 74 t.Errorf("UncompressedSize64: got %d, want %d\n", got, want) 75 } 76 if got, want := fh2.ModifiedTime, fh.ModifiedTime; got != want { 77 t.Errorf("ModifiedTime: got %d, want %d\n", got, want) 78 } 79 if got, want := fh2.ModifiedDate, fh.ModifiedDate; got != want { 80 t.Errorf("ModifiedDate: got %d, want %d\n", got, want) 81 } 82 83 if sysfh, ok := fi.Sys().(*FileHeader); !ok && sysfh != fh { 84 t.Errorf("Sys didn't return original *FileHeader") 85 } 86 } 87 88 func TestFileHeaderRoundTrip(t *testing.T) { 89 fh := &FileHeader{ 90 Name: "foo.txt", 91 UncompressedSize: 987654321, 92 ModifiedTime: 1234, 93 ModifiedDate: 5678, 94 } 95 testHeaderRoundTrip(fh, fh.UncompressedSize, uint64(fh.UncompressedSize), t) 96 } 97 98 func TestFileHeaderRoundTrip64(t *testing.T) { 99 fh := &FileHeader{ 100 Name: "foo.txt", 101 UncompressedSize64: 9876543210, 102 ModifiedTime: 1234, 103 ModifiedDate: 5678, 104 } 105 testHeaderRoundTrip(fh, uint32max, fh.UncompressedSize64, t) 106 } 107 108 func TestZip64(t *testing.T) { 109 if testing.Short() { 110 t.Skip("slow test; skipping") 111 } 112 // write 2^32 bytes plus "END\n" to a zip file 113 buf := new(bytes.Buffer) 114 w := NewWriter(buf) 115 f, err := w.Create("huge.txt") 116 if err != nil { 117 t.Fatal(err) 118 } 119 chunk := make([]byte, 1024) 120 for i := range chunk { 121 chunk[i] = '.' 122 } 123 chunk[len(chunk)-1] = '\n' 124 end := []byte("END\n") 125 for i := 0; i < (1<<32)/1024; i++ { 126 _, err := f.Write(chunk) 127 if err != nil { 128 t.Fatal("write chunk:", err) 129 } 130 } 131 _, err = f.Write(end) 132 if err != nil { 133 t.Fatal("write end:", err) 134 } 135 if err := w.Close(); err != nil { 136 t.Fatal(err) 137 } 138 139 // read back zip file and check that we get to the end of it 140 r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len())) 141 if err != nil { 142 t.Fatal("reader:", err) 143 } 144 f0 := r.File[0] 145 rc, err := f0.Open() 146 if err != nil { 147 t.Fatal("opening:", err) 148 } 149 for i := 0; i < (1<<32)/1024; i++ { 150 _, err := io.ReadFull(rc, chunk) 151 if err != nil { 152 t.Fatal("read:", err) 153 } 154 } 155 gotEnd, err := ioutil.ReadAll(rc) 156 if err != nil { 157 t.Fatal("read end:", err) 158 } 159 if !bytes.Equal(gotEnd, end) { 160 t.Errorf("End of zip64 archive %q, want %q", gotEnd, end) 161 } 162 err = rc.Close() 163 if err != nil { 164 t.Fatal("closing:", err) 165 } 166 if got, want := f0.UncompressedSize, uint32(uint32max); got != want { 167 t.Errorf("UncompressedSize %d, want %d", got, want) 168 } 169 170 if got, want := f0.UncompressedSize64, (1<<32)+uint64(len(end)); got != want { 171 t.Errorf("UncompressedSize64 %d, want %d", got, want) 172 } 173 } 174 175 func testInvalidHeader(h *FileHeader, t *testing.T) { 176 var buf bytes.Buffer 177 z := NewWriter(&buf) 178 179 f, err := z.CreateHeader(h) 180 if err != nil { 181 t.Fatalf("error creating header: %v", err) 182 } 183 if _, err := f.Write([]byte("hi")); err != nil { 184 t.Fatalf("error writing content: %v", err) 185 } 186 if err := z.Close(); err != nil { 187 t.Fatalf("error closing zip writer: %v", err) 188 } 189 190 b := buf.Bytes() 191 if _, err = NewReader(bytes.NewReader(b), int64(len(b))); err != ErrFormat { 192 t.Fatalf("got %v, expected ErrFormat", err) 193 } 194 } 195 196 func testValidHeader(h *FileHeader, t *testing.T) { 197 var buf bytes.Buffer 198 z := NewWriter(&buf) 199 200 f, err := z.CreateHeader(h) 201 if err != nil { 202 t.Fatalf("error creating header: %v", err) 203 } 204 if _, err := f.Write([]byte("hi")); err != nil { 205 t.Fatalf("error writing content: %v", err) 206 } 207 if err := z.Close(); err != nil { 208 t.Fatalf("error closing zip writer: %v", err) 209 } 210 211 b := buf.Bytes() 212 if _, err = NewReader(bytes.NewReader(b), int64(len(b))); err != nil { 213 t.Fatalf("got %v, expected nil", err) 214 } 215 } 216 217 // Issue 4302. 218 func TestHeaderInvalidTagAndSize(t *testing.T) { 219 const timeFormat = "20060102T150405.000.txt" 220 221 ts := time.Now() 222 filename := ts.Format(timeFormat) 223 224 h := FileHeader{ 225 Name: filename, 226 Method: Deflate, 227 Extra: []byte(ts.Format(time.RFC3339Nano)), // missing tag and len 228 } 229 h.SetModTime(ts) 230 231 testInvalidHeader(&h, t) 232 } 233 234 func TestHeaderTooShort(t *testing.T) { 235 h := FileHeader{ 236 Name: "foo.txt", 237 Method: Deflate, 238 Extra: []byte{zip64ExtraId}, // missing size 239 } 240 testInvalidHeader(&h, t) 241 } 242 243 // Issue 4393. It is valid to have an extra data header 244 // which contains no body. 245 func TestZeroLengthHeader(t *testing.T) { 246 h := FileHeader{ 247 Name: "extadata.txt", 248 Method: Deflate, 249 Extra: []byte{ 250 85, 84, 5, 0, 3, 154, 144, 195, 77, // tag 21589 size 5 251 85, 120, 0, 0, // tag 30805 size 0 252 }, 253 } 254 testValidHeader(&h, t) 255 }