mirror of
https://github.com/rwinkhart/go-winio.git
synced 2026-09-04 08:07:20 -04:00
LZX: Fix unaligned block failure
This fixes the case where an unaligned block lands on a 16-bit boundary.
This commit is contained in:
+20
-13
@@ -21,7 +21,7 @@ const (
|
|||||||
maxBlockSize = 32768
|
maxBlockSize = 32768
|
||||||
windowSize = 32768
|
windowSize = 32768
|
||||||
|
|
||||||
treePathLenCount = 17
|
maxTreePathLen = 16
|
||||||
|
|
||||||
e8filesize = 12000000
|
e8filesize = 12000000
|
||||||
maxe8offset = 0x3fffffff
|
maxe8offset = 0x3fffffff
|
||||||
@@ -97,8 +97,8 @@ func (f *decompressor) feed() bool {
|
|||||||
// getBits retrieves the next n bits from the byte stream. n
|
// getBits retrieves the next n bits from the byte stream. n
|
||||||
// must be <= 16. It sets f.err on error.
|
// must be <= 16. It sets f.err on error.
|
||||||
func (f *decompressor) getBits(n byte) uint16 {
|
func (f *decompressor) getBits(n byte) uint16 {
|
||||||
if f.nbits < 16 {
|
if f.nbits < n {
|
||||||
if !f.feed() && n > f.nbits {
|
if !f.feed() {
|
||||||
f.err = io.ErrUnexpectedEOF
|
f.err = io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,12 +115,12 @@ type huffman struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildTable builds a huffman decoding table from a slice of code lengths,
|
// buildTable builds a huffman decoding table from a slice of code lengths,
|
||||||
// one per code, in order. Each code length must be less than treePathLenCount.
|
// one per code, in order. Each code length must be <= maxTreePathLen.
|
||||||
// See https://en.wikipedia.org/wiki/Canonical_Huffman_code.
|
// See https://en.wikipedia.org/wiki/Canonical_Huffman_code.
|
||||||
func buildTable(codelens []byte) *huffman {
|
func buildTable(codelens []byte) *huffman {
|
||||||
// Determine the number of codes of each length, and the
|
// Determine the number of codes of each length, and the
|
||||||
// maximum length.
|
// maximum length.
|
||||||
var count [treePathLenCount]uint
|
var count [maxTreePathLen + 1]uint
|
||||||
var max byte
|
var max byte
|
||||||
for _, cl := range codelens {
|
for _, cl := range codelens {
|
||||||
count[cl]++
|
count[cl]++
|
||||||
@@ -134,7 +134,7 @@ func buildTable(codelens []byte) *huffman {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine the first code of each length.
|
// Determine the first code of each length.
|
||||||
var first [treePathLenCount]uint
|
var first [maxTreePathLen + 1]uint
|
||||||
code := uint(0)
|
code := uint(0)
|
||||||
for i := byte(1); i <= max; i++ {
|
for i := byte(1); i <= max; i++ {
|
||||||
code <<= 1
|
code <<= 1
|
||||||
@@ -178,7 +178,7 @@ func (f *decompressor) getCode(h *huffman) uint16 {
|
|||||||
f.err = errCorrupt
|
f.err = errCorrupt
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
if f.nbits < 16 {
|
if f.nbits < maxTreePathLen {
|
||||||
f.feed()
|
f.feed()
|
||||||
}
|
}
|
||||||
// For codes with length < h.maxbits, it doesn't matter
|
// For codes with length < h.maxbits, it doesn't matter
|
||||||
@@ -309,14 +309,21 @@ func (f *decompressor) readBlockHeader() (byte, uint16, error) {
|
|||||||
case verbatimBlock, alignedOffsetBlock:
|
case verbatimBlock, alignedOffsetBlock:
|
||||||
// The caller will read the huffman trees.
|
// The caller will read the huffman trees.
|
||||||
case uncompressedBlock:
|
case uncompressedBlock:
|
||||||
// Not sure if this can happen...
|
if f.nbits > 16 {
|
||||||
if f.nbits > 16 || f.nbits == 0 {
|
panic("impossible: more than one 16-bit word remains")
|
||||||
return 0, 0, errCorrupt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop the remaining bits in the current 16-bit word.
|
// Drop the remaining bits in the current 16-bit word
|
||||||
f.nbits = 0
|
// If there are no bits left, discard a full 16-bit word.
|
||||||
f.c = 0
|
n := f.nbits
|
||||||
|
if n == 0 {
|
||||||
|
n = 16
|
||||||
|
}
|
||||||
|
|
||||||
|
f.getBits(n)
|
||||||
|
if f.err != nil {
|
||||||
|
return 0, 0, f.err
|
||||||
|
}
|
||||||
|
|
||||||
// Read the LRU values for the next block.
|
// Read the LRU values for the next block.
|
||||||
var lru [12]byte
|
var lru [12]byte
|
||||||
|
|||||||
Reference in New Issue
Block a user