Home | History | Annotate | Download | only in syscall
      1 // Copyright 2009 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 // Small in-memory unzip implementation.
      6 // A simplified copy of the pre-Go 1 compress/flate/inflate.go
      7 // and a modified copy of the zip reader in package time.
      8 // (The one in package time does not support decompression; this one does.)
      9 
     10 package syscall
     11 
     12 const (
     13 	maxCodeLen = 16    // max length of Huffman code
     14 	maxHist    = 32768 // max history required
     15 	maxLit     = 286
     16 	maxDist    = 32
     17 	numCodes   = 19 // number of codes in Huffman meta-code
     18 )
     19 
     20 type decompressor struct {
     21 	in  string // compressed input
     22 	out []byte // uncompressed output
     23 	b   uint32 // input bits, at top of b
     24 	nb  uint
     25 	err bool // invalid input
     26 	eof bool // reached EOF
     27 
     28 	h1, h2   huffmanDecoder        // decoders for literal/length, distance
     29 	bits     [maxLit + maxDist]int // lengths defining Huffman codes
     30 	codebits [numCodes]int
     31 }
     32 
     33 func (f *decompressor) nextBlock() {
     34 	for f.nb < 1+2 {
     35 		if f.moreBits(); f.err {
     36 			return
     37 		}
     38 	}
     39 	f.eof = f.b&1 == 1
     40 	f.b >>= 1
     41 	typ := f.b & 3
     42 	f.b >>= 2
     43 	f.nb -= 1 + 2
     44 	switch typ {
     45 	case 0:
     46 		f.dataBlock()
     47 	case 1:
     48 		// compressed, fixed Huffman tables
     49 		f.huffmanBlock(&fixedHuffmanDecoder, nil)
     50 	case 2:
     51 		// compressed, dynamic Huffman tables
     52 		if f.readHuffman(); f.err {
     53 			break
     54 		}
     55 		f.huffmanBlock(&f.h1, &f.h2)
     56 	default:
     57 		// 3 is reserved.
     58 		f.err = true
     59 	}
     60 }
     61 
     62 // RFC 1951 section 3.2.7.
     63 // Compression with dynamic Huffman codes
     64 
     65 var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
     66 
     67 func (f *decompressor) readHuffman() {
     68 	// HLIT[5], HDIST[5], HCLEN[4].
     69 	for f.nb < 5+5+4 {
     70 		if f.moreBits(); f.err {
     71 			return
     72 		}
     73 	}
     74 	nlit := int(f.b&0x1F) + 257
     75 	f.b >>= 5
     76 	ndist := int(f.b&0x1F) + 1
     77 	f.b >>= 5
     78 	nclen := int(f.b&0xF) + 4
     79 	f.b >>= 4
     80 	f.nb -= 5 + 5 + 4
     81 
     82 	// (HCLEN+4)*3 bits: code lengths in the magic codeOrder order.
     83 	for i := 0; i < nclen; i++ {
     84 		for f.nb < 3 {
     85 			if f.moreBits(); f.err {
     86 				return
     87 			}
     88 		}
     89 		f.codebits[codeOrder[i]] = int(f.b & 0x7)
     90 		f.b >>= 3
     91 		f.nb -= 3
     92 	}
     93 	for i := nclen; i < len(codeOrder); i++ {
     94 		f.codebits[codeOrder[i]] = 0
     95 	}
     96 	if !f.h1.init(f.codebits[0:]) {
     97 		f.err = true
     98 		return
     99 	}
    100 
    101 	// HLIT + 257 code lengths, HDIST + 1 code lengths,
    102 	// using the code length Huffman code.
    103 	for i, n := 0, nlit+ndist; i < n; {
    104 		x := f.huffSym(&f.h1)
    105 		if f.err {
    106 			return
    107 		}
    108 		if x < 16 {
    109 			// Actual length.
    110 			f.bits[i] = x
    111 			i++
    112 			continue
    113 		}
    114 		// Repeat previous length or zero.
    115 		var rep int
    116 		var nb uint
    117 		var b int
    118 		switch x {
    119 		default:
    120 			f.err = true
    121 			return
    122 		case 16:
    123 			rep = 3
    124 			nb = 2
    125 			if i == 0 {
    126 				f.err = true
    127 				return
    128 			}
    129 			b = f.bits[i-1]
    130 		case 17:
    131 			rep = 3
    132 			nb = 3
    133 			b = 0
    134 		case 18:
    135 			rep = 11
    136 			nb = 7
    137 			b = 0
    138 		}
    139 		for f.nb < nb {
    140 			if f.moreBits(); f.err {
    141 				return
    142 			}
    143 		}
    144 		rep += int(f.b & uint32(1<<nb-1))
    145 		f.b >>= nb
    146 		f.nb -= nb
    147 		if i+rep > n {
    148 			f.err = true
    149 			return
    150 		}
    151 		for j := 0; j < rep; j++ {
    152 			f.bits[i] = b
    153 			i++
    154 		}
    155 	}
    156 
    157 	if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) {
    158 		f.err = true
    159 		return
    160 	}
    161 }
    162 
    163 // Decode a single Huffman block from f.
    164 // hl and hd are the Huffman states for the lit/length values
    165 // and the distance values, respectively. If hd == nil, using the
    166 // fixed distance encoding associated with fixed Huffman blocks.
    167 func (f *decompressor) huffmanBlock(hl, hd *huffmanDecoder) {
    168 	for {
    169 		v := f.huffSym(hl)
    170 		if f.err {
    171 			return
    172 		}
    173 		var n uint // number of bits extra
    174 		var length int
    175 		switch {
    176 		case v < 256:
    177 			f.out = append(f.out, byte(v))
    178 			continue
    179 		case v == 256:
    180 			// Done with huffman block; read next block.
    181 			return
    182 		// otherwise, reference to older data
    183 		case v < 265:
    184 			length = v - (257 - 3)
    185 			n = 0
    186 		case v < 269:
    187 			length = v*2 - (265*2 - 11)
    188 			n = 1
    189 		case v < 273:
    190 			length = v*4 - (269*4 - 19)
    191 			n = 2
    192 		case v < 277:
    193 			length = v*8 - (273*8 - 35)
    194 			n = 3
    195 		case v < 281:
    196 			length = v*16 - (277*16 - 67)
    197 			n = 4
    198 		case v < 285:
    199 			length = v*32 - (281*32 - 131)
    200 			n = 5
    201 		default:
    202 			length = 258
    203 			n = 0
    204 		}
    205 		if n > 0 {
    206 			for f.nb < n {
    207 				if f.moreBits(); f.err {
    208 					return
    209 				}
    210 			}
    211 			length += int(f.b & uint32(1<<n-1))
    212 			f.b >>= n
    213 			f.nb -= n
    214 		}
    215 
    216 		var dist int
    217 		if hd == nil {
    218 			for f.nb < 5 {
    219 				if f.moreBits(); f.err {
    220 					return
    221 				}
    222 			}
    223 			dist = int(reverseByte[(f.b&0x1F)<<3])
    224 			f.b >>= 5
    225 			f.nb -= 5
    226 		} else {
    227 			if dist = f.huffSym(hd); f.err {
    228 				return
    229 			}
    230 		}
    231 
    232 		switch {
    233 		case dist < 4:
    234 			dist++
    235 		case dist >= 30:
    236 			f.err = true
    237 			return
    238 		default:
    239 			nb := uint(dist-2) >> 1
    240 			// have 1 bit in bottom of dist, need nb more.
    241 			extra := (dist & 1) << nb
    242 			for f.nb < nb {
    243 				if f.moreBits(); f.err {
    244 					return
    245 				}
    246 			}
    247 			extra |= int(f.b & uint32(1<<nb-1))
    248 			f.b >>= nb
    249 			f.nb -= nb
    250 			dist = 1<<(nb+1) + 1 + extra
    251 		}
    252 
    253 		// Copy [-dist:-dist+length] into output.
    254 		// Encoding can be prescient, so no check on length.
    255 		if dist > len(f.out) {
    256 			f.err = true
    257 			return
    258 		}
    259 
    260 		p := len(f.out) - dist
    261 		for i := 0; i < length; i++ {
    262 			f.out = append(f.out, f.out[p])
    263 			p++
    264 		}
    265 	}
    266 }
    267 
    268 // Copy a single uncompressed data block from input to output.
    269 func (f *decompressor) dataBlock() {
    270 	// Uncompressed.
    271 	// Discard current half-byte.
    272 	f.nb = 0
    273 	f.b = 0
    274 
    275 	if len(f.in) < 4 {
    276 		f.err = true
    277 		return
    278 	}
    279 
    280 	buf := f.in[:4]
    281 	f.in = f.in[4:]
    282 	n := int(buf[0]) | int(buf[1])<<8
    283 	nn := int(buf[2]) | int(buf[3])<<8
    284 	if uint16(nn) != uint16(^n) {
    285 		f.err = true
    286 		return
    287 	}
    288 
    289 	if len(f.in) < n {
    290 		f.err = true
    291 		return
    292 	}
    293 	f.out = append(f.out, f.in[:n]...)
    294 	f.in = f.in[n:]
    295 }
    296 
    297 func (f *decompressor) moreBits() {
    298 	if len(f.in) == 0 {
    299 		f.err = true
    300 		return
    301 	}
    302 	c := f.in[0]
    303 	f.in = f.in[1:]
    304 	f.b |= uint32(c) << f.nb
    305 	f.nb += 8
    306 }
    307 
    308 // Read the next Huffman-encoded symbol from f according to h.
    309 func (f *decompressor) huffSym(h *huffmanDecoder) int {
    310 	for n := uint(h.min); n <= uint(h.max); n++ {
    311 		lim := h.limit[n]
    312 		if lim == -1 {
    313 			continue
    314 		}
    315 		for f.nb < n {
    316 			if f.moreBits(); f.err {
    317 				return 0
    318 			}
    319 		}
    320 		v := int(f.b & uint32(1<<n-1))
    321 		v <<= 16 - n
    322 		v = int(reverseByte[v>>8]) | int(reverseByte[v&0xFF])<<8 // reverse bits
    323 		if v <= lim {
    324 			f.b >>= n
    325 			f.nb -= n
    326 			return h.codes[v-h.base[n]]
    327 		}
    328 	}
    329 	f.err = true
    330 	return 0
    331 }
    332 
    333 var reverseByte = [256]byte{
    334 	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
    335 	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
    336 	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
    337 	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
    338 	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
    339 	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
    340 	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
    341 	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
    342 	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
    343 	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
    344 	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
    345 	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
    346 	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
    347 	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
    348 	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
    349 	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
    350 	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
    351 	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
    352 	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
    353 	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
    354 	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
    355 	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
    356 	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
    357 	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
    358 	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
    359 	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
    360 	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
    361 	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
    362 	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
    363 	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
    364 	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
    365 	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
    366 }
    367 
    368 // Hard-coded Huffman tables for DEFLATE algorithm.
    369 // See RFC 1951, section 3.2.6.
    370 var fixedHuffmanDecoder = huffmanDecoder{
    371 	7, 9,
    372 	[maxCodeLen + 1]int{7: 23, 199, 511},
    373 	[maxCodeLen + 1]int{7: 0, 24, 224},
    374 	[]int{
    375 		// length 7: 256-279
    376 		256, 257, 258, 259, 260, 261, 262,
    377 		263, 264, 265, 266, 267, 268, 269,
    378 		270, 271, 272, 273, 274, 275, 276,
    379 		277, 278, 279,
    380 
    381 		// length 8: 0-143
    382 		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
    383 		12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
    384 		22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    385 		32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
    386 		42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
    387 		52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
    388 		62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
    389 		72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
    390 		82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
    391 		92, 93, 94, 95, 96, 97, 98, 99, 100,
    392 		101, 102, 103, 104, 105, 106, 107, 108,
    393 		109, 110, 111, 112, 113, 114, 115, 116,
    394 		117, 118, 119, 120, 121, 122, 123, 124,
    395 		125, 126, 127, 128, 129, 130, 131, 132,
    396 		133, 134, 135, 136, 137, 138, 139, 140,
    397 		141, 142, 143,
    398 
    399 		// length 8: 280-287
    400 		280, 281, 282, 283, 284, 285, 286, 287,
    401 
    402 		// length 9: 144-255
    403 		144, 145, 146, 147, 148, 149, 150, 151,
    404 		152, 153, 154, 155, 156, 157, 158, 159,
    405 		160, 161, 162, 163, 164, 165, 166, 167,
    406 		168, 169, 170, 171, 172, 173, 174, 175,
    407 		176, 177, 178, 179, 180, 181, 182, 183,
    408 		184, 185, 186, 187, 188, 189, 190, 191,
    409 		192, 193, 194, 195, 196, 197, 198, 199,
    410 		200, 201, 202, 203, 204, 205, 206, 207,
    411 		208, 209, 210, 211, 212, 213, 214, 215,
    412 		216, 217, 218, 219, 220, 221, 222, 223,
    413 		224, 225, 226, 227, 228, 229, 230, 231,
    414 		232, 233, 234, 235, 236, 237, 238, 239,
    415 		240, 241, 242, 243, 244, 245, 246, 247,
    416 		248, 249, 250, 251, 252, 253, 254, 255,
    417 	},
    418 }
    419 
    420 // Huffman decoder is based on
    421 // J. Brian Connell, ``A Huffman-Shannon-Fano Code,''
    422 // Proceedings of the IEEE, 61(7) (July 1973), pp 1046-1047.
    423 type huffmanDecoder struct {
    424 	// min, max code length
    425 	min, max int
    426 
    427 	// limit[i] = largest code word of length i
    428 	// Given code v of length n,
    429 	// need more bits if v > limit[n].
    430 	limit [maxCodeLen + 1]int
    431 
    432 	// base[i] = smallest code word of length i - seq number
    433 	base [maxCodeLen + 1]int
    434 
    435 	// codes[seq number] = output code.
    436 	// Given code v of length n, value is
    437 	// codes[v - base[n]].
    438 	codes []int
    439 }
    440 
    441 // Initialize Huffman decoding tables from array of code lengths.
    442 func (h *huffmanDecoder) init(bits []int) bool {
    443 	// Count number of codes of each length,
    444 	// compute min and max length.
    445 	var count [maxCodeLen + 1]int
    446 	var min, max int
    447 	for _, n := range bits {
    448 		if n == 0 {
    449 			continue
    450 		}
    451 		if min == 0 || n < min {
    452 			min = n
    453 		}
    454 		if n > max {
    455 			max = n
    456 		}
    457 		count[n]++
    458 	}
    459 	if max == 0 {
    460 		return false
    461 	}
    462 
    463 	h.min = min
    464 	h.max = max
    465 
    466 	// For each code range, compute
    467 	// nextcode (first code of that length),
    468 	// limit (last code of that length), and
    469 	// base (offset from first code to sequence number).
    470 	code := 0
    471 	seq := 0
    472 	var nextcode [maxCodeLen]int
    473 	for i := min; i <= max; i++ {
    474 		n := count[i]
    475 		nextcode[i] = code
    476 		h.base[i] = code - seq
    477 		code += n
    478 		seq += n
    479 		h.limit[i] = code - 1
    480 		code <<= 1
    481 	}
    482 
    483 	// Make array mapping sequence numbers to codes.
    484 	if len(h.codes) < len(bits) {
    485 		h.codes = make([]int, len(bits))
    486 	}
    487 	for i, n := range bits {
    488 		if n == 0 {
    489 			continue
    490 		}
    491 		code := nextcode[n]
    492 		nextcode[n]++
    493 		seq := code - h.base[n]
    494 		h.codes[seq] = i
    495 	}
    496 	return true
    497 }
    498 
    499 func inflate(in string) (out []byte) {
    500 	var d decompressor
    501 	d.in = in
    502 	for !d.err && !d.eof {
    503 		d.nextBlock()
    504 	}
    505 	if len(d.in) != 0 {
    506 		println("fs unzip: junk at end of compressed data")
    507 		return nil
    508 	}
    509 	return d.out
    510 }
    511 
    512 // get4 returns the little-endian 32-bit value in b.
    513 func zget4(b string) int {
    514 	if len(b) < 4 {
    515 		return 0
    516 	}
    517 	return int(b[0]) | int(b[1])<<8 | int(b[2])<<16 | int(b[3])<<24
    518 }
    519 
    520 // get2 returns the little-endian 16-bit value in b.
    521 func zget2(b string) int {
    522 	if len(b) < 2 {
    523 		return 0
    524 	}
    525 	return int(b[0]) | int(b[1])<<8
    526 }
    527 
    528 func unzip(data string) {
    529 	const (
    530 		zecheader   = 0x06054b50
    531 		zcheader    = 0x02014b50
    532 		ztailsize   = 22
    533 		zheadersize = 30
    534 		zheader     = 0x04034b50
    535 	)
    536 
    537 	buf := data[len(data)-ztailsize:]
    538 	n := zget2(buf[10:])
    539 	size := zget4(buf[12:])
    540 	off := zget4(buf[16:])
    541 
    542 	hdr := data[off : off+size]
    543 	for i := 0; i < n; i++ {
    544 		// zip entry layout:
    545 		//	0	magic[4]
    546 		//	4	madevers[1]
    547 		//	5	madeos[1]
    548 		//	6	extvers[1]
    549 		//	7	extos[1]
    550 		//	8	flags[2]
    551 		//	10	meth[2]
    552 		//	12	modtime[2]
    553 		//	14	moddate[2]
    554 		//	16	crc[4]
    555 		//	20	csize[4]
    556 		//	24	uncsize[4]
    557 		//	28	namelen[2]
    558 		//	30	xlen[2]
    559 		//	32	fclen[2]
    560 		//	34	disknum[2]
    561 		//	36	iattr[2]
    562 		//	38	eattr[4]
    563 		//	42	off[4]
    564 		//	46	name[namelen]
    565 		//	46+namelen+xlen+fclen - next header
    566 		//
    567 		if zget4(hdr) != zcheader {
    568 			println("fs unzip: bad magic")
    569 			break
    570 		}
    571 		meth := zget2(hdr[10:])
    572 		mtime := zget2(hdr[12:])
    573 		mdate := zget2(hdr[14:])
    574 		csize := zget4(hdr[20:])
    575 		size := zget4(hdr[24:])
    576 		namelen := zget2(hdr[28:])
    577 		xlen := zget2(hdr[30:])
    578 		fclen := zget2(hdr[32:])
    579 		xattr := uint32(zget4(hdr[38:])) >> 16
    580 		off := zget4(hdr[42:])
    581 		name := hdr[46 : 46+namelen]
    582 		hdr = hdr[46+namelen+xlen+fclen:]
    583 
    584 		// zip per-file header layout:
    585 		//	0	magic[4]
    586 		//	4	extvers[1]
    587 		//	5	extos[1]
    588 		//	6	flags[2]
    589 		//	8	meth[2]
    590 		//	10	modtime[2]
    591 		//	12	moddate[2]
    592 		//	14	crc[4]
    593 		//	18	csize[4]
    594 		//	22	uncsize[4]
    595 		//	26	namelen[2]
    596 		//	28	xlen[2]
    597 		//	30	name[namelen]
    598 		//	30+namelen+xlen - file data
    599 		//
    600 		buf := data[off : off+zheadersize+namelen]
    601 		if zget4(buf) != zheader ||
    602 			zget2(buf[8:]) != meth ||
    603 			zget2(buf[26:]) != namelen ||
    604 			buf[30:30+namelen] != name {
    605 			println("fs unzip: inconsistent zip file")
    606 			return
    607 		}
    608 		xlen = zget2(buf[28:])
    609 
    610 		off += zheadersize + namelen + xlen
    611 
    612 		var fdata []byte
    613 		switch meth {
    614 		case 0:
    615 			// buf is uncompressed
    616 			buf = data[off : off+size]
    617 			fdata = []byte(buf)
    618 		case 8:
    619 			// buf is deflate-compressed
    620 			buf = data[off : off+csize]
    621 			fdata = inflate(buf)
    622 			if len(fdata) != size {
    623 				println("fs unzip: inconsistent size in zip file")
    624 				return
    625 			}
    626 		}
    627 
    628 		if xattr&S_IFMT == 0 {
    629 			if xattr&0777 == 0 {
    630 				xattr |= 0666
    631 			}
    632 			if len(name) > 0 && name[len(name)-1] == '/' {
    633 				xattr |= S_IFDIR
    634 				xattr |= 0111
    635 			} else {
    636 				xattr |= S_IFREG
    637 			}
    638 		}
    639 
    640 		if err := create(name, xattr, zipToTime(mdate, mtime), fdata); err != nil {
    641 			print("fs unzip: create ", name, ": ", err.Error(), "\n")
    642 		}
    643 	}
    644 
    645 	chdirEnv()
    646 }
    647 
    648 func zipToTime(date, time int) int64 {
    649 	dd := date & 0x1f
    650 	mm := date >> 5 & 0xf
    651 	yy := date >> 9 // since 1980
    652 
    653 	sec := int64(315532800) // jan 1 1980
    654 	sec += int64(yy) * 365 * 86400
    655 	sec += int64(yy) / 4 * 86400
    656 	if yy%4 > 0 || mm >= 3 {
    657 		sec += 86400
    658 	}
    659 	sec += int64(daysBeforeMonth[mm]) * 86400
    660 	sec += int64(dd-1) * 86400
    661 
    662 	h := time >> 11
    663 	m := time >> 5 & 0x3F
    664 	s := time & 0x1f * 2
    665 	sec += int64(h*3600 + m*60 + s)
    666 
    667 	return sec
    668 }
    669 
    670 var daysBeforeMonth = [...]int32{
    671 	0,
    672 	0,
    673 	31,
    674 	31 + 28,
    675 	31 + 28 + 31,
    676 	31 + 28 + 31 + 30,
    677 	31 + 28 + 31 + 30 + 31,
    678 	31 + 28 + 31 + 30 + 31 + 30,
    679 	31 + 28 + 31 + 30 + 31 + 30 + 31,
    680 	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
    681 	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
    682 	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
    683 	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
    684 	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
    685 }
    686