...

Source file src/github.com/xi2/xz/dec_stream.go

Documentation: github.com/xi2/xz

     1  /*
     2   * .xz Stream decoder
     3   *
     4   * Author: Lasse Collin <lasse.collin@tukaani.org>
     5   *
     6   * Translation to Go: Michael Cross <https://github.com/xi2>
     7   *
     8   * This file has been put into the public domain.
     9   * You can do whatever you want with this file.
    10   */
    11  
    12  package xz
    13  
    14  import (
    15  	"bytes"
    16  	"crypto/sha256"
    17  	"hash"
    18  	"hash/crc32"
    19  	"hash/crc64"
    20  )
    21  
    22  /* from linux/lib/xz/xz_stream.h **************************************/
    23  
    24  /*
    25   * See the .xz file format specification at
    26   * http://tukaani.org/xz/xz-file-format.txt
    27   * to understand the container format.
    28   */
    29  const (
    30  	streamHeaderSize = 12
    31  	headerMagic      = "\xfd7zXZ\x00"
    32  	footerMagic      = "YZ"
    33  )
    34  
    35  /*
    36   * Variable-length integer can hold a 63-bit unsigned integer or a special
    37   * value indicating that the value is unknown.
    38   */
    39  type vliType uint64
    40  
    41  const (
    42  	vliUnknown vliType = ^vliType(0)
    43  	/* Maximum encoded size of a VLI */
    44  	vliBytesMax = 8 * 8 / 7 // (Sizeof(vliType) * 8 / 7)
    45  )
    46  
    47  /* from linux/lib/xz/xz_dec_stream.c **********************************/
    48  
    49  /* Hash used to validate the Index field */
    50  type xzDecHash struct {
    51  	unpadded     vliType
    52  	uncompressed vliType
    53  	sha256       hash.Hash
    54  }
    55  
    56  // type of xzDec.sequence
    57  type xzDecSeq int
    58  
    59  const (
    60  	seqStreamHeader xzDecSeq = iota
    61  	seqBlockStart
    62  	seqBlockHeader
    63  	seqBlockUncompress
    64  	seqBlockPadding
    65  	seqBlockCheck
    66  	seqIndex
    67  	seqIndexPadding
    68  	seqIndexCRC32
    69  	seqStreamFooter
    70  )
    71  
    72  // type of xzDec.index.sequence
    73  type xzDecIndexSeq int
    74  
    75  const (
    76  	seqIndexCount xzDecIndexSeq = iota
    77  	seqIndexUnpadded
    78  	seqIndexUncompressed
    79  )
    80  
    81  /**
    82   * xzDec - Opaque type to hold the XZ decoder state
    83   */
    84  type xzDec struct {
    85  	/* Position in decMain */
    86  	sequence xzDecSeq
    87  	/* Position in variable-length integers and Check fields */
    88  	pos int
    89  	/* Variable-length integer decoded by decVLI */
    90  	vli vliType
    91  	/* Saved inPos and outPos */
    92  	inStart  int
    93  	outStart int
    94  	/* CRC32 checksum hash used in Index */
    95  	crc32 hash.Hash
    96  	/* Hashes used in Blocks */
    97  	checkCRC32  hash.Hash
    98  	checkCRC64  hash.Hash
    99  	checkSHA256 hash.Hash
   100  	/* for checkTypes CRC32/CRC64/SHA256, check is one of the above 3 hashes */
   101  	check hash.Hash
   102  	/* Embedded stream header struct containing CheckType */
   103  	*Header
   104  	/*
   105  	 * True if the next call to xzDecRun is allowed to return
   106  	 * xzBufError.
   107  	 */
   108  	allowBufError bool
   109  	/* Information stored in Block Header */
   110  	blockHeader struct {
   111  		/*
   112  		 * Value stored in the Compressed Size field, or
   113  		 * vliUnknown if Compressed Size is not present.
   114  		 */
   115  		compressed vliType
   116  		/*
   117  		 * Value stored in the Uncompressed Size field, or
   118  		 * vliUnknown if Uncompressed Size is not present.
   119  		 */
   120  		uncompressed vliType
   121  		/* Size of the Block Header field */
   122  		size int
   123  	}
   124  	/* Information collected when decoding Blocks */
   125  	block struct {
   126  		/* Observed compressed size of the current Block */
   127  		compressed vliType
   128  		/* Observed uncompressed size of the current Block */
   129  		uncompressed vliType
   130  		/* Number of Blocks decoded so far */
   131  		count vliType
   132  		/*
   133  		 * Hash calculated from the Block sizes. This is used to
   134  		 * validate the Index field.
   135  		 */
   136  		hash xzDecHash
   137  	}
   138  	/* Variables needed when verifying the Index field */
   139  	index struct {
   140  		/* Position in decIndex */
   141  		sequence xzDecIndexSeq
   142  		/* Size of the Index in bytes */
   143  		size vliType
   144  		/* Number of Records (matches block.count in valid files) */
   145  		count vliType
   146  		/*
   147  		 * Hash calculated from the Records (matches block.hash in
   148  		 * valid files).
   149  		 */
   150  		hash xzDecHash
   151  	}
   152  	/*
   153  	 * Temporary buffer needed to hold Stream Header, Block Header,
   154  	 * and Stream Footer. The Block Header is the biggest (1 KiB)
   155  	 * so we reserve space according to that. bufArray has to be aligned
   156  	 * to a multiple of four bytes; the variables before it
   157  	 * should guarantee this.
   158  	 */
   159  	temp struct {
   160  		pos      int
   161  		buf      []byte // slice buf will be backed by bufArray
   162  		bufArray [1024]byte
   163  	}
   164  	// chain is the function (or to be more precise, closure) which
   165  	// does the decompression and will call into the lzma2 and other
   166  	// filter code as needed. It is constructed by decBlockHeader
   167  	chain func(b *xzBuf) xzRet
   168  	// lzma2 holds the state of the last filter (which must be LZMA2)
   169  	lzma2 *xzDecLZMA2
   170  	// pointers to allocated BCJ/Delta filters
   171  	bcjs   []*xzDecBCJ
   172  	deltas []*xzDecDelta
   173  	// number of currently in use BCJ/Delta filters from the above
   174  	bcjsUsed   int
   175  	deltasUsed int
   176  }
   177  
   178  /* Sizes of the Check field with different Check IDs */
   179  var checkSizes = [...]byte{
   180  	0,
   181  	4, 4, 4,
   182  	8, 8, 8,
   183  	16, 16, 16,
   184  	32, 32, 32,
   185  	64, 64, 64,
   186  }
   187  
   188  /*
   189   * Fill s.temp by copying data starting from b.in[b.inPos]. Caller
   190   * must have set s.temp.pos to indicate how much data we are supposed
   191   * to copy into s.temp.buf. Return true once s.temp.pos has reached
   192   * len(s.temp.buf).
   193   */
   194  func fillTemp(s *xzDec, b *xzBuf) bool {
   195  	copySize := len(b.in) - b.inPos
   196  	tempRemaining := len(s.temp.buf) - s.temp.pos
   197  	if copySize > tempRemaining {
   198  		copySize = tempRemaining
   199  	}
   200  	copy(s.temp.buf[s.temp.pos:], b.in[b.inPos:])
   201  	b.inPos += copySize
   202  	s.temp.pos += copySize
   203  	if s.temp.pos == len(s.temp.buf) {
   204  		s.temp.pos = 0
   205  		return true
   206  	}
   207  	return false
   208  }
   209  
   210  /* Decode a variable-length integer (little-endian base-128 encoding) */
   211  func decVLI(s *xzDec, in []byte, inPos *int) xzRet {
   212  	var byte byte
   213  	if s.pos == 0 {
   214  		s.vli = 0
   215  	}
   216  	for *inPos < len(in) {
   217  		byte = in[*inPos]
   218  		*inPos++
   219  		s.vli |= vliType(byte&0x7f) << uint(s.pos)
   220  		if byte&0x80 == 0 {
   221  			/* Don't allow non-minimal encodings. */
   222  			if byte == 0 && s.pos != 0 {
   223  				return xzDataError
   224  			}
   225  			s.pos = 0
   226  			return xzStreamEnd
   227  		}
   228  		s.pos += 7
   229  		if s.pos == 7*vliBytesMax {
   230  			return xzDataError
   231  		}
   232  	}
   233  	return xzOK
   234  }
   235  
   236  /*
   237   * Decode the Compressed Data field from a Block. Update and validate
   238   * the observed compressed and uncompressed sizes of the Block so that
   239   * they don't exceed the values possibly stored in the Block Header
   240   * (validation assumes that no integer overflow occurs, since vliType
   241   * is uint64). Update s.check if presence of the CRC32/CRC64/SHA256
   242   * field was indicated in Stream Header.
   243   *
   244   * Once the decoding is finished, validate that the observed sizes match
   245   * the sizes possibly stored in the Block Header. Update the hash and
   246   * Block count, which are later used to validate the Index field.
   247   */
   248  func decBlock(s *xzDec, b *xzBuf) xzRet {
   249  	var ret xzRet
   250  	s.inStart = b.inPos
   251  	s.outStart = b.outPos
   252  	ret = s.chain(b)
   253  	s.block.compressed += vliType(b.inPos - s.inStart)
   254  	s.block.uncompressed += vliType(b.outPos - s.outStart)
   255  	/*
   256  	 * There is no need to separately check for vliUnknown since
   257  	 * the observed sizes are always smaller than vliUnknown.
   258  	 */
   259  	if s.block.compressed > s.blockHeader.compressed ||
   260  		s.block.uncompressed > s.blockHeader.uncompressed {
   261  		return xzDataError
   262  	}
   263  	switch s.CheckType {
   264  	case CheckCRC32, CheckCRC64, CheckSHA256:
   265  		_, _ = s.check.Write(b.out[s.outStart:b.outPos])
   266  	}
   267  	if ret == xzStreamEnd {
   268  		if s.blockHeader.compressed != vliUnknown &&
   269  			s.blockHeader.compressed != s.block.compressed {
   270  			return xzDataError
   271  		}
   272  		if s.blockHeader.uncompressed != vliUnknown &&
   273  			s.blockHeader.uncompressed != s.block.uncompressed {
   274  			return xzDataError
   275  		}
   276  		s.block.hash.unpadded +=
   277  			vliType(s.blockHeader.size) + s.block.compressed
   278  		s.block.hash.unpadded += vliType(checkSizes[s.CheckType])
   279  		s.block.hash.uncompressed += s.block.uncompressed
   280  		var buf [2 * 8]byte // 2*Sizeof(vliType)
   281  		putLE64(uint64(s.block.hash.unpadded), buf[:])
   282  		putLE64(uint64(s.block.hash.uncompressed), buf[8:])
   283  		_, _ = s.block.hash.sha256.Write(buf[:])
   284  		s.block.count++
   285  	}
   286  	return ret
   287  }
   288  
   289  /* Update the Index size and the CRC32 hash. */
   290  func indexUpdate(s *xzDec, b *xzBuf) {
   291  	inUsed := b.inPos - s.inStart
   292  	s.index.size += vliType(inUsed)
   293  	_, _ = s.crc32.Write(b.in[s.inStart : s.inStart+inUsed])
   294  }
   295  
   296  /*
   297   * Decode the Number of Records, Unpadded Size, and Uncompressed Size
   298   * fields from the Index field. That is, Index Padding and CRC32 are not
   299   * decoded by this function.
   300   *
   301   * This can return xzOK (more input needed), xzStreamEnd (everything
   302   * successfully decoded), or xzDataError (input is corrupt).
   303   */
   304  func decIndex(s *xzDec, b *xzBuf) xzRet {
   305  	var ret xzRet
   306  	for {
   307  		ret = decVLI(s, b.in, &b.inPos)
   308  		if ret != xzStreamEnd {
   309  			indexUpdate(s, b)
   310  			return ret
   311  		}
   312  		switch s.index.sequence {
   313  		case seqIndexCount:
   314  			s.index.count = s.vli
   315  			/*
   316  			 * Validate that the Number of Records field
   317  			 * indicates the same number of Records as
   318  			 * there were Blocks in the Stream.
   319  			 */
   320  			if s.index.count != s.block.count {
   321  				return xzDataError
   322  			}
   323  			s.index.sequence = seqIndexUnpadded
   324  		case seqIndexUnpadded:
   325  			s.index.hash.unpadded += s.vli
   326  			s.index.sequence = seqIndexUncompressed
   327  		case seqIndexUncompressed:
   328  			s.index.hash.uncompressed += s.vli
   329  			var buf [2 * 8]byte // 2*Sizeof(vliType)
   330  			putLE64(uint64(s.index.hash.unpadded), buf[:])
   331  			putLE64(uint64(s.index.hash.uncompressed), buf[8:])
   332  			_, _ = s.index.hash.sha256.Write(buf[:])
   333  			s.index.count--
   334  			s.index.sequence = seqIndexUnpadded
   335  		}
   336  		if !(s.index.count > 0) {
   337  			break
   338  		}
   339  	}
   340  	return xzStreamEnd
   341  }
   342  
   343  /*
   344   * Validate that the next 4 bytes match s.crc32.Sum(nil). s.pos must
   345   * be zero when starting to validate the first byte.
   346   */
   347  func crcValidate(s *xzDec, b *xzBuf) xzRet {
   348  	sum := s.crc32.Sum(nil)
   349  	// CRC32 - reverse slice
   350  	sum[0], sum[1], sum[2], sum[3] = sum[3], sum[2], sum[1], sum[0]
   351  	for {
   352  		if b.inPos == len(b.in) {
   353  			return xzOK
   354  		}
   355  		if sum[s.pos] != b.in[b.inPos] {
   356  			return xzDataError
   357  		}
   358  		b.inPos++
   359  		s.pos++
   360  		if !(s.pos < 4) {
   361  			break
   362  		}
   363  	}
   364  	s.crc32.Reset()
   365  	s.pos = 0
   366  	return xzStreamEnd
   367  }
   368  
   369  /*
   370   * Validate that the next 4/8/32 bytes match s.check.Sum(nil). s.pos
   371   * must be zero when starting to validate the first byte.
   372   */
   373  func checkValidate(s *xzDec, b *xzBuf) xzRet {
   374  	sum := s.check.Sum(nil)
   375  	if s.CheckType == CheckCRC32 || s.CheckType == CheckCRC64 {
   376  		// CRC32/64 - reverse slice
   377  		for i, j := 0, len(sum)-1; i < j; i, j = i+1, j-1 {
   378  			sum[i], sum[j] = sum[j], sum[i]
   379  		}
   380  	}
   381  	for {
   382  		if b.inPos == len(b.in) {
   383  			return xzOK
   384  		}
   385  		if sum[s.pos] != b.in[b.inPos] {
   386  			return xzDataError
   387  		}
   388  		b.inPos++
   389  		s.pos++
   390  		if !(s.pos < len(sum)) {
   391  			break
   392  		}
   393  	}
   394  	s.check.Reset()
   395  	s.pos = 0
   396  	return xzStreamEnd
   397  }
   398  
   399  /*
   400   * Skip over the Check field when the Check ID is not supported.
   401   * Returns true once the whole Check field has been skipped over.
   402   */
   403  func checkSkip(s *xzDec, b *xzBuf) bool {
   404  	for s.pos < int(checkSizes[s.CheckType]) {
   405  		if b.inPos == len(b.in) {
   406  			return false
   407  		}
   408  		b.inPos++
   409  		s.pos++
   410  	}
   411  	s.pos = 0
   412  	return true
   413  }
   414  
   415  /* polynomial table used in decStreamHeader below */
   416  var xzCRC64Table = crc64.MakeTable(crc64.ECMA)
   417  
   418  /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */
   419  func decStreamHeader(s *xzDec) xzRet {
   420  	if string(s.temp.buf[:len(headerMagic)]) != headerMagic {
   421  		return xzFormatError
   422  	}
   423  	if crc32.ChecksumIEEE(s.temp.buf[len(headerMagic):len(headerMagic)+2]) !=
   424  		getLE32(s.temp.buf[len(headerMagic)+2:]) {
   425  		return xzDataError
   426  	}
   427  	if s.temp.buf[len(headerMagic)] != 0 {
   428  		return xzOptionsError
   429  	}
   430  	/*
   431  	 * Of integrity checks, we support none (Check ID = 0),
   432  	 * CRC32 (Check ID = 1), CRC64 (Check ID = 4) and SHA256 (Check ID = 10)
   433  	 * However, we will accept other check types too, but then the check
   434  	 * won't be verified and a warning (xzUnsupportedCheck) will be given.
   435  	 */
   436  	s.CheckType = CheckID(s.temp.buf[len(headerMagic)+1])
   437  	if s.CheckType > checkMax {
   438  		return xzOptionsError
   439  	}
   440  	switch s.CheckType {
   441  	case CheckNone:
   442  		// CheckNone: no action needed
   443  	case CheckCRC32:
   444  		if s.checkCRC32 == nil {
   445  			s.checkCRC32 = crc32.NewIEEE()
   446  		} else {
   447  			s.checkCRC32.Reset()
   448  		}
   449  		s.check = s.checkCRC32
   450  	case CheckCRC64:
   451  		if s.checkCRC64 == nil {
   452  			s.checkCRC64 = crc64.New(xzCRC64Table)
   453  		} else {
   454  			s.checkCRC64.Reset()
   455  		}
   456  		s.check = s.checkCRC64
   457  	case CheckSHA256:
   458  		if s.checkSHA256 == nil {
   459  			s.checkSHA256 = sha256.New()
   460  		} else {
   461  			s.checkSHA256.Reset()
   462  		}
   463  		s.check = s.checkSHA256
   464  	default:
   465  		return xzUnsupportedCheck
   466  	}
   467  	return xzOK
   468  }
   469  
   470  /* Decode the Stream Footer field (the last 12 bytes of the .xz Stream) */
   471  func decStreamFooter(s *xzDec) xzRet {
   472  	if string(s.temp.buf[10:10+len(footerMagic)]) != footerMagic {
   473  		return xzDataError
   474  	}
   475  	if crc32.ChecksumIEEE(s.temp.buf[4:10]) != getLE32(s.temp.buf) {
   476  		return xzDataError
   477  	}
   478  	/*
   479  	 * Validate Backward Size. Note that we never added the size of the
   480  	 * Index CRC32 field to s->index.size, thus we use s->index.size / 4
   481  	 * instead of s->index.size / 4 - 1.
   482  	 */
   483  	if s.index.size>>2 != vliType(getLE32(s.temp.buf[4:])) {
   484  		return xzDataError
   485  	}
   486  	if s.temp.buf[8] != 0 || CheckID(s.temp.buf[9]) != s.CheckType {
   487  		return xzDataError
   488  	}
   489  	/*
   490  	 * Use xzStreamEnd instead of xzOK to be more convenient
   491  	 * for the caller.
   492  	 */
   493  	return xzStreamEnd
   494  }
   495  
   496  /* Decode the Block Header and initialize the filter chain. */
   497  func decBlockHeader(s *xzDec) xzRet {
   498  	var ret xzRet
   499  	/*
   500  	 * Validate the CRC32. We know that the temp buffer is at least
   501  	 * eight bytes so this is safe.
   502  	 */
   503  	crc := getLE32(s.temp.buf[len(s.temp.buf)-4:])
   504  	s.temp.buf = s.temp.buf[:len(s.temp.buf)-4]
   505  	if crc32.ChecksumIEEE(s.temp.buf) != crc {
   506  		return xzDataError
   507  	}
   508  	s.temp.pos = 2
   509  	/*
   510  	 * Catch unsupported Block Flags.
   511  	 */
   512  	if s.temp.buf[1]&0x3C != 0 {
   513  		return xzOptionsError
   514  	}
   515  	/* Compressed Size */
   516  	if s.temp.buf[1]&0x40 != 0 {
   517  		if decVLI(s, s.temp.buf, &s.temp.pos) != xzStreamEnd {
   518  			return xzDataError
   519  		}
   520  		if s.vli >= 1<<63-8 {
   521  			// the whole block must stay smaller than 2^63 bytes
   522  			// the block header cannot be smaller than 8 bytes
   523  			return xzDataError
   524  		}
   525  		if s.vli == 0 {
   526  			// compressed size must be non-zero
   527  			return xzDataError
   528  		}
   529  		s.blockHeader.compressed = s.vli
   530  	} else {
   531  		s.blockHeader.compressed = vliUnknown
   532  	}
   533  	/* Uncompressed Size */
   534  	if s.temp.buf[1]&0x80 != 0 {
   535  		if decVLI(s, s.temp.buf, &s.temp.pos) != xzStreamEnd {
   536  			return xzDataError
   537  		}
   538  		s.blockHeader.uncompressed = s.vli
   539  	} else {
   540  		s.blockHeader.uncompressed = vliUnknown
   541  	}
   542  	// get total number of filters (1-4)
   543  	filterTotal := int(s.temp.buf[1]&0x03) + 1
   544  	// slice to hold decoded filters
   545  	filterList := make([]struct {
   546  		id    xzFilterID
   547  		props uint32
   548  	}, filterTotal)
   549  	// decode the non-last filters which cannot be LZMA2
   550  	for i := 0; i < filterTotal-1; i++ {
   551  		/* Valid Filter Flags always take at least two bytes. */
   552  		if len(s.temp.buf)-s.temp.pos < 2 {
   553  			return xzDataError
   554  		}
   555  		s.temp.pos += 2
   556  		switch id := xzFilterID(s.temp.buf[s.temp.pos-2]); id {
   557  		case idDelta:
   558  			// delta filter
   559  			if s.temp.buf[s.temp.pos-1] != 0x01 {
   560  				return xzOptionsError
   561  			}
   562  			/* Filter Properties contains distance - 1 */
   563  			if len(s.temp.buf)-s.temp.pos < 1 {
   564  				return xzDataError
   565  			}
   566  			props := uint32(s.temp.buf[s.temp.pos])
   567  			s.temp.pos++
   568  			filterList[i] = struct {
   569  				id    xzFilterID
   570  				props uint32
   571  			}{id: id, props: props}
   572  		case idBCJX86, idBCJPowerPC, idBCJIA64,
   573  			idBCJARM, idBCJARMThumb, idBCJSPARC:
   574  			// bcj filter
   575  			var props uint32
   576  			switch s.temp.buf[s.temp.pos-1] {
   577  			case 0x00:
   578  				props = 0
   579  			case 0x04:
   580  				if len(s.temp.buf)-s.temp.pos < 4 {
   581  					return xzDataError
   582  				}
   583  				props = getLE32(s.temp.buf[s.temp.pos:])
   584  				s.temp.pos += 4
   585  			default:
   586  				return xzOptionsError
   587  			}
   588  			filterList[i] = struct {
   589  				id    xzFilterID
   590  				props uint32
   591  			}{id: id, props: props}
   592  		default:
   593  			return xzOptionsError
   594  		}
   595  	}
   596  	/*
   597  	 * decode the last filter which must be LZMA2
   598  	 */
   599  	if len(s.temp.buf)-s.temp.pos < 2 {
   600  		return xzDataError
   601  	}
   602  	/* Filter ID = LZMA2 */
   603  	if xzFilterID(s.temp.buf[s.temp.pos]) != idLZMA2 {
   604  		return xzOptionsError
   605  	}
   606  	s.temp.pos++
   607  	/* Size of Properties = 1-byte Filter Properties */
   608  	if s.temp.buf[s.temp.pos] != 0x01 {
   609  		return xzOptionsError
   610  	}
   611  	s.temp.pos++
   612  	/* Filter Properties contains LZMA2 dictionary size. */
   613  	if len(s.temp.buf)-s.temp.pos < 1 {
   614  		return xzDataError
   615  	}
   616  	props := uint32(s.temp.buf[s.temp.pos])
   617  	s.temp.pos++
   618  	filterList[filterTotal-1] = struct {
   619  		id    xzFilterID
   620  		props uint32
   621  	}{id: idLZMA2, props: props}
   622  	/*
   623  	 * Process the filter list and create s.chain, going from last
   624  	 * filter (LZMA2) to first filter
   625  	 *
   626  	 * First, LZMA2.
   627  	 */
   628  	ret = xzDecLZMA2Reset(s.lzma2, byte(filterList[filterTotal-1].props))
   629  	if ret != xzOK {
   630  		return ret
   631  	}
   632  	s.chain = func(b *xzBuf) xzRet {
   633  		return xzDecLZMA2Run(s.lzma2, b)
   634  	}
   635  	/*
   636  	 * Now the non-last filters
   637  	 */
   638  	for i := filterTotal - 2; i >= 0; i-- {
   639  		switch id := filterList[i].id; id {
   640  		case idDelta:
   641  			// delta filter
   642  			var delta *xzDecDelta
   643  			if s.deltasUsed < len(s.deltas) {
   644  				delta = s.deltas[s.deltasUsed]
   645  			} else {
   646  				delta = xzDecDeltaCreate()
   647  				s.deltas = append(s.deltas, delta)
   648  			}
   649  			s.deltasUsed++
   650  			ret = xzDecDeltaReset(delta, int(filterList[i].props)+1)
   651  			if ret != xzOK {
   652  				return ret
   653  			}
   654  			chain := s.chain
   655  			s.chain = func(b *xzBuf) xzRet {
   656  				return xzDecDeltaRun(delta, b, chain)
   657  			}
   658  		case idBCJX86, idBCJPowerPC, idBCJIA64,
   659  			idBCJARM, idBCJARMThumb, idBCJSPARC:
   660  			// bcj filter
   661  			var bcj *xzDecBCJ
   662  			if s.bcjsUsed < len(s.bcjs) {
   663  				bcj = s.bcjs[s.bcjsUsed]
   664  			} else {
   665  				bcj = xzDecBCJCreate()
   666  				s.bcjs = append(s.bcjs, bcj)
   667  			}
   668  			s.bcjsUsed++
   669  			ret = xzDecBCJReset(bcj, id, int(filterList[i].props))
   670  			if ret != xzOK {
   671  				return ret
   672  			}
   673  			chain := s.chain
   674  			s.chain = func(b *xzBuf) xzRet {
   675  				return xzDecBCJRun(bcj, b, chain)
   676  			}
   677  		}
   678  	}
   679  	/* The rest must be Header Padding. */
   680  	for s.temp.pos < len(s.temp.buf) {
   681  		if s.temp.buf[s.temp.pos] != 0x00 {
   682  			return xzOptionsError
   683  		}
   684  		s.temp.pos++
   685  	}
   686  	s.temp.pos = 0
   687  	s.block.compressed = 0
   688  	s.block.uncompressed = 0
   689  	return xzOK
   690  }
   691  
   692  func decMain(s *xzDec, b *xzBuf) xzRet {
   693  	var ret xzRet
   694  	/*
   695  	 * Store the start position for the case when we are in the middle
   696  	 * of the Index field.
   697  	 */
   698  	s.inStart = b.inPos
   699  	for {
   700  		switch s.sequence {
   701  		case seqStreamHeader:
   702  			/*
   703  			 * Stream Header is copied to s.temp, and then
   704  			 * decoded from there. This way if the caller
   705  			 * gives us only little input at a time, we can
   706  			 * still keep the Stream Header decoding code
   707  			 * simple. Similar approach is used in many places
   708  			 * in this file.
   709  			 */
   710  			if !fillTemp(s, b) {
   711  				return xzOK
   712  			}
   713  			/*
   714  			 * If decStreamHeader returns
   715  			 * xzUnsupportedCheck, it is still possible
   716  			 * to continue decoding. Thus, update s.sequence
   717  			 * before calling decStreamHeader.
   718  			 */
   719  			s.sequence = seqBlockStart
   720  			ret = decStreamHeader(s)
   721  			if ret != xzOK {
   722  				return ret
   723  			}
   724  			fallthrough
   725  		case seqBlockStart:
   726  			/* We need one byte of input to continue. */
   727  			if b.inPos == len(b.in) {
   728  				return xzOK
   729  			}
   730  			/* See if this is the beginning of the Index field. */
   731  			if b.in[b.inPos] == 0 {
   732  				s.inStart = b.inPos
   733  				b.inPos++
   734  				s.sequence = seqIndex
   735  				break
   736  			}
   737  			/*
   738  			 * Calculate the size of the Block Header and
   739  			 * prepare to decode it.
   740  			 */
   741  			s.blockHeader.size = (int(b.in[b.inPos]) + 1) * 4
   742  			s.temp.buf = s.temp.bufArray[:s.blockHeader.size]
   743  			s.temp.pos = 0
   744  			s.sequence = seqBlockHeader
   745  			fallthrough
   746  		case seqBlockHeader:
   747  			if !fillTemp(s, b) {
   748  				return xzOK
   749  			}
   750  			ret = decBlockHeader(s)
   751  			if ret != xzOK {
   752  				return ret
   753  			}
   754  			s.sequence = seqBlockUncompress
   755  			fallthrough
   756  		case seqBlockUncompress:
   757  			ret = decBlock(s, b)
   758  			if ret != xzStreamEnd {
   759  				return ret
   760  			}
   761  			s.sequence = seqBlockPadding
   762  			fallthrough
   763  		case seqBlockPadding:
   764  			/*
   765  			 * Size of Compressed Data + Block Padding
   766  			 * must be a multiple of four. We don't need
   767  			 * s->block.compressed for anything else
   768  			 * anymore, so we use it here to test the size
   769  			 * of the Block Padding field.
   770  			 */
   771  			for s.block.compressed&3 != 0 {
   772  				if b.inPos == len(b.in) {
   773  					return xzOK
   774  				}
   775  				if b.in[b.inPos] != 0 {
   776  					return xzDataError
   777  				}
   778  				b.inPos++
   779  				s.block.compressed++
   780  			}
   781  			s.sequence = seqBlockCheck
   782  			fallthrough
   783  		case seqBlockCheck:
   784  			switch s.CheckType {
   785  			case CheckCRC32, CheckCRC64, CheckSHA256:
   786  				ret = checkValidate(s, b)
   787  				if ret != xzStreamEnd {
   788  					return ret
   789  				}
   790  			default:
   791  				if !checkSkip(s, b) {
   792  					return xzOK
   793  				}
   794  			}
   795  			s.sequence = seqBlockStart
   796  		case seqIndex:
   797  			ret = decIndex(s, b)
   798  			if ret != xzStreamEnd {
   799  				return ret
   800  			}
   801  			s.sequence = seqIndexPadding
   802  			fallthrough
   803  		case seqIndexPadding:
   804  			for (s.index.size+vliType(b.inPos-s.inStart))&3 != 0 {
   805  				if b.inPos == len(b.in) {
   806  					indexUpdate(s, b)
   807  					return xzOK
   808  				}
   809  				if b.in[b.inPos] != 0 {
   810  					return xzDataError
   811  				}
   812  				b.inPos++
   813  			}
   814  			/* Finish the CRC32 value and Index size. */
   815  			indexUpdate(s, b)
   816  			/* Compare the hashes to validate the Index field. */
   817  			if !bytes.Equal(
   818  				s.block.hash.sha256.Sum(nil), s.index.hash.sha256.Sum(nil)) {
   819  				return xzDataError
   820  			}
   821  			s.sequence = seqIndexCRC32
   822  			fallthrough
   823  		case seqIndexCRC32:
   824  			ret = crcValidate(s, b)
   825  			if ret != xzStreamEnd {
   826  				return ret
   827  			}
   828  			s.temp.buf = s.temp.bufArray[:streamHeaderSize]
   829  			s.sequence = seqStreamFooter
   830  			fallthrough
   831  		case seqStreamFooter:
   832  			if !fillTemp(s, b) {
   833  				return xzOK
   834  			}
   835  			return decStreamFooter(s)
   836  		}
   837  	}
   838  	/* Never reached */
   839  }
   840  
   841  /**
   842   * xzDecRun - Run the XZ decoder
   843   * @s:         Decoder state allocated using xzDecInit
   844   * @b:         Input and output buffers
   845   *
   846   * See xzRet for details of return values.
   847   *
   848   * xzDecRun is a wrapper for decMain to handle some special cases.
   849   *
   850   * We must return xzBufError when it seems clear that we are not
   851   * going to make any progress anymore. This is to prevent the caller
   852   * from calling us infinitely when the input file is truncated or
   853   * otherwise corrupt. Since zlib-style API allows that the caller
   854   * fills the input buffer only when the decoder doesn't produce any
   855   * new output, we have to be careful to avoid returning xzBufError
   856   * too easily: xzBufError is returned only after the second
   857   * consecutive call to xzDecRun that makes no progress.
   858   */
   859  func xzDecRun(s *xzDec, b *xzBuf) xzRet {
   860  	inStart := b.inPos
   861  	outStart := b.outPos
   862  	ret := decMain(s, b)
   863  	if ret == xzOK && inStart == b.inPos && outStart == b.outPos {
   864  		if s.allowBufError {
   865  			ret = xzBufError
   866  		}
   867  		s.allowBufError = true
   868  	} else {
   869  		s.allowBufError = false
   870  	}
   871  	return ret
   872  }
   873  
   874  /**
   875   * xzDecInit - Allocate and initialize a XZ decoder state
   876   * @dictMax:    Maximum size of the LZMA2 dictionary (history buffer) for
   877   *              decoding. LZMA2 dictionary is always 2^n bytes
   878   *              or 2^n + 2^(n-1) bytes (the latter sizes are less common
   879   *              in practice), so other values for dictMax don't make sense.
   880   *
   881   * dictMax specifies the maximum allowed dictionary size that xzDecRun
   882   * may allocate once it has parsed the dictionary size from the stream
   883   * headers. This way excessive allocations can be avoided while still
   884   * limiting the maximum memory usage to a sane value to prevent running the
   885   * system out of memory when decompressing streams from untrusted sources.
   886   *
   887   * xzDecInit returns a pointer to an xzDec, which is ready to be used with
   888   * xzDecRun.
   889   */
   890  func xzDecInit(dictMax uint32, header *Header) *xzDec {
   891  	s := new(xzDec)
   892  	s.crc32 = crc32.NewIEEE()
   893  	s.Header = header
   894  	s.block.hash.sha256 = sha256.New()
   895  	s.index.hash.sha256 = sha256.New()
   896  	s.lzma2 = xzDecLZMA2Create(dictMax)
   897  	xzDecReset(s)
   898  	return s
   899  }
   900  
   901  /**
   902   * xzDecReset - Reset an already allocated decoder state
   903   * @s:          Decoder state allocated using xzDecInit
   904   *
   905   * This function can be used to reset the decoder state without
   906   * reallocating memory with xzDecInit.
   907   */
   908  func xzDecReset(s *xzDec) {
   909  	s.sequence = seqStreamHeader
   910  	s.allowBufError = false
   911  	s.pos = 0
   912  	s.crc32.Reset()
   913  	s.check = nil
   914  	s.CheckType = checkUnset
   915  	s.block.compressed = 0
   916  	s.block.uncompressed = 0
   917  	s.block.count = 0
   918  	s.block.hash.unpadded = 0
   919  	s.block.hash.uncompressed = 0
   920  	s.block.hash.sha256.Reset()
   921  	s.index.sequence = seqIndexCount
   922  	s.index.size = 0
   923  	s.index.count = 0
   924  	s.index.hash.unpadded = 0
   925  	s.index.hash.uncompressed = 0
   926  	s.index.hash.sha256.Reset()
   927  	s.temp.pos = 0
   928  	s.temp.buf = s.temp.bufArray[:streamHeaderSize]
   929  	s.chain = nil
   930  	s.bcjsUsed = 0
   931  	s.deltasUsed = 0
   932  }
   933  

View as plain text