// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Small in-memory unzip implementation. // A simplified copy of the pre-Go 1 compress/flate/inflate.go // and a modified copy of the zip reader in package time. // (The one in package time does not support decompression; this one does.) package syscall const ( maxCodeLen = 16 // max length of Huffman code maxHist = 32768 // max history required maxLit = 286 maxDist = 32 numCodes = 19 // number of codes in Huffman meta-code ) type decompressor struct { in string // compressed input out []byte // uncompressed output b uint32 // input bits, at top of b nb uint err bool // invalid input eof bool // reached EOF h1, h2 huffmanDecoder // decoders for literal/length, distance bits [maxLit + maxDist]int // lengths defining Huffman codes codebits [numCodes]int } func (f *decompressor) nextBlock() { for f.nb < 1+2 { if f.moreBits(); f.err { return } } f.eof = f.b&1 == 1 f.b >>= 1 typ := f.b & 3 f.b >>= 2 f.nb -= 1 + 2 switch typ { case 0: f.dataBlock() case 1: // compressed, fixed Huffman tables f.huffmanBlock(&fixedHuffmanDecoder, nil) case 2: // compressed, dynamic Huffman tables if f.readHuffman(); f.err { break } f.huffmanBlock(&f.h1, &f.h2) default: // 3 is reserved. f.err = true } } // RFC 1951 section 3.2.7. // Compression with dynamic Huffman codes var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15} func (f *decompressor) readHuffman() { // HLIT[5], HDIST[5], HCLEN[4]. for f.nb < 5+5+4 { if f.moreBits(); f.err { return } } nlit := int(f.b&0x1F) + 257 f.b >>= 5 ndist := int(f.b&0x1F) + 1 f.b >>= 5 nclen := int(f.b&0xF) + 4 f.b >>= 4 f.nb -= 5 + 5 + 4 // (HCLEN+4)*3 bits: code lengths in the magic codeOrder order. for i := 0; i < nclen; i++ { for f.nb < 3 { if f.moreBits(); f.err { return } } f.codebits[codeOrder[i]] = int(f.b & 0x7) f.b >>= 3 f.nb -= 3 } for i := nclen; i < len(codeOrder); i++ { f.codebits[codeOrder[i]] = 0 } if !f.h1.init(f.codebits[0:]) { f.err = true return } // HLIT + 257 code lengths, HDIST + 1 code lengths, // using the code length Huffman code. for i, n := 0, nlit+ndist; i < n; { x := f.huffSym(&f.h1) if f.err { return } if x < 16 { // Actual length. f.bits[i] = x i++ continue } // Repeat previous length or zero. var rep int var nb uint var b int switch x { default: f.err = true return case 16: rep = 3 nb = 2 if i == 0 { f.err = true return } b = f.bits[i-1] case 17: rep = 3 nb = 3 b = 0 case 18: rep = 11 nb = 7 b = 0 } for f.nb < nb { if f.moreBits(); f.err { return } } rep += int(f.b & uint32(1<>= nb f.nb -= nb if i+rep > n { f.err = true return } for j := 0; j < rep; j++ { f.bits[i] = b i++ } } if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) { f.err = true return } } // Decode a single Huffman block from f. // hl and hd are the Huffman states for the lit/length values // and the distance values, respectively. If hd == nil, using the // fixed distance encoding associated with fixed Huffman blocks. func (f *decompressor) huffmanBlock(hl, hd *huffmanDecoder) { for { v := f.huffSym(hl) if f.err { return } var n uint // number of bits extra var length int switch { case v < 256: f.out = append(f.out, byte(v)) continue case v == 256: // Done with huffman block; read next block. return // otherwise, reference to older data case v < 265: length = v - (257 - 3) n = 0 case v < 269: length = v*2 - (265*2 - 11) n = 1 case v < 273: length = v*4 - (269*4 - 19) n = 2 case v < 277: length = v*8 - (273*8 - 35) n = 3 case v < 281: length = v*16 - (277*16 - 67) n = 4 case v < 285: length = v*32 - (281*32 - 131) n = 5 default: length = 258 n = 0 } if n > 0 { for f.nb < n { if f.moreBits(); f.err { return } } length += int(f.b & uint32(1<>= n f.nb -= n } var dist int if hd == nil { for f.nb < 5 { if f.moreBits(); f.err { return } } dist = int(reverseByte[(f.b&0x1F)<<3]) f.b >>= 5 f.nb -= 5 } else { if dist = f.huffSym(hd); f.err { return } } switch { case dist < 4: dist++ case dist >= 30: f.err = true return default: nb := uint(dist-2) >> 1 // have 1 bit in bottom of dist, need nb more. extra := (dist & 1) << nb for f.nb < nb { if f.moreBits(); f.err { return } } extra |= int(f.b & uint32(1<>= nb f.nb -= nb dist = 1<<(nb+1) + 1 + extra } // Copy [-dist:-dist+length] into output. // Encoding can be prescient, so no check on length. if dist > len(f.out) { f.err = true return } p := len(f.out) - dist for i := 0; i < length; i++ { f.out = append(f.out, f.out[p]) p++ } } } // Copy a single uncompressed data block from input to output. func (f *decompressor) dataBlock() { // Uncompressed. // Discard current half-byte. f.nb = 0 f.b = 0 if len(f.in) < 4 { f.err = true return } buf := f.in[:4] f.in = f.in[4:] n := int(buf[0]) | int(buf[1])<<8 nn := int(buf[2]) | int(buf[3])<<8 if uint16(nn) != uint16(^n) { f.err = true return } if len(f.in) < n { f.err = true return } f.out = append(f.out, f.in[:n]...) f.in = f.in[n:] } func (f *decompressor) moreBits() { if len(f.in) == 0 { f.err = true return } c := f.in[0] f.in = f.in[1:] f.b |= uint32(c) << f.nb f.nb += 8 } // Read the next Huffman-encoded symbol from f according to h. func (f *decompressor) huffSym(h *huffmanDecoder) int { for n := uint(h.min); n <= uint(h.max); n++ { lim := h.limit[n] if lim == -1 { continue } for f.nb < n { if f.moreBits(); f.err { return 0 } } v := int(f.b & uint32(1<>8]) | int(reverseByte[v&0xFF])<<8 // reverse bits if v <= lim { f.b >>= n f.nb -= n return h.codes[v-h.base[n]] } } f.err = true return 0 } var reverseByte = [256]byte{ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, } // Hard-coded Huffman tables for DEFLATE algorithm. // See RFC 1951, section 3.2.6. var fixedHuffmanDecoder = huffmanDecoder{ 7, 9, [maxCodeLen + 1]int{7: 23, 199, 511}, [maxCodeLen + 1]int{7: 0, 24, 224}, []int{ // length 7: 256-279 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, // length 8: 0-143 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, // length 8: 280-287 280, 281, 282, 283, 284, 285, 286, 287, // length 9: 144-255 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, }, } // Huffman decoder is based on // J. Brian Connell, ``A Huffman-Shannon-Fano Code,'' // Proceedings of the IEEE, 61(7) (July 1973), pp 1046-1047. type huffmanDecoder struct { // min, max code length min, max int // limit[i] = largest code word of length i // Given code v of length n, // need more bits if v > limit[n]. limit [maxCodeLen + 1]int // base[i] = smallest code word of length i - seq number base [maxCodeLen + 1]int // codes[seq number] = output code. // Given code v of length n, value is // codes[v - base[n]]. codes []int } // Initialize Huffman decoding tables from array of code lengths. func (h *huffmanDecoder) init(bits []int) bool { // Count number of codes of each length, // compute min and max length. var count [maxCodeLen + 1]int var min, max int for _, n := range bits { if n == 0 { continue } if min == 0 || n < min { min = n } if n > max { max = n } count[n]++ } if max == 0 { return false } h.min = min h.max = max // For each code range, compute // nextcode (first code of that length), // limit (last code of that length), and // base (offset from first code to sequence number). code := 0 seq := 0 var nextcode [maxCodeLen]int for i := min; i <= max; i++ { n := count[i] nextcode[i] = code h.base[i] = code - seq code += n seq += n h.limit[i] = code - 1 code <<= 1 } // Make array mapping sequence numbers to codes. if len(h.codes) < len(bits) { h.codes = make([]int, len(bits)) } for i, n := range bits { if n == 0 { continue } code := nextcode[n] nextcode[n]++ seq := code - h.base[n] h.codes[seq] = i } return true } func inflate(in string) (out []byte) { var d decompressor d.in = in for !d.err && !d.eof { d.nextBlock() } if len(d.in) != 0 { println("fs unzip: junk at end of compressed data") return nil } return d.out } // get4 returns the little-endian 32-bit value in b. func zget4(b string) int { if len(b) < 4 { return 0 } return int(b[0]) | int(b[1])<<8 | int(b[2])<<16 | int(b[3])<<24 } // get2 returns the little-endian 16-bit value in b. func zget2(b string) int { if len(b) < 2 { return 0 } return int(b[0]) | int(b[1])<<8 } func unzip(data string) { const ( zecheader = 0x06054b50 zcheader = 0x02014b50 ztailsize = 22 zheadersize = 30 zheader = 0x04034b50 ) buf := data[len(data)-ztailsize:] n := zget2(buf[10:]) size := zget4(buf[12:]) off := zget4(buf[16:]) hdr := data[off : off+size] for i := 0; i < n; i++ { // zip entry layout: // 0 magic[4] // 4 madevers[1] // 5 madeos[1] // 6 extvers[1] // 7 extos[1] // 8 flags[2] // 10 meth[2] // 12 modtime[2] // 14 moddate[2] // 16 crc[4] // 20 csize[4] // 24 uncsize[4] // 28 namelen[2] // 30 xlen[2] // 32 fclen[2] // 34 disknum[2] // 36 iattr[2] // 38 eattr[4] // 42 off[4] // 46 name[namelen] // 46+namelen+xlen+fclen - next header // if zget4(hdr) != zcheader { println("fs unzip: bad magic") break } meth := zget2(hdr[10:]) mtime := zget2(hdr[12:]) mdate := zget2(hdr[14:]) csize := zget4(hdr[20:]) size := zget4(hdr[24:]) namelen := zget2(hdr[28:]) xlen := zget2(hdr[30:]) fclen := zget2(hdr[32:]) xattr := uint32(zget4(hdr[38:])) >> 16 off := zget4(hdr[42:]) name := hdr[46 : 46+namelen] hdr = hdr[46+namelen+xlen+fclen:] // zip per-file header layout: // 0 magic[4] // 4 extvers[1] // 5 extos[1] // 6 flags[2] // 8 meth[2] // 10 modtime[2] // 12 moddate[2] // 14 crc[4] // 18 csize[4] // 22 uncsize[4] // 26 namelen[2] // 28 xlen[2] // 30 name[namelen] // 30+namelen+xlen - file data // buf := data[off : off+zheadersize+namelen] if zget4(buf) != zheader || zget2(buf[8:]) != meth || zget2(buf[26:]) != namelen || buf[30:30+namelen] != name { println("fs unzip: inconsistent zip file") return } xlen = zget2(buf[28:]) off += zheadersize + namelen + xlen var fdata []byte switch meth { case 0: // buf is uncompressed buf = data[off : off+size] fdata = []byte(buf) case 8: // buf is deflate-compressed buf = data[off : off+csize] fdata = inflate(buf) if len(fdata) != size { println("fs unzip: inconsistent size in zip file") return } } if xattr&S_IFMT == 0 { if xattr&0777 == 0 { xattr |= 0666 } if len(name) > 0 && name[len(name)-1] == '/' { xattr |= S_IFDIR xattr |= 0111 } else { xattr |= S_IFREG } } if err := create(name, xattr, zipToTime(mdate, mtime), fdata); err != nil { print("fs unzip: create ", name, ": ", err.Error(), "\n") } } chdirEnv() } func zipToTime(date, time int) int64 { dd := date & 0x1f mm := date >> 5 & 0xf yy := date >> 9 // since 1980 sec := int64(315532800) // jan 1 1980 sec += int64(yy) * 365 * 86400 sec += int64(yy) / 4 * 86400 if yy%4 > 0 || mm >= 3 { sec += 86400 } sec += int64(daysBeforeMonth[mm]) * 86400 sec += int64(dd-1) * 86400 h := time >> 11 m := time >> 5 & 0x3F s := time & 0x1f * 2 sec += int64(h*3600 + m*60 + s) return sec } var daysBeforeMonth = [...]int32{ 0, 0, 31, 31 + 28, 31 + 28 + 31, 31 + 28 + 31 + 30, 31 + 28 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30, 31 + 28 + 31 + 30 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31, }