From bfcd2d1e800d78a9da9b9ab24f624c4621875ae3 Mon Sep 17 00:00:00 2001 From: Andrew Gerrand Date: Mon, 8 Apr 2013 15:38:06 +1000 Subject: [PATCH] archive/zip: handle trailing data after the end of directory header The spec doesn't explicitly say that trailing data is okay, but a lot of people do this and most unzippers will handle it just fine. In any case, this makes the package more useful, and led me to make the directory parsing code marginally more robust. Fixes #5228. R=golang-dev, dsymonds CC=golang-dev https://golang.org/cl/8504044 --- src/pkg/archive/zip/reader.go | 7 +++++- src/pkg/archive/zip/reader_test.go | 20 +++++++++++++++++- .../zip/testdata/test-trailing-junk.zip | Bin 0 -> 1184 bytes 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 src/pkg/archive/zip/testdata/test-trailing-junk.zip diff --git a/src/pkg/archive/zip/reader.go b/src/pkg/archive/zip/reader.go index c10f29a836..f19cf2d1f1 100644 --- a/src/pkg/archive/zip/reader.go +++ b/src/pkg/archive/zip/reader.go @@ -353,6 +353,11 @@ func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, err error) if err != nil { return nil, err } + + // Make sure directoryOffset points to somewhere in our file. + if o := int64(d.directoryOffset); o < 0 || o >= size { + return nil, ErrFormat + } return d, nil } @@ -407,7 +412,7 @@ func findSignatureInBlock(b []byte) int { if b[i] == 'P' && b[i+1] == 'K' && b[i+2] == 0x05 && b[i+3] == 0x06 { // n is length of comment n := int(b[i+directoryEndLen-2]) | int(b[i+directoryEndLen-1])<<8 - if n+directoryEndLen+i == len(b) { + if n+directoryEndLen+i <= len(b) { return i } } diff --git a/src/pkg/archive/zip/reader_test.go b/src/pkg/archive/zip/reader_test.go index cf9c59c4b9..833ba28ad5 100644 --- a/src/pkg/archive/zip/reader_test.go +++ b/src/pkg/archive/zip/reader_test.go @@ -63,6 +63,24 @@ var tests = []ZipTest{ }, }, }, + { + Name: "test-trailing-junk.zip", + Comment: "This is a zipfile comment.", + File: []ZipTestFile{ + { + Name: "test.txt", + Content: []byte("This is a test text file.\n"), + Mtime: "09-05-10 12:12:02", + Mode: 0644, + }, + { + Name: "gophercolor16x16.png", + File: "gophercolor16x16.png", + Mtime: "09-05-10 15:52:58", + Mode: 0644, + }, + }, + }, { Name: "r.zip", Source: returnRecursiveZip, @@ -262,7 +280,7 @@ func readTestZip(t *testing.T, zt ZipTest) { } } if err != zt.Error { - t.Errorf("error=%v, want %v", err, zt.Error) + t.Errorf("%s: error=%v, want %v", zt.Name, err, zt.Error) return } diff --git a/src/pkg/archive/zip/testdata/test-trailing-junk.zip b/src/pkg/archive/zip/testdata/test-trailing-junk.zip new file mode 100644 index 0000000000000000000000000000000000000000..42281b4e3053eec7924b58d234d04e492c3baa38 GIT binary patch literal 1184 zcmWIWW@Zs#U|`^2XiQYKJ#hW)VM!oQ3M?YSP?B0)qE}K;5*otEz+CvJ$)^m6ODnh; z7+JnDGBAL3a-Te*6UMN}rFGJkM?wmLfr}l&aaaM)^pwV1FgBTd*)~VY5GrSri z$jrb1!XgYZ4C(m=8L36d`8oMThGrFpW_ksA>0oQD44Qqcff&u2&Hz7mUM?w+fxMm` zE&U=x?Zy@V2qPe0vcxr_Bsf2F!C6nVlf&(QE?5{rm?pSGb*exy9+#I&RurKk- z+m)0yRCPG=d-HHDZeo&8l5*8w*j(kQ)h25CKV`;*MHBS|=I94cI>i2RTbstM*llm) zO8IWizic_XckQR<_w%av+wcEed*5>UK?&z&H{O(96e0boH{+WCE(bu95f2^3EZ4O=VNZ?3)UvtyJg5QDRcf$^EI~Jki zWtQzJsL_x*GnsW)scd27+nNv&O9`(nP~TLZC!C)&dpmb9Gex+~DL%5m{kC!2{41u2r}!o#L;7=ONQ zE-qq{y7hnokNZ9E^>G%L>tA=N)+ZKnN{AiY63=$`mQ27(iv*7buak|7iv?tIZF@fl zt>|OAAsR5{#f{tFon;*@eKst4U%}L6{!DE$Q;-Gc;z`Q`4>jq0{kyW^?3@=d0sB55 zxoLcI^%PC5#tAeEd>m$^DR^;2N$vDP24)a*LyE?_;6T$0ZaWgUlR!) zO)1Y`?`E^OggslIl9kNpY|u0@YV$J_L(}Dqa{cO(OH|YIR<91PW~;8;CG9SvxT%P1 zf&1?rTi;(l9{BL-LFV7-o3%9b_5H&Yx{{nGExEP)?O%T1_U}*5o%1=o!$7pc+~7{P zVEy`CyQ(f_ZB6^{)1;6Rw%g;&&eO(;vcI48f3W$#VE69d#v5C|RN3w=iCp_vEP-JK z2X8m?^Q2e6G|k}Y>gTe~DWNIAn~_P58CTww04Zev=23TwQdKa(&kYWhQ$ShU>qC|zN%!0JcoK%J6 Y{M_8syb`_Q{M=N9y!^c4R3PF40F)}f^8f$< literal 0 HcmV?d00001 -- 2.50.0