...
Run Format

Source file src/syscall/unzip_nacl.go

Documentation: 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  

View as plain text