diff options
author | Ian Lance Taylor <iant@google.com> | 2016-02-03 21:58:02 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-02-03 21:58:02 +0000 |
commit | f98dd1a338867a408f7c72d73fbad7fe7fc93e3a (patch) | |
tree | 2f8da9862a9c1fe0df138917f997b03439c02773 /libgo/go/compress | |
parent | b081ed4efc144da0c45a6484aebfd10e0eb9fda3 (diff) | |
download | gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.zip gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.gz gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.bz2 |
libgo: Update to go1.6rc1.
Reviewed-on: https://go-review.googlesource.com/19200
From-SVN: r233110
Diffstat (limited to 'libgo/go/compress')
-rw-r--r-- | libgo/go/compress/bzip2/bit_reader.go | 8 | ||||
-rw-r--r-- | libgo/go/compress/bzip2/bzip2_test.go | 6 | ||||
-rw-r--r-- | libgo/go/compress/bzip2/huffman.go | 44 | ||||
-rw-r--r-- | libgo/go/compress/flate/deflate_test.go | 10 | ||||
-rw-r--r-- | libgo/go/compress/flate/fixedhuff.go | 78 | ||||
-rw-r--r-- | libgo/go/compress/flate/flate_test.go | 14 | ||||
-rw-r--r-- | libgo/go/compress/flate/gen.go | 265 | ||||
-rw-r--r-- | libgo/go/compress/flate/inflate.go | 66 | ||||
-rw-r--r-- | libgo/go/compress/flate/reader_test.go | 2 | ||||
-rw-r--r-- | libgo/go/compress/flate/token.go | 10 | ||||
-rw-r--r-- | libgo/go/compress/gzip/gunzip.go | 24 | ||||
-rw-r--r-- | libgo/go/compress/gzip/gunzip_test.go | 32 | ||||
-rw-r--r-- | libgo/go/compress/gzip/gzip.go | 7 | ||||
-rw-r--r-- | libgo/go/compress/lzw/reader.go | 17 | ||||
-rw-r--r-- | libgo/go/compress/lzw/writer_test.go | 10 | ||||
-rw-r--r-- | libgo/go/compress/testdata/Mark.Twain-Tom.Sawyer.txt | 393 | ||||
-rw-r--r-- | libgo/go/compress/testdata/gettysburg.txt | 29 | ||||
-rw-r--r-- | libgo/go/compress/zlib/reader.go | 9 | ||||
-rw-r--r-- | libgo/go/compress/zlib/reader_test.go | 24 | ||||
-rw-r--r-- | libgo/go/compress/zlib/writer_test.go | 27 |
20 files changed, 271 insertions, 804 deletions
diff --git a/libgo/go/compress/bzip2/bit_reader.go b/libgo/go/compress/bzip2/bit_reader.go index 32d1036..ab1d606 100644 --- a/libgo/go/compress/bzip2/bit_reader.go +++ b/libgo/go/compress/bzip2/bit_reader.go @@ -77,14 +77,6 @@ func (br *bitReader) ReadBit() bool { return n != 0 } -func (br *bitReader) TryReadBit() (bit byte, ok bool) { - if br.bits > 0 { - br.bits-- - return byte(br.n>>br.bits) & 1, true - } - return 0, false -} - func (br *bitReader) Err() error { return br.err } diff --git a/libgo/go/compress/bzip2/bzip2_test.go b/libgo/go/compress/bzip2/bzip2_test.go index 77c50df..7293d4e 100644 --- a/libgo/go/compress/bzip2/bzip2_test.go +++ b/libgo/go/compress/bzip2/bzip2_test.go @@ -173,6 +173,7 @@ const rand3Hex = "1744b384d68c042371244e13500d4bfb98c6244e3d71a5b700224420b59c59 const ( digits = iota twain + random ) var testfiles = []string{ @@ -180,8 +181,10 @@ var testfiles = []string{ // does not repeat, but there are only 10 possible digits, so it should be // reasonably compressible. digits: "testdata/e.txt.bz2", - // Twain is Project Gutenberg's edition of Mark Twain's classic English novel. + // Twain is Mark Twain's classic English novel. twain: "testdata/Mark.Twain-Tom.Sawyer.txt.bz2", + // 16KB of random data from /dev/urandom + random: "testdata/random.data.bz2", } func benchmarkDecode(b *testing.B, testfile int) { @@ -198,6 +201,7 @@ func benchmarkDecode(b *testing.B, testfile int) { func BenchmarkDecodeDigits(b *testing.B) { benchmarkDecode(b, digits) } func BenchmarkDecodeTwain(b *testing.B) { benchmarkDecode(b, twain) } +func BenchmarkDecodeRand(b *testing.B) { benchmarkDecode(b, random) } func TestBufferOverrun(t *testing.T) { // Tests https://golang.org/issue/5747. diff --git a/libgo/go/compress/bzip2/huffman.go b/libgo/go/compress/bzip2/huffman.go index 75a6223..9d574b9 100644 --- a/libgo/go/compress/bzip2/huffman.go +++ b/libgo/go/compress/bzip2/huffman.go @@ -38,23 +38,35 @@ func (t *huffmanTree) Decode(br *bitReader) (v uint16) { for { node := &t.nodes[nodeIndex] - bit, ok := br.TryReadBit() - if !ok && br.ReadBit() { - bit = 1 - } - // bzip2 encodes left as a true bit. - if bit != 0 { - // left - if node.left == invalidNodeValue { - return node.leftValue - } - nodeIndex = node.left + + var bit uint16 + if br.bits > 0 { + // Get next bit - fast path. + br.bits-- + bit = 0 - (uint16(br.n>>br.bits) & 1) } else { - // right - if node.right == invalidNodeValue { - return node.rightValue - } - nodeIndex = node.right + // Get next bit - slow path. + // Use ReadBits to retrieve a single bit + // from the underling io.ByteReader. + bit = 0 - uint16(br.ReadBits(1)) + } + // now + // bit = 0xffff if the next bit was 1 + // bit = 0x0000 if the next bit was 0 + + // 1 means left, 0 means right. + // + // if bit == 0xffff { + // nodeIndex = node.left + // } else { + // nodeIndex = node.right + // } + nodeIndex = (bit & node.left) | (^bit & node.right) + + if nodeIndex == invalidNodeValue { + // We found a leaf. Use the value of bit to decide + // whether is a left or a right value. + return (bit & node.leftValue) | (^bit & node.rightValue) } } } diff --git a/libgo/go/compress/flate/deflate_test.go b/libgo/go/compress/flate/deflate_test.go index d5d6e73..72bc665 100644 --- a/libgo/go/compress/flate/deflate_test.go +++ b/libgo/go/compress/flate/deflate_test.go @@ -7,6 +7,7 @@ package flate import ( "bytes" "fmt" + "internal/testenv" "io" "io/ioutil" "reflect" @@ -343,6 +344,9 @@ var deflateInflateStringTests = []deflateInflateStringTest{ } func TestDeflateInflateString(t *testing.T) { + if testing.Short() && testenv.Builder() == "" { + t.Skip("skipping in short mode") + } for _, test := range deflateInflateStringTests { gold, err := ioutil.ReadFile(test.filename) if err != nil { @@ -436,7 +440,11 @@ func TestWriterReset(t *testing.T) { t.Fatalf("NewWriter: %v", err) } buf := []byte("hello world") - for i := 0; i < 1024; i++ { + n := 1024 + if testing.Short() { + n = 10 + } + for i := 0; i < n; i++ { w.Write(buf) } w.Reset(ioutil.Discard) diff --git a/libgo/go/compress/flate/fixedhuff.go b/libgo/go/compress/flate/fixedhuff.go deleted file mode 100644 index 7df8b9a..0000000 --- a/libgo/go/compress/flate/fixedhuff.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2013 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. - -package flate - -// autogenerated by go run gen.go -output fixedhuff.go, DO NOT EDIT - -var fixedHuffmanDecoder = huffmanDecoder{ - 7, - [huffmanNumChunks]uint32{ - 0x1007, 0x0508, 0x0108, 0x1188, 0x1107, 0x0708, 0x0308, 0x0c09, - 0x1087, 0x0608, 0x0208, 0x0a09, 0x0008, 0x0808, 0x0408, 0x0e09, - 0x1047, 0x0588, 0x0188, 0x0909, 0x1147, 0x0788, 0x0388, 0x0d09, - 0x10c7, 0x0688, 0x0288, 0x0b09, 0x0088, 0x0888, 0x0488, 0x0f09, - 0x1027, 0x0548, 0x0148, 0x11c8, 0x1127, 0x0748, 0x0348, 0x0c89, - 0x10a7, 0x0648, 0x0248, 0x0a89, 0x0048, 0x0848, 0x0448, 0x0e89, - 0x1067, 0x05c8, 0x01c8, 0x0989, 0x1167, 0x07c8, 0x03c8, 0x0d89, - 0x10e7, 0x06c8, 0x02c8, 0x0b89, 0x00c8, 0x08c8, 0x04c8, 0x0f89, - 0x1017, 0x0528, 0x0128, 0x11a8, 0x1117, 0x0728, 0x0328, 0x0c49, - 0x1097, 0x0628, 0x0228, 0x0a49, 0x0028, 0x0828, 0x0428, 0x0e49, - 0x1057, 0x05a8, 0x01a8, 0x0949, 0x1157, 0x07a8, 0x03a8, 0x0d49, - 0x10d7, 0x06a8, 0x02a8, 0x0b49, 0x00a8, 0x08a8, 0x04a8, 0x0f49, - 0x1037, 0x0568, 0x0168, 0x11e8, 0x1137, 0x0768, 0x0368, 0x0cc9, - 0x10b7, 0x0668, 0x0268, 0x0ac9, 0x0068, 0x0868, 0x0468, 0x0ec9, - 0x1077, 0x05e8, 0x01e8, 0x09c9, 0x1177, 0x07e8, 0x03e8, 0x0dc9, - 0x10f7, 0x06e8, 0x02e8, 0x0bc9, 0x00e8, 0x08e8, 0x04e8, 0x0fc9, - 0x1007, 0x0518, 0x0118, 0x1198, 0x1107, 0x0718, 0x0318, 0x0c29, - 0x1087, 0x0618, 0x0218, 0x0a29, 0x0018, 0x0818, 0x0418, 0x0e29, - 0x1047, 0x0598, 0x0198, 0x0929, 0x1147, 0x0798, 0x0398, 0x0d29, - 0x10c7, 0x0698, 0x0298, 0x0b29, 0x0098, 0x0898, 0x0498, 0x0f29, - 0x1027, 0x0558, 0x0158, 0x11d8, 0x1127, 0x0758, 0x0358, 0x0ca9, - 0x10a7, 0x0658, 0x0258, 0x0aa9, 0x0058, 0x0858, 0x0458, 0x0ea9, - 0x1067, 0x05d8, 0x01d8, 0x09a9, 0x1167, 0x07d8, 0x03d8, 0x0da9, - 0x10e7, 0x06d8, 0x02d8, 0x0ba9, 0x00d8, 0x08d8, 0x04d8, 0x0fa9, - 0x1017, 0x0538, 0x0138, 0x11b8, 0x1117, 0x0738, 0x0338, 0x0c69, - 0x1097, 0x0638, 0x0238, 0x0a69, 0x0038, 0x0838, 0x0438, 0x0e69, - 0x1057, 0x05b8, 0x01b8, 0x0969, 0x1157, 0x07b8, 0x03b8, 0x0d69, - 0x10d7, 0x06b8, 0x02b8, 0x0b69, 0x00b8, 0x08b8, 0x04b8, 0x0f69, - 0x1037, 0x0578, 0x0178, 0x11f8, 0x1137, 0x0778, 0x0378, 0x0ce9, - 0x10b7, 0x0678, 0x0278, 0x0ae9, 0x0078, 0x0878, 0x0478, 0x0ee9, - 0x1077, 0x05f8, 0x01f8, 0x09e9, 0x1177, 0x07f8, 0x03f8, 0x0de9, - 0x10f7, 0x06f8, 0x02f8, 0x0be9, 0x00f8, 0x08f8, 0x04f8, 0x0fe9, - 0x1007, 0x0508, 0x0108, 0x1188, 0x1107, 0x0708, 0x0308, 0x0c19, - 0x1087, 0x0608, 0x0208, 0x0a19, 0x0008, 0x0808, 0x0408, 0x0e19, - 0x1047, 0x0588, 0x0188, 0x0919, 0x1147, 0x0788, 0x0388, 0x0d19, - 0x10c7, 0x0688, 0x0288, 0x0b19, 0x0088, 0x0888, 0x0488, 0x0f19, - 0x1027, 0x0548, 0x0148, 0x11c8, 0x1127, 0x0748, 0x0348, 0x0c99, - 0x10a7, 0x0648, 0x0248, 0x0a99, 0x0048, 0x0848, 0x0448, 0x0e99, - 0x1067, 0x05c8, 0x01c8, 0x0999, 0x1167, 0x07c8, 0x03c8, 0x0d99, - 0x10e7, 0x06c8, 0x02c8, 0x0b99, 0x00c8, 0x08c8, 0x04c8, 0x0f99, - 0x1017, 0x0528, 0x0128, 0x11a8, 0x1117, 0x0728, 0x0328, 0x0c59, - 0x1097, 0x0628, 0x0228, 0x0a59, 0x0028, 0x0828, 0x0428, 0x0e59, - 0x1057, 0x05a8, 0x01a8, 0x0959, 0x1157, 0x07a8, 0x03a8, 0x0d59, - 0x10d7, 0x06a8, 0x02a8, 0x0b59, 0x00a8, 0x08a8, 0x04a8, 0x0f59, - 0x1037, 0x0568, 0x0168, 0x11e8, 0x1137, 0x0768, 0x0368, 0x0cd9, - 0x10b7, 0x0668, 0x0268, 0x0ad9, 0x0068, 0x0868, 0x0468, 0x0ed9, - 0x1077, 0x05e8, 0x01e8, 0x09d9, 0x1177, 0x07e8, 0x03e8, 0x0dd9, - 0x10f7, 0x06e8, 0x02e8, 0x0bd9, 0x00e8, 0x08e8, 0x04e8, 0x0fd9, - 0x1007, 0x0518, 0x0118, 0x1198, 0x1107, 0x0718, 0x0318, 0x0c39, - 0x1087, 0x0618, 0x0218, 0x0a39, 0x0018, 0x0818, 0x0418, 0x0e39, - 0x1047, 0x0598, 0x0198, 0x0939, 0x1147, 0x0798, 0x0398, 0x0d39, - 0x10c7, 0x0698, 0x0298, 0x0b39, 0x0098, 0x0898, 0x0498, 0x0f39, - 0x1027, 0x0558, 0x0158, 0x11d8, 0x1127, 0x0758, 0x0358, 0x0cb9, - 0x10a7, 0x0658, 0x0258, 0x0ab9, 0x0058, 0x0858, 0x0458, 0x0eb9, - 0x1067, 0x05d8, 0x01d8, 0x09b9, 0x1167, 0x07d8, 0x03d8, 0x0db9, - 0x10e7, 0x06d8, 0x02d8, 0x0bb9, 0x00d8, 0x08d8, 0x04d8, 0x0fb9, - 0x1017, 0x0538, 0x0138, 0x11b8, 0x1117, 0x0738, 0x0338, 0x0c79, - 0x1097, 0x0638, 0x0238, 0x0a79, 0x0038, 0x0838, 0x0438, 0x0e79, - 0x1057, 0x05b8, 0x01b8, 0x0979, 0x1157, 0x07b8, 0x03b8, 0x0d79, - 0x10d7, 0x06b8, 0x02b8, 0x0b79, 0x00b8, 0x08b8, 0x04b8, 0x0f79, - 0x1037, 0x0578, 0x0178, 0x11f8, 0x1137, 0x0778, 0x0378, 0x0cf9, - 0x10b7, 0x0678, 0x0278, 0x0af9, 0x0078, 0x0878, 0x0478, 0x0ef9, - 0x1077, 0x05f8, 0x01f8, 0x09f9, 0x1177, 0x07f8, 0x03f8, 0x0df9, - 0x10f7, 0x06f8, 0x02f8, 0x0bf9, 0x00f8, 0x08f8, 0x04f8, 0x0ff9, - }, - nil, 0, -} diff --git a/libgo/go/compress/flate/flate_test.go b/libgo/go/compress/flate/flate_test.go index 3f67025..341d807 100644 --- a/libgo/go/compress/flate/flate_test.go +++ b/libgo/go/compress/flate/flate_test.go @@ -11,7 +11,9 @@ package flate import ( "bytes" "encoding/hex" + "io" "io/ioutil" + "strings" "testing" ) @@ -258,3 +260,15 @@ func TestStreams(t *testing.T) { } } } + +func TestTruncatedStreams(t *testing.T) { + const data = "\x00\f\x00\xf3\xffhello, world\x01\x00\x00\xff\xff" + + for i := 0; i < len(data)-1; i++ { + r := NewReader(strings.NewReader(data[:i])) + _, err := io.Copy(ioutil.Discard, r) + if err != io.ErrUnexpectedEOF { + t.Errorf("io.Copy(%d) on truncated stream: got %v, want %v", i, err, io.ErrUnexpectedEOF) + } + } +} diff --git a/libgo/go/compress/flate/gen.go b/libgo/go/compress/flate/gen.go deleted file mode 100644 index 154c89a..0000000 --- a/libgo/go/compress/flate/gen.go +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright 2012 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. - -// +build ignore - -// This program generates fixedhuff.go -// Invoke as -// -// go run gen.go -output fixedhuff.go - -package main - -import ( - "bytes" - "flag" - "fmt" - "go/format" - "io/ioutil" - "log" -) - -var filename = flag.String("output", "fixedhuff.go", "output file name") - -const maxCodeLen = 16 - -// Note: the definition of the huffmanDecoder struct is copied from -// inflate.go, as it is private to the implementation. - -// chunk & 15 is number of bits -// chunk >> 4 is value, including table link - -const ( - huffmanChunkBits = 9 - huffmanNumChunks = 1 << huffmanChunkBits - huffmanCountMask = 15 - huffmanValueShift = 4 -) - -type huffmanDecoder struct { - min int // the minimum code length - chunks [huffmanNumChunks]uint32 // chunks as described above - links [][]uint32 // overflow links - linkMask uint32 // mask the width of the link table -} - -// Initialize Huffman decoding tables from array of code lengths. -// Following this function, h is guaranteed to be initialized into a complete -// tree (i.e., neither over-subscribed nor under-subscribed). The exception is a -// degenerate case where the tree has only a single symbol with length 1. Empty -// trees are permitted. -func (h *huffmanDecoder) init(bits []int) bool { - // Sanity enables additional runtime tests during Huffman - // table construction. It's intended to be used during - // development to supplement the currently ad-hoc unit tests. - const sanity = false - - if h.min != 0 { - *h = huffmanDecoder{} - } - - // Count number of codes of each length, - // compute min and max length. - var count [maxCodeLen]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]++ - } - - // Empty tree. The decompressor.huffSym function will fail later if the tree - // is used. Technically, an empty tree is only valid for the HDIST tree and - // not the HCLEN and HLIT tree. However, a stream with an empty HCLEN tree - // is guaranteed to fail since it will attempt to use the tree to decode the - // codes for the HLIT and HDIST trees. Similarly, an empty HLIT tree is - // guaranteed to fail later since the compressed data section must be - // composed of at least one symbol (the end-of-block marker). - if max == 0 { - return true - } - - code := 0 - var nextcode [maxCodeLen]int - for i := min; i <= max; i++ { - code <<= 1 - nextcode[i] = code - code += count[i] - } - - // Check that the coding is complete (i.e., that we've - // assigned all 2-to-the-max possible bit sequences). - // Exception: To be compatible with zlib, we also need to - // accept degenerate single-code codings. See also - // TestDegenerateHuffmanCoding. - if code != 1<<uint(max) && !(code == 1 && max == 1) { - return false - } - - h.min = min - if max > huffmanChunkBits { - numLinks := 1 << (uint(max) - huffmanChunkBits) - h.linkMask = uint32(numLinks - 1) - - // create link tables - link := nextcode[huffmanChunkBits+1] >> 1 - h.links = make([][]uint32, huffmanNumChunks-link) - for j := uint(link); j < huffmanNumChunks; j++ { - reverse := int(reverseByte[j>>8]) | int(reverseByte[j&0xff])<<8 - reverse >>= uint(16 - huffmanChunkBits) - off := j - uint(link) - if sanity && h.chunks[reverse] != 0 { - panic("impossible: overwriting existing chunk") - } - h.chunks[reverse] = uint32(off<<huffmanValueShift | (huffmanChunkBits + 1)) - h.links[off] = make([]uint32, numLinks) - } - } - - for i, n := range bits { - if n == 0 { - continue - } - code := nextcode[n] - nextcode[n]++ - chunk := uint32(i<<huffmanValueShift | n) - reverse := int(reverseByte[code>>8]) | int(reverseByte[code&0xff])<<8 - reverse >>= uint(16 - n) - if n <= huffmanChunkBits { - for off := reverse; off < len(h.chunks); off += 1 << uint(n) { - // We should never need to overwrite - // an existing chunk. Also, 0 is - // never a valid chunk, because the - // lower 4 "count" bits should be - // between 1 and 15. - if sanity && h.chunks[off] != 0 { - panic("impossible: overwriting existing chunk") - } - h.chunks[off] = chunk - } - } else { - j := reverse & (huffmanNumChunks - 1) - if sanity && h.chunks[j]&huffmanCountMask != huffmanChunkBits+1 { - // Longer codes should have been - // associated with a link table above. - panic("impossible: not an indirect chunk") - } - value := h.chunks[j] >> huffmanValueShift - linktab := h.links[value] - reverse >>= huffmanChunkBits - for off := reverse; off < len(linktab); off += 1 << uint(n-huffmanChunkBits) { - if sanity && linktab[off] != 0 { - panic("impossible: overwriting existing chunk") - } - linktab[off] = chunk - } - } - } - - if sanity { - // Above we've sanity checked that we never overwrote - // an existing entry. Here we additionally check that - // we filled the tables completely. - for i, chunk := range h.chunks { - if chunk == 0 { - // As an exception, in the degenerate - // single-code case, we allow odd - // chunks to be missing. - if code == 1 && i%2 == 1 { - continue - } - panic("impossible: missing chunk") - } - } - for _, linktab := range h.links { - for _, chunk := range linktab { - if chunk == 0 { - panic("impossible: missing chunk") - } - } - } - } - - return true -} - -func main() { - flag.Parse() - - var h huffmanDecoder - var bits [288]int - initReverseByte() - for i := 0; i < 144; i++ { - bits[i] = 8 - } - for i := 144; i < 256; i++ { - bits[i] = 9 - } - for i := 256; i < 280; i++ { - bits[i] = 7 - } - for i := 280; i < 288; i++ { - bits[i] = 8 - } - h.init(bits[:]) - if h.links != nil { - log.Fatal("Unexpected links table in fixed Huffman decoder") - } - - var buf bytes.Buffer - - fmt.Fprintf(&buf, `// Copyright 2013 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.`+"\n\n") - - fmt.Fprintln(&buf, "package flate") - fmt.Fprintln(&buf) - fmt.Fprintln(&buf, "// autogenerated by go run gen.go -output fixedhuff.go, DO NOT EDIT") - fmt.Fprintln(&buf) - fmt.Fprintln(&buf, "var fixedHuffmanDecoder = huffmanDecoder{") - fmt.Fprintf(&buf, "\t%d,\n", h.min) - fmt.Fprintln(&buf, "\t[huffmanNumChunks]uint32{") - for i := 0; i < huffmanNumChunks; i++ { - if i&7 == 0 { - fmt.Fprintf(&buf, "\t\t") - } else { - fmt.Fprintf(&buf, " ") - } - fmt.Fprintf(&buf, "0x%04x,", h.chunks[i]) - if i&7 == 7 { - fmt.Fprintln(&buf) - } - } - fmt.Fprintln(&buf, "\t},") - fmt.Fprintln(&buf, "\tnil, 0,") - fmt.Fprintln(&buf, "}") - - data, err := format.Source(buf.Bytes()) - if err != nil { - log.Fatal(err) - } - err = ioutil.WriteFile(*filename, data, 0644) - if err != nil { - log.Fatal(err) - } -} - -var reverseByte [256]byte - -func initReverseByte() { - for x := 0; x < 256; x++ { - var result byte - for i := uint(0); i < 8; i++ { - result |= byte(((x >> i) & 1) << (7 - i)) - } - reverseByte[x] = result - } -} diff --git a/libgo/go/compress/flate/inflate.go b/libgo/go/compress/flate/inflate.go index 04372de..42261e9 100644 --- a/libgo/go/compress/flate/inflate.go +++ b/libgo/go/compress/flate/inflate.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:generate go run gen.go -output fixedhuff.go - // Package flate implements the DEFLATE compressed data format, described in // RFC 1951. The gzip and zlib packages implement access to DEFLATE-based file // formats. @@ -13,6 +11,7 @@ import ( "bufio" "io" "strconv" + "sync" ) const ( @@ -26,6 +25,10 @@ const ( numCodes = 19 // number of codes in Huffman meta-code ) +// Initialize the fixedHuffmanDecoder only once upon first use. +var fixedOnce sync.Once +var fixedHuffmanDecoder huffmanDecoder + // A CorruptInputError reports the presence of corrupt input at a given offset. type CorruptInputError int64 @@ -39,6 +42,8 @@ type InternalError string func (e InternalError) Error() string { return "flate: internal error: " + string(e) } // A ReadError reports an error encountered while reading input. +// +// Deprecated: No longer returned. type ReadError struct { Offset int64 // byte offset where error occurred Err error // error returned by underlying Read @@ -49,6 +54,8 @@ func (e *ReadError) Error() string { } // A WriteError reports an error encountered while writing output. +// +// Deprecated: No longer returned. type WriteError struct { Offset int64 // byte offset where error occurred Err error // error returned by underlying Write @@ -67,10 +74,6 @@ type Resetter interface { Reset(r io.Reader, dict []byte) error } -// Note that much of the implementation of huffmanDecoder is also copied -// into gen.go (in package main) for the purpose of precomputing the -// fixed huffman tables so they can be included statically. - // The data structure for decoding Huffman tables is based on that of // zlib. There is a lookup table of a fixed bit width (huffmanChunkBits), // For codes smaller than the table width, there are multiple entries @@ -78,12 +81,15 @@ type Resetter interface { // larger than the table width, the table contains a link to an overflow // table. The width of each entry in the link table is the maximum code // size minus the chunk width. - +// // Note that you can do a lookup in the table even without all bits // filled. Since the extra bits are zero, and the DEFLATE Huffman codes // have the property that shorter codes come before longer ones, the // bit length estimate in the result is a lower bound on the actual // number of bits. +// +// See the following: +// http://www.gzip.org/algorithm.txt // chunk & 15 is number of bits // chunk >> 4 is value, including table link @@ -459,6 +465,14 @@ func (f *decompressor) readHuffman() error { return CorruptInputError(f.roffset) } + // As an optimization, we can initialize the min bits to read at a time + // for the HLIT tree to the length of the EOB marker since we know that + // every block must terminate with one. This preserves the property that + // we never read any extra bytes after the end of the DEFLATE stream. + if f.h1.min < f.bits[endBlockMarker] { + f.h1.min = f.bits[endBlockMarker] + } + return nil } @@ -635,7 +649,10 @@ func (f *decompressor) dataBlock() { nr, err := io.ReadFull(f.r, f.buf[0:4]) f.roffset += int64(nr) if err != nil { - f.err = &ReadError{f.roffset, err} + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + f.err = err return } n := int(f.buf[0]) | int(f.buf[1])<<8 @@ -667,7 +684,10 @@ func (f *decompressor) copyData() { m, err := io.ReadFull(f.r, f.hist[f.hp:f.hp+m]) f.roffset += int64(m) if err != nil { - f.err = &ReadError{f.roffset, err} + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + f.err = err return } n -= m @@ -760,6 +780,26 @@ func makeReader(r io.Reader) Reader { return bufio.NewReader(r) } +func fixedHuffmanDecoderInit() { + fixedOnce.Do(func() { + // These come from the RFC section 3.2.6. + var bits [288]int + for i := 0; i < 144; i++ { + bits[i] = 8 + } + for i := 144; i < 256; i++ { + bits[i] = 9 + } + for i := 256; i < 280; i++ { + bits[i] = 7 + } + for i := 280; i < 288; i++ { + bits[i] = 8 + } + fixedHuffmanDecoder.init(bits[:]) + }) +} + func (f *decompressor) Reset(r io.Reader, dict []byte) error { *f = decompressor{ r: makeReader(r), @@ -783,11 +823,13 @@ func (f *decompressor) Reset(r io.Reader, dict []byte) error { // // The ReadCloser returned by NewReader also implements Resetter. func NewReader(r io.Reader) io.ReadCloser { + fixedHuffmanDecoderInit() + var f decompressor - f.bits = new([maxNumLit + maxNumDist]int) - f.codebits = new([numCodes]int) f.r = makeReader(r) f.hist = new([maxHist]byte) + f.bits = new([maxNumLit + maxNumDist]int) + f.codebits = new([numCodes]int) f.step = (*decompressor).nextBlock return &f } @@ -800,6 +842,8 @@ func NewReader(r io.Reader) io.ReadCloser { // // The ReadCloser returned by NewReader also implements Resetter. func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser { + fixedHuffmanDecoderInit() + var f decompressor f.r = makeReader(r) f.hist = new([maxHist]byte) diff --git a/libgo/go/compress/flate/reader_test.go b/libgo/go/compress/flate/reader_test.go index a62ef74..bd88732 100644 --- a/libgo/go/compress/flate/reader_test.go +++ b/libgo/go/compress/flate/reader_test.go @@ -32,7 +32,7 @@ var testfiles = []string{ // does not repeat, but there are only 10 possible digits, so it should be // reasonably compressible. digits: "../testdata/e.txt", - // Twain is Project Gutenberg's edition of Mark Twain's classic English novel. + // Twain is Mark Twain's classic English novel. twain: "../testdata/Mark.Twain-Tom.Sawyer.txt", } diff --git a/libgo/go/compress/flate/token.go b/libgo/go/compress/flate/token.go index 4d49176..c485939 100644 --- a/libgo/go/compress/flate/token.go +++ b/libgo/go/compress/flate/token.go @@ -90,13 +90,11 @@ func lengthCode(len uint32) uint32 { return lengthCodes[len] } // Returns the offset code corresponding to a specific offset func offsetCode(off uint32) uint32 { - const n = uint32(len(offsetCodes)) - switch { - case off < n: + if off < uint32(len(offsetCodes)) { return offsetCodes[off] - case off>>7 < n: + } + if off>>7 < uint32(len(offsetCodes)) { return offsetCodes[off>>7] + 14 - default: - return offsetCodes[off>>14] + 28 } + return offsetCodes[off>>14] + 28 } diff --git a/libgo/go/compress/gzip/gunzip.go b/libgo/go/compress/gzip/gunzip.go index 72ee55c..3d33145 100644 --- a/libgo/go/compress/gzip/gunzip.go +++ b/libgo/go/compress/gzip/gunzip.go @@ -43,6 +43,9 @@ var ( // The gzip file stores a header giving metadata about the compressed file. // That header is exposed as the fields of the Writer and Reader structs. +// +// Strings must be UTF-8 encoded and may only contain Unicode code points +// U+0001 through U+00FF, due to limitations of the GZIP file format. type Header struct { Comment string // comment Extra []byte // "extra data" @@ -66,7 +69,7 @@ type Header struct { // returned by Read as tentative until they receive the io.EOF // marking the end of the data. type Reader struct { - Header + Header // valid after NewReader or Reader.Reset r flate.Reader decompressor io.ReadCloser digest hash.Hash32 @@ -80,7 +83,10 @@ type Reader struct { // NewReader creates a new Reader reading the given reader. // If r does not also implement io.ByteReader, // the decompressor may read more data than necessary from r. +// // It is the caller's responsibility to call Close on the Reader when done. +// +// The Reader.Header fields will be valid in the Reader returned. func NewReader(r io.Reader) (*Reader, error) { z := new(Reader) z.r = makeReader(r) @@ -164,6 +170,9 @@ func (z *Reader) readString() (string, error) { func (z *Reader) read2() (uint32, error) { _, err := io.ReadFull(z.r, z.buf[0:2]) if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } return 0, err } return uint32(z.buf[0]) | uint32(z.buf[1])<<8, nil @@ -172,6 +181,13 @@ func (z *Reader) read2() (uint32, error) { func (z *Reader) readHeader(save bool) error { _, err := io.ReadFull(z.r, z.buf[0:10]) if err != nil { + // RFC1952 section 2.2 says the following: + // A gzip file consists of a series of "members" (compressed data sets). + // + // Other than this, the specification does not clarify whether a + // "series" is defined as "one or more" or "zero or more". To err on the + // side of caution, Go interprets this to mean "zero or more". + // Thus, it is okay to return io.EOF here. return err } if z.buf[0] != gzipID1 || z.buf[1] != gzipID2 || z.buf[2] != gzipDeflate { @@ -193,6 +209,9 @@ func (z *Reader) readHeader(save bool) error { } data := make([]byte, n) if _, err = io.ReadFull(z.r, data); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } return err } if save { @@ -257,6 +276,9 @@ func (z *Reader) Read(p []byte) (n int, err error) { // Finished file; check checksum + size. if _, err := io.ReadFull(z.r, z.buf[0:8]); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } z.err = err return 0, err } diff --git a/libgo/go/compress/gzip/gunzip_test.go b/libgo/go/compress/gzip/gunzip_test.go index 0636dec..007d958 100644 --- a/libgo/go/compress/gzip/gunzip_test.go +++ b/libgo/go/compress/gzip/gunzip_test.go @@ -6,6 +6,7 @@ package gzip import ( "bytes" + "compress/flate" "io" "io/ioutil" "os" @@ -408,3 +409,34 @@ Found: t.Fatalf("third reset: err=%v, want io.EOF", err) } } + +func TestNilStream(t *testing.T) { + // Go liberally interprets RFC1952 section 2.2 to mean that a gzip file + // consist of zero or more members. Thus, we test that a nil stream is okay. + _, err := NewReader(bytes.NewReader(nil)) + if err != io.EOF { + t.Fatalf("NewReader(nil) on empty stream: got %v, want io.EOF", err) + } +} + +func TestTruncatedStreams(t *testing.T) { + const data = "\x1f\x8b\b\x04\x00\tn\x88\x00\xff\a\x00foo bar\xcbH\xcd\xc9\xc9\xd7Q(\xcf/\xcaI\x01\x04:r\xab\xff\f\x00\x00\x00" + + // Intentionally iterate starting with at least one byte in the stream. + for i := 1; i < len(data)-1; i++ { + r, err := NewReader(strings.NewReader(data[:i])) + if err != nil { + if err != io.ErrUnexpectedEOF { + t.Errorf("NewReader(%d) on truncated stream: got %v, want %v", i, err, io.ErrUnexpectedEOF) + } + continue + } + _, err = io.Copy(ioutil.Discard, r) + if ferr, ok := err.(*flate.ReadError); ok { + err = ferr.Err + } + if err != io.ErrUnexpectedEOF { + t.Errorf("io.Copy(%d) on truncated stream: got %v, want %v", i, err, io.ErrUnexpectedEOF) + } + } +} diff --git a/libgo/go/compress/gzip/gzip.go b/libgo/go/compress/gzip/gzip.go index 5131d12..4d945e4 100644 --- a/libgo/go/compress/gzip/gzip.go +++ b/libgo/go/compress/gzip/gzip.go @@ -25,7 +25,7 @@ const ( // A Writer is an io.WriteCloser. // Writes to a Writer are compressed and written to w. type Writer struct { - Header + Header // written at first call to Write, Flush, or Close w io.Writer level int wroteHeader bool @@ -44,10 +44,7 @@ type Writer struct { // Writes may be buffered and not flushed until Close. // // Callers that wish to set the fields in Writer.Header must do so before -// the first call to Write or Close. The Comment and Name header fields are -// UTF-8 strings in Go, but the underlying format requires NUL-terminated ISO -// 8859-1 (Latin-1). NUL or non-Latin-1 runes in those strings will lead to an -// error on Write. +// the first call to Write, Flush, or Close. func NewWriter(w io.Writer) *Writer { z, _ := NewWriterLevel(w, DefaultCompression) return z diff --git a/libgo/go/compress/lzw/reader.go b/libgo/go/compress/lzw/reader.go index 1353831..9eef2b2 100644 --- a/libgo/go/compress/lzw/reader.go +++ b/libgo/go/compress/lzw/reader.go @@ -132,6 +132,7 @@ func (d *decoder) Read(b []byte) (int, error) { // litWidth is the width in bits of literal codes. func (d *decoder) decode() { // Loop over the code stream, converting codes into decompressed bytes. +loop: for { code, err := d.read(d) if err != nil { @@ -139,8 +140,7 @@ func (d *decoder) decode() { err = io.ErrUnexpectedEOF } d.err = err - d.flush() - return + break } switch { case code < d.clear: @@ -159,9 +159,8 @@ func (d *decoder) decode() { d.last = decoderInvalidCode continue case code == d.eof: - d.flush() d.err = io.EOF - return + break loop case code <= d.hi: c, i := code, len(d.output)-1 if code == d.hi { @@ -191,8 +190,7 @@ func (d *decoder) decode() { } default: d.err = errors.New("lzw: invalid code") - d.flush() - return + break loop } d.last, d.hi = code, d.hi+1 if d.hi >= d.overflow { @@ -204,13 +202,10 @@ func (d *decoder) decode() { } } if d.o >= flushBuffer { - d.flush() - return + break } } -} - -func (d *decoder) flush() { + // Flush pending output. d.toRead = d.output[:d.o] d.o = 0 } diff --git a/libgo/go/compress/lzw/writer_test.go b/libgo/go/compress/lzw/writer_test.go index c20d058..66d7617 100644 --- a/libgo/go/compress/lzw/writer_test.go +++ b/libgo/go/compress/lzw/writer_test.go @@ -5,6 +5,7 @@ package lzw import ( + "internal/testenv" "io" "io/ioutil" "os" @@ -13,6 +14,7 @@ import ( ) var filenames = []string{ + "../testdata/gettysburg.txt", "../testdata/e.txt", "../testdata/pi.txt", } @@ -89,10 +91,16 @@ func TestWriter(t *testing.T) { for _, filename := range filenames { for _, order := range [...]Order{LSB, MSB} { // The test data "2.71828 etcetera" is ASCII text requiring at least 6 bits. - for _, litWidth := range [...]int{6, 7, 8} { + for litWidth := 6; litWidth <= 8; litWidth++ { + if filename == "../testdata/gettysburg.txt" && litWidth == 6 { + continue + } testFile(t, filename, order, litWidth) } } + if testing.Short() && testenv.Builder() == "" { + break + } } } diff --git a/libgo/go/compress/testdata/Mark.Twain-Tom.Sawyer.txt b/libgo/go/compress/testdata/Mark.Twain-Tom.Sawyer.txt index c97da7e..c9106fd 100644 --- a/libgo/go/compress/testdata/Mark.Twain-Tom.Sawyer.txt +++ b/libgo/go/compress/testdata/Mark.Twain-Tom.Sawyer.txt @@ -1,27 +1,3 @@ -The Project Gutenberg EBook of The Adventures of Tom Sawyer, Complete -by Mark Twain (Samuel Clemens) - -This eBook is for the use of anyone anywhere at no cost and with -almost no restrictions whatsoever. You may copy it, give it away or -re-use it under the terms of the Project Gutenberg License included -with this eBook or online at www.gutenberg.net - - -Title: The Adventures of Tom Sawyer, Complete - -Author: Mark Twain (Samuel Clemens) - -Release Date: August 20, 2006 [EBook #74] -[Last updated: May 3, 2011] - -Language: English - - -*** START OF THIS PROJECT GUTENBERG EBOOK TOM SAWYER *** - - - - Produced by David Widger. The previous edition was updated by Jose Menendez. @@ -8487,372 +8463,3 @@ prosperous and happy. Some day it may seem worth while to take up the story of the younger ones again and see what sort of men and women they turned out to be; therefore it will be wisest not to reveal any of that part of their lives at present. - - - - - -End of the Project Gutenberg EBook of The Adventures of Tom Sawyer, Complete -by Mark Twain (Samuel Clemens) - -*** END OF THIS PROJECT GUTENBERG EBOOK TOM SAWYER *** - -***** This file should be named 74.txt or 74.zip ***** -This and all associated files of various formats will be found in: - http://www.gutenberg.net/7/74/ - -Produced by David Widger. The previous edition was update by Jose -Menendez. - - -Updated editions will replace the previous one--the old editions -will be renamed. - -Creating the works from public domain print editions means that no -one owns a United States copyright in these works, so the Foundation -(and you!) can copy and distribute it in the United States without -permission and without paying copyright royalties. Special rules, -set forth in the General Terms of Use part of this license, apply to -copying and distributing Project Gutenberg-tm electronic works to -protect the PROJECT GUTENBERG-tm concept and trademark. Project -Gutenberg is a registered trademark, and may not be used if you -charge for the eBooks, unless you receive specific permission. If you -do not charge anything for copies of this eBook, complying with the -rules is very easy. You may use this eBook for nearly any purpose -such as creation of derivative works, reports, performances and -research. They may be modified and printed and given away--you may do -practically ANYTHING with public domain eBooks. Redistribution is -subject to the trademark license, especially commercial -redistribution. - - - -*** START: FULL LICENSE *** - -THE FULL PROJECT GUTENBERG LICENSE -PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK - -To protect the Project Gutenberg-tm mission of promoting the free -distribution of electronic works, by using or distributing this work -(or any other work associated in any way with the phrase "Project -Gutenberg"), you agree to comply with all the terms of the Full Project -Gutenberg-tm License (available with this file or online at -http://gutenberg.net/license). - - -Section 1. General Terms of Use and Redistributing Project Gutenberg-tm -electronic works - -1.A. By reading or using any part of this Project Gutenberg-tm -electronic work, you indicate that you have read, understand, agree to -and accept all the terms of this license and intellectual property -(trademark/copyright) agreement. If you do not agree to abide by all -the terms of this agreement, you must cease using and return or destroy -all copies of Project Gutenberg-tm electronic works in your possession. -If you paid a fee for obtaining a copy of or access to a Project -Gutenberg-tm electronic work and you do not agree to be bound by the -terms of this agreement, you may obtain a refund from the person or -entity to whom you paid the fee as set forth in paragraph 1.E.8. - -1.B. "Project Gutenberg" is a registered trademark. It may only be -used on or associated in any way with an electronic work by people who -agree to be bound by the terms of this agreement. There are a few -things that you can do with most Project Gutenberg-tm electronic works -even without complying with the full terms of this agreement. See -paragraph 1.C below. There are a lot of things you can do with Project -Gutenberg-tm electronic works if you follow the terms of this agreement -and help preserve free future access to Project Gutenberg-tm electronic -works. See paragraph 1.E below. - -1.C. The Project Gutenberg Literary Archive Foundation ("the Foundation" -or PGLAF), owns a compilation copyright in the collection of Project -Gutenberg-tm electronic works. Nearly all the individual works in the -collection are in the public domain in the United States. If an -individual work is in the public domain in the United States and you are -located in the United States, we do not claim a right to prevent you from -copying, distributing, performing, displaying or creating derivative -works based on the work as long as all references to Project Gutenberg -are removed. Of course, we hope that you will support the Project -Gutenberg-tm mission of promoting free access to electronic works by -freely sharing Project Gutenberg-tm works in compliance with the terms of -this agreement for keeping the Project Gutenberg-tm name associated with -the work. You can easily comply with the terms of this agreement by -keeping this work in the same format with its attached full Project -Gutenberg-tm License when you share it without charge with others. - -1.D. The copyright laws of the place where you are located also govern -what you can do with this work. Copyright laws in most countries are in -a constant state of change. If you are outside the United States, check -the laws of your country in addition to the terms of this agreement -before downloading, copying, displaying, performing, distributing or -creating derivative works based on this work or any other Project -Gutenberg-tm work. The Foundation makes no representations concerning -the copyright status of any work in any country outside the United -States. - -1.E. Unless you have removed all references to Project Gutenberg: - -1.E.1. The following sentence, with active links to, or other immediate -access to, the full Project Gutenberg-tm License must appear prominently -whenever any copy of a Project Gutenberg-tm work (any work on which the -phrase "Project Gutenberg" appears, or with which the phrase "Project -Gutenberg" is associated) is accessed, displayed, performed, viewed, -copied or distributed: - -This eBook is for the use of anyone anywhere at no cost and with -almost no restrictions whatsoever. You may copy it, give it away or -re-use it under the terms of the Project Gutenberg License included -with this eBook or online at www.gutenberg.net - -1.E.2. If an individual Project Gutenberg-tm electronic work is derived -from the public domain (does not contain a notice indicating that it is -posted with permission of the copyright holder), the work can be copied -and distributed to anyone in the United States without paying any fees -or charges. If you are redistributing or providing access to a work -with the phrase "Project Gutenberg" associated with or appearing on the -work, you must comply either with the requirements of paragraphs 1.E.1 -through 1.E.7 or obtain permission for the use of the work and the -Project Gutenberg-tm trademark as set forth in paragraphs 1.E.8 or -1.E.9. - -1.E.3. If an individual Project Gutenberg-tm electronic work is posted -with the permission of the copyright holder, your use and distribution -must comply with both paragraphs 1.E.1 through 1.E.7 and any additional -terms imposed by the copyright holder. Additional terms will be linked -to the Project Gutenberg-tm License for all works posted with the -permission of the copyright holder found at the beginning of this work. - -1.E.4. Do not unlink or detach or remove the full Project Gutenberg-tm -License terms from this work, or any files containing a part of this -work or any other work associated with Project Gutenberg-tm. - -1.E.5. Do not copy, display, perform, distribute or redistribute this -electronic work, or any part of this electronic work, without -prominently displaying the sentence set forth in paragraph 1.E.1 with -active links or immediate access to the full terms of the Project -Gutenberg-tm License. - -1.E.6. You may convert to and distribute this work in any binary, -compressed, marked up, nonproprietary or proprietary form, including any -word processing or hypertext form. However, if you provide access to or -distribute copies of a Project Gutenberg-tm work in a format other than -"Plain Vanilla ASCII" or other format used in the official version -posted on the official Project Gutenberg-tm web site (www.gutenberg.net), -you must, at no additional cost, fee or expense to the user, provide a -copy, a means of exporting a copy, or a means of obtaining a copy upon -request, of the work in its original "Plain Vanilla ASCII" or other -form. Any alternate format must include the full Project Gutenberg-tm -License as specified in paragraph 1.E.1. - -1.E.7. Do not charge a fee for access to, viewing, displaying, -performing, copying or distributing any Project Gutenberg-tm works -unless you comply with paragraph 1.E.8 or 1.E.9. - -1.E.8. You may charge a reasonable fee for copies of or providing -access to or distributing Project Gutenberg-tm electronic works provided -that - -- You pay a royalty fee of 20% of the gross profits you derive from - the use of Project Gutenberg-tm works calculated using the method - you already use to calculate your applicable taxes. The fee is - owed to the owner of the Project Gutenberg-tm trademark, but he - has agreed to donate royalties under this paragraph to the - Project Gutenberg Literary Archive Foundation. Royalty payments - must be paid within 60 days following each date on which you - prepare (or are legally required to prepare) your periodic tax - returns. Royalty payments should be clearly marked as such and - sent to the Project Gutenberg Literary Archive Foundation at the - address specified in Section 4, "Information about donations to - the Project Gutenberg Literary Archive Foundation." - -- You provide a full refund of any money paid by a user who notifies - you in writing (or by e-mail) within 30 days of receipt that s/he - does not agree to the terms of the full Project Gutenberg-tm - License. You must require such a user to return or - destroy all copies of the works possessed in a physical medium - and discontinue all use of and all access to other copies of - Project Gutenberg-tm works. - -- You provide, in accordance with paragraph 1.F.3, a full refund of any - money paid for a work or a replacement copy, if a defect in the - electronic work is discovered and reported to you within 90 days - of receipt of the work. - -- You comply with all other terms of this agreement for free - distribution of Project Gutenberg-tm works. - -1.E.9. If you wish to charge a fee or distribute a Project Gutenberg-tm -electronic work or group of works on different terms than are set -forth in this agreement, you must obtain permission in writing from -both the Project Gutenberg Literary Archive Foundation and Michael -Hart, the owner of the Project Gutenberg-tm trademark. Contact the -Foundation as set forth in Section 3 below. - -1.F. - -1.F.1. Project Gutenberg volunteers and employees expend considerable -effort to identify, do copyright research on, transcribe and proofread -public domain works in creating the Project Gutenberg-tm -collection. Despite these efforts, Project Gutenberg-tm electronic -works, and the medium on which they may be stored, may contain -"Defects," such as, but not limited to, incomplete, inaccurate or -corrupt data, transcription errors, a copyright or other intellectual -property infringement, a defective or damaged disk or other medium, a -computer virus, or computer codes that damage or cannot be read by -your equipment. - -1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the "Right -of Replacement or Refund" described in paragraph 1.F.3, the Project -Gutenberg Literary Archive Foundation, the owner of the Project -Gutenberg-tm trademark, and any other party distributing a Project -Gutenberg-tm electronic work under this agreement, disclaim all -liability to you for damages, costs and expenses, including legal -fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT -LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE -PROVIDED IN PARAGRAPH F3. YOU AGREE THAT THE FOUNDATION, THE -TRADEMARK OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE -LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE OR -INCIDENTAL DAMAGES EVEN IF YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH -DAMAGE. - -1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a -defect in this electronic work within 90 days of receiving it, you can -receive a refund of the money (if any) you paid for it by sending a -written explanation to the person you received the work from. If you -received the work on a physical medium, you must return the medium with -your written explanation. The person or entity that provided you with -the defective work may elect to provide a replacement copy in lieu of a -refund. If you received the work electronically, the person or entity -providing it to you may choose to give you a second opportunity to -receive the work electronically in lieu of a refund. If the second copy -is also defective, you may demand a refund in writing without further -opportunities to fix the problem. - -1.F.4. Except for the limited right of replacement or refund set forth -in paragraph 1.F.3, this work is provided to you 'AS-IS' WITH NO OTHER -WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR ANY PURPOSE. - -1.F.5. Some states do not allow disclaimers of certain implied -warranties or the exclusion or limitation of certain types of damages. -If any disclaimer or limitation set forth in this agreement violates the -law of the state applicable to this agreement, the agreement shall be -interpreted to make the maximum disclaimer or limitation permitted by -the applicable state law. The invalidity or unenforceability of any -provision of this agreement shall not void the remaining provisions. - -1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation, the -trademark owner, any agent or employee of the Foundation, anyone -providing copies of Project Gutenberg-tm electronic works in accordance -with this agreement, and any volunteers associated with the production, -promotion and distribution of Project Gutenberg-tm electronic works, -harmless from all liability, costs and expenses, including legal fees, -that arise directly or indirectly from any of the following which you do -or cause to occur: (a) distribution of this or any Project Gutenberg-tm -work, (b) alteration, modification, or additions or deletions to any -Project Gutenberg-tm work, and (c) any Defect you cause. - - -Section 2. Information about the Mission of Project Gutenberg-tm - -Project Gutenberg-tm is synonymous with the free distribution of -electronic works in formats readable by the widest variety of computers -including obsolete, old, middle-aged and new computers. It exists -because of the efforts of hundreds of volunteers and donations from -people in all walks of life. - -Volunteers and financial support to provide volunteers with the -assistance they need, is critical to reaching Project Gutenberg-tm's -goals and ensuring that the Project Gutenberg-tm collection will -remain freely available for generations to come. In 2001, the Project -Gutenberg Literary Archive Foundation was created to provide a secure -and permanent future for Project Gutenberg-tm and future generations. -To learn more about the Project Gutenberg Literary Archive Foundation -and how your efforts and donations can help, see Sections 3 and 4 -and the Foundation web page at http://www.pglaf.org. - - -Section 3. Information about the Project Gutenberg Literary Archive -Foundation - -The Project Gutenberg Literary Archive Foundation is a non profit -501(c)(3) educational corporation organized under the laws of the -state of Mississippi and granted tax exempt status by the Internal -Revenue Service. The Foundation's EIN or federal tax identification -number is 64-6221541. Its 501(c)(3) letter is posted at -http://pglaf.org/fundraising. Contributions to the Project Gutenberg -Literary Archive Foundation are tax deductible to the full extent -permitted by U.S. federal laws and your state's laws. - -The Foundation's principal office is located at 4557 Melan Dr. S. -Fairbanks, AK, 99712., but its volunteers and employees are scattered -throughout numerous locations. Its business office is located at -809 North 1500 West, Salt Lake City, UT 84116, (801) 596-1887, email -business@pglaf.org. Email contact links and up to date contact -information can be found at the Foundation's web site and official -page at http://pglaf.org - -For additional contact information: - Dr. Gregory B. Newby - Chief Executive and Director - gbnewby@pglaf.org - - -Section 4. Information about Donations to the Project Gutenberg -Literary Archive Foundation - -Project Gutenberg-tm depends upon and cannot survive without wide -spread public support and donations to carry out its mission of -increasing the number of public domain and licensed works that can be -freely distributed in machine readable form accessible by the widest -array of equipment including outdated equipment. Many small donations -($1 to $5,000) are particularly important to maintaining tax exempt -status with the IRS. - -The Foundation is committed to complying with the laws regulating -charities and charitable donations in all 50 states of the United -States. Compliance requirements are not uniform and it takes a -considerable effort, much paperwork and many fees to meet and keep up -with these requirements. We do not solicit donations in locations -where we have not received written confirmation of compliance. To -SEND DONATIONS or determine the status of compliance for any -particular state visit http://pglaf.org - -While we cannot and do not solicit contributions from states where we -have not met the solicitation requirements, we know of no prohibition -against accepting unsolicited donations from donors in such states who -approach us with offers to donate. - -International donations are gratefully accepted, but we cannot make -any statements concerning tax treatment of donations received from -outside the United States. U.S. laws alone swamp our small staff. - -Please check the Project Gutenberg Web pages for current donation -methods and addresses. Donations are accepted in a number of other -ways including including checks, online payments and credit card -donations. To donate, please visit: http://pglaf.org/donate - - -Section 5. General Information About Project Gutenberg-tm electronic -works. - -Professor Michael S. Hart is the originator of the Project Gutenberg-tm -concept of a library of electronic works that could be freely shared -with anyone. For thirty years, he produced and distributed Project -Gutenberg-tm eBooks with only a loose network of volunteer support. - - -Project Gutenberg-tm eBooks are often created from several printed -editions, all of which are confirmed as Public Domain in the U.S. -unless a copyright notice is included. Thus, we do not necessarily -keep eBooks in compliance with any particular paper edition. - - -Most people start at our Web site which has the main PG search facility: - - http://www.gutenberg.net - -This Web site includes information about Project Gutenberg-tm, -including how to make donations to the Project Gutenberg Literary -Archive Foundation, how to help produce our new eBooks, and how to -subscribe to our email newsletter to hear about new eBooks. diff --git a/libgo/go/compress/testdata/gettysburg.txt b/libgo/go/compress/testdata/gettysburg.txt new file mode 100644 index 0000000..2c9bcde --- /dev/null +++ b/libgo/go/compress/testdata/gettysburg.txt @@ -0,0 +1,29 @@ + Four score and seven years ago our fathers brought forth on +this continent, a new nation, conceived in Liberty, and dedicated +to the proposition that all men are created equal. + Now we are engaged in a great Civil War, testing whether that +nation, or any nation so conceived and so dedicated, can long +endure. + We are met on a great battle-field of that war. + We have come to dedicate a portion of that field, as a final +resting place for those who here gave their lives that that +nation might live. It is altogether fitting and proper that +we should do this. + But, in a larger sense, we can not dedicate - we can not +consecrate - we can not hallow - this ground. + The brave men, living and dead, who struggled here, have +consecrated it, far above our poor power to add or detract. +The world will little note, nor long remember what we say here, +but it can never forget what they did here. + It is for us the living, rather, to be dedicated here to the +unfinished work which they who fought here have thus far so +nobly advanced. It is rather for us to be here dedicated to +the great task remaining before us - that from these honored +dead we take increased devotion to that cause for which they +gave the last full measure of devotion - + that we here highly resolve that these dead shall not have +died in vain - that this nation, under God, shall have a new +birth of freedom - and that government of the people, by the +people, for the people, shall not perish from this earth. + +Abraham Lincoln, November 19, 1863, Gettysburg, Pennsylvania diff --git a/libgo/go/compress/zlib/reader.go b/libgo/go/compress/zlib/reader.go index 816f1bf..78ea704 100644 --- a/libgo/go/compress/zlib/reader.go +++ b/libgo/go/compress/zlib/reader.go @@ -101,6 +101,9 @@ func (z *reader) Read(p []byte) (n int, err error) { // Finished file; check checksum. if _, err := io.ReadFull(z.r, z.scratch[0:4]); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } z.err = err return 0, err } @@ -130,6 +133,9 @@ func (z *reader) Reset(r io.Reader, dict []byte) error { } _, err := io.ReadFull(z.r, z.scratch[0:2]) if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } return err } h := uint(z.scratch[0])<<8 | uint(z.scratch[1]) @@ -140,6 +146,9 @@ func (z *reader) Reset(r io.Reader, dict []byte) error { if haveDict { _, err = io.ReadFull(z.r, z.scratch[0:4]) if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } return err } checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3]) diff --git a/libgo/go/compress/zlib/reader_test.go b/libgo/go/compress/zlib/reader_test.go index 218ccba1..449f446 100644 --- a/libgo/go/compress/zlib/reader_test.go +++ b/libgo/go/compress/zlib/reader_test.go @@ -23,6 +23,30 @@ type zlibTest struct { var zlibTests = []zlibTest{ { + "truncated empty", + "", + []byte{}, + nil, + io.ErrUnexpectedEOF, + }, + { + "truncated dict", + "", + []byte{0x78, 0xbb}, + []byte{0x00}, + io.ErrUnexpectedEOF, + }, + { + "truncated checksum", + "", + []byte{0x78, 0xbb, 0x00, 0x01, 0x00, 0x01, 0xca, 0x48, + 0xcd, 0xc9, 0xc9, 0xd7, 0x51, 0x28, 0xcf, 0x2f, + 0xca, 0x49, 0x01, 0x04, 0x00, 0x00, 0xff, 0xff, + }, + []byte{0x00}, + io.ErrUnexpectedEOF, + }, + { "empty", "", []byte{0x78, 0x9c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01}, diff --git a/libgo/go/compress/zlib/writer_test.go b/libgo/go/compress/zlib/writer_test.go index 71ba81a..dd94165 100644 --- a/libgo/go/compress/zlib/writer_test.go +++ b/libgo/go/compress/zlib/writer_test.go @@ -7,6 +7,7 @@ package zlib import ( "bytes" "fmt" + "internal/testenv" "io" "io/ioutil" "os" @@ -14,6 +15,7 @@ import ( ) var filenames = []string{ + "../testdata/gettysburg.txt", "../testdata/e.txt", "../testdata/pi.txt", } @@ -152,22 +154,34 @@ func TestWriter(t *testing.T) { } func TestWriterBig(t *testing.T) { - for _, fn := range filenames { + for i, fn := range filenames { testFileLevelDict(t, fn, DefaultCompression, "") testFileLevelDict(t, fn, NoCompression, "") for level := BestSpeed; level <= BestCompression; level++ { testFileLevelDict(t, fn, level, "") + if level >= 1 && testing.Short() && testenv.Builder() == "" { + break + } + } + if i == 0 && testing.Short() && testenv.Builder() == "" { + break } } } func TestWriterDict(t *testing.T) { const dictionary = "0123456789." - for _, fn := range filenames { + for i, fn := range filenames { testFileLevelDict(t, fn, DefaultCompression, dictionary) testFileLevelDict(t, fn, NoCompression, dictionary) for level := BestSpeed; level <= BestCompression; level++ { testFileLevelDict(t, fn, level, dictionary) + if level >= 1 && testing.Short() && testenv.Builder() == "" { + break + } + } + if i == 0 && testing.Short() && testenv.Builder() == "" { + break } } } @@ -179,10 +193,11 @@ func TestWriterReset(t *testing.T) { testFileLevelDictReset(t, fn, DefaultCompression, nil) testFileLevelDictReset(t, fn, NoCompression, []byte(dictionary)) testFileLevelDictReset(t, fn, DefaultCompression, []byte(dictionary)) - if !testing.Short() { - for level := BestSpeed; level <= BestCompression; level++ { - testFileLevelDictReset(t, fn, level, nil) - } + if testing.Short() { + break + } + for level := BestSpeed; level <= BestCompression; level++ { + testFileLevelDictReset(t, fn, level, nil) } } } |