1*07fb1d06SElliott Hughes // Copyright 2017 The ChromiumOS Authors
2*07fb1d06SElliott Hughes // Use of this source code is governed by a BSD-style license that can be
3*07fb1d06SElliott Hughes // found in the LICENSE file.
4*07fb1d06SElliott Hughes
5*07fb1d06SElliott Hughes #include <algorithm>
6*07fb1d06SElliott Hughes #include <string>
7*07fb1d06SElliott Hughes #include <vector>
8*07fb1d06SElliott Hughes
9*07fb1d06SElliott Hughes #include "gtest/gtest.h"
10*07fb1d06SElliott Hughes
11*07fb1d06SElliott Hughes #include "puffin/memory_stream.h"
12*07fb1d06SElliott Hughes #include "puffin/src/bit_reader.h"
13*07fb1d06SElliott Hughes #include "puffin/src/bit_writer.h"
14*07fb1d06SElliott Hughes #include "puffin/src/include/puffin/common.h"
15*07fb1d06SElliott Hughes #include "puffin/src/include/puffin/huffer.h"
16*07fb1d06SElliott Hughes #include "puffin/src/include/puffin/puffer.h"
17*07fb1d06SElliott Hughes #include "puffin/src/include/puffin/utils.h"
18*07fb1d06SElliott Hughes #include "puffin/src/logging.h"
19*07fb1d06SElliott Hughes #include "puffin/src/puff_reader.h"
20*07fb1d06SElliott Hughes #include "puffin/src/puff_writer.h"
21*07fb1d06SElliott Hughes #include "puffin/src/puffin_stream.h"
22*07fb1d06SElliott Hughes #include "puffin/src/unittest_common.h"
23*07fb1d06SElliott Hughes
24*07fb1d06SElliott Hughes using std::string;
25*07fb1d06SElliott Hughes using std::vector;
26*07fb1d06SElliott Hughes
27*07fb1d06SElliott Hughes namespace puffin {
28*07fb1d06SElliott Hughes
29*07fb1d06SElliott Hughes namespace {
30*07fb1d06SElliott Hughes
31*07fb1d06SElliott Hughes // Uncompressed deflate block.
32*07fb1d06SElliott Hughes const Buffer kRawEmpty = {};
33*07fb1d06SElliott Hughes const Buffer kRaw1 = {0x01};
34*07fb1d06SElliott Hughes const Buffer kRaw2 = {0x01, 0x01};
35*07fb1d06SElliott Hughes const Buffer kRaw5 = {0x01, 0x02, 0x03, 0x04, 0x05};
36*07fb1d06SElliott Hughes
37*07fb1d06SElliott Hughes } // namespace
38*07fb1d06SElliott Hughes
39*07fb1d06SElliott Hughes class PuffinTest : public ::testing::Test {
40*07fb1d06SElliott Hughes public:
41*07fb1d06SElliott Hughes // Utility for decompressing a puff stream.
DecompressPuff(const uint8_t * puff_buf,size_t * puff_size,uint8_t * out_buf,size_t * out_size)42*07fb1d06SElliott Hughes bool DecompressPuff(const uint8_t* puff_buf,
43*07fb1d06SElliott Hughes size_t* puff_size,
44*07fb1d06SElliott Hughes uint8_t* out_buf,
45*07fb1d06SElliott Hughes size_t* out_size) {
46*07fb1d06SElliott Hughes BufferPuffReader puff_reader(static_cast<const uint8_t*>(puff_buf),
47*07fb1d06SElliott Hughes *puff_size);
48*07fb1d06SElliott Hughes auto start = static_cast<uint8_t*>(out_buf);
49*07fb1d06SElliott Hughes
50*07fb1d06SElliott Hughes PuffData pd;
51*07fb1d06SElliott Hughes while (puff_reader.BytesLeft() != 0) {
52*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(puff_reader.GetNext(&pd));
53*07fb1d06SElliott Hughes switch (pd.type) {
54*07fb1d06SElliott Hughes case PuffData::Type::kLiteral:
55*07fb1d06SElliott Hughes *start = pd.byte;
56*07fb1d06SElliott Hughes start++;
57*07fb1d06SElliott Hughes FALLTHROUGH_INTENDED;
58*07fb1d06SElliott Hughes
59*07fb1d06SElliott Hughes case PuffData::Type::kLiterals:
60*07fb1d06SElliott Hughes pd.read_fn(start, pd.length);
61*07fb1d06SElliott Hughes start += pd.length;
62*07fb1d06SElliott Hughes break;
63*07fb1d06SElliott Hughes
64*07fb1d06SElliott Hughes case PuffData::Type::kLenDist: {
65*07fb1d06SElliott Hughes while (pd.length-- > 0) {
66*07fb1d06SElliott Hughes *start = *(start - pd.distance);
67*07fb1d06SElliott Hughes start++;
68*07fb1d06SElliott Hughes }
69*07fb1d06SElliott Hughes break;
70*07fb1d06SElliott Hughes }
71*07fb1d06SElliott Hughes
72*07fb1d06SElliott Hughes case PuffData::Type::kBlockMetadata:
73*07fb1d06SElliott Hughes break;
74*07fb1d06SElliott Hughes
75*07fb1d06SElliott Hughes case PuffData::Type::kEndOfBlock:
76*07fb1d06SElliott Hughes break;
77*07fb1d06SElliott Hughes
78*07fb1d06SElliott Hughes default:
79*07fb1d06SElliott Hughes LOG(ERROR) << "Invalid block data type";
80*07fb1d06SElliott Hughes break;
81*07fb1d06SElliott Hughes }
82*07fb1d06SElliott Hughes }
83*07fb1d06SElliott Hughes *out_size = start - static_cast<uint8_t*>(out_buf);
84*07fb1d06SElliott Hughes *puff_size = *puff_size - puff_reader.BytesLeft();
85*07fb1d06SElliott Hughes return true;
86*07fb1d06SElliott Hughes }
87*07fb1d06SElliott Hughes
PuffDeflate(const uint8_t * comp_buf,size_t comp_size,uint8_t * puff_buf,size_t puff_size) const88*07fb1d06SElliott Hughes bool PuffDeflate(const uint8_t* comp_buf,
89*07fb1d06SElliott Hughes size_t comp_size,
90*07fb1d06SElliott Hughes uint8_t* puff_buf,
91*07fb1d06SElliott Hughes size_t puff_size) const {
92*07fb1d06SElliott Hughes BufferBitReader bit_reader(comp_buf, comp_size);
93*07fb1d06SElliott Hughes BufferPuffWriter puff_writer(puff_buf, puff_size);
94*07fb1d06SElliott Hughes
95*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(
96*07fb1d06SElliott Hughes puffer_.PuffDeflate(&bit_reader, &puff_writer, nullptr));
97*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(comp_size == bit_reader.Offset());
98*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(puff_size == puff_writer.Size());
99*07fb1d06SElliott Hughes return true;
100*07fb1d06SElliott Hughes }
101*07fb1d06SElliott Hughes
HuffDeflate(const uint8_t * puff_buf,size_t puff_size,uint8_t * comp_buf,size_t comp_size) const102*07fb1d06SElliott Hughes bool HuffDeflate(const uint8_t* puff_buf,
103*07fb1d06SElliott Hughes size_t puff_size,
104*07fb1d06SElliott Hughes uint8_t* comp_buf,
105*07fb1d06SElliott Hughes size_t comp_size) const {
106*07fb1d06SElliott Hughes BufferPuffReader puff_reader(puff_buf, puff_size);
107*07fb1d06SElliott Hughes BufferBitWriter bit_writer(comp_buf, comp_size);
108*07fb1d06SElliott Hughes
109*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(huffer_.HuffDeflate(&puff_reader, &bit_writer));
110*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(comp_size == bit_writer.Size());
111*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(puff_reader.BytesLeft() == 0);
112*07fb1d06SElliott Hughes return true;
113*07fb1d06SElliott Hughes }
114*07fb1d06SElliott Hughes
115*07fb1d06SElliott Hughes // Puffs |compressed| into |out_puff| and checks its equality with
116*07fb1d06SElliott Hughes // |expected_puff|.
TestPuffDeflate(const Buffer & compressed,const Buffer & expected_puff,Buffer * out_puff)117*07fb1d06SElliott Hughes void TestPuffDeflate(const Buffer& compressed,
118*07fb1d06SElliott Hughes const Buffer& expected_puff,
119*07fb1d06SElliott Hughes Buffer* out_puff) {
120*07fb1d06SElliott Hughes out_puff->resize(expected_puff.size());
121*07fb1d06SElliott Hughes auto comp_size = compressed.size();
122*07fb1d06SElliott Hughes auto puff_size = out_puff->size();
123*07fb1d06SElliott Hughes ASSERT_TRUE(
124*07fb1d06SElliott Hughes PuffDeflate(compressed.data(), comp_size, out_puff->data(), puff_size));
125*07fb1d06SElliott Hughes ASSERT_EQ(puff_size, expected_puff.size());
126*07fb1d06SElliott Hughes out_puff->resize(puff_size);
127*07fb1d06SElliott Hughes ASSERT_EQ(expected_puff, *out_puff);
128*07fb1d06SElliott Hughes }
129*07fb1d06SElliott Hughes
130*07fb1d06SElliott Hughes // Should fail when trying to puff |compressed|.
FailPuffDeflate(const Buffer & compressed,Buffer * out_puff)131*07fb1d06SElliott Hughes void FailPuffDeflate(const Buffer& compressed, Buffer* out_puff) {
132*07fb1d06SElliott Hughes out_puff->resize(compressed.size() * 2 + 10);
133*07fb1d06SElliott Hughes auto comp_size = compressed.size();
134*07fb1d06SElliott Hughes auto puff_size = out_puff->size();
135*07fb1d06SElliott Hughes ASSERT_FALSE(
136*07fb1d06SElliott Hughes PuffDeflate(compressed.data(), comp_size, out_puff->data(), puff_size));
137*07fb1d06SElliott Hughes }
138*07fb1d06SElliott Hughes
139*07fb1d06SElliott Hughes // Huffs |puffed| into |out_huff| and checks its equality with
140*07fb1d06SElliott Hughes // |expected_huff|.|
TestHuffDeflate(const Buffer & puffed,const Buffer & expected_huff,Buffer * out_huff)141*07fb1d06SElliott Hughes void TestHuffDeflate(const Buffer& puffed,
142*07fb1d06SElliott Hughes const Buffer& expected_huff,
143*07fb1d06SElliott Hughes Buffer* out_huff) {
144*07fb1d06SElliott Hughes out_huff->resize(expected_huff.size());
145*07fb1d06SElliott Hughes auto huff_size = out_huff->size();
146*07fb1d06SElliott Hughes auto puffed_size = puffed.size();
147*07fb1d06SElliott Hughes ASSERT_TRUE(
148*07fb1d06SElliott Hughes HuffDeflate(puffed.data(), puffed_size, out_huff->data(), huff_size));
149*07fb1d06SElliott Hughes ASSERT_EQ(expected_huff, *out_huff);
150*07fb1d06SElliott Hughes }
151*07fb1d06SElliott Hughes
152*07fb1d06SElliott Hughes // Should fail while huffing |puffed|
FailHuffDeflate(const Buffer & puffed,Buffer * out_compress)153*07fb1d06SElliott Hughes void FailHuffDeflate(const Buffer& puffed, Buffer* out_compress) {
154*07fb1d06SElliott Hughes out_compress->resize(puffed.size());
155*07fb1d06SElliott Hughes auto comp_size = out_compress->size();
156*07fb1d06SElliott Hughes auto puff_size = puffed.size();
157*07fb1d06SElliott Hughes ASSERT_TRUE(
158*07fb1d06SElliott Hughes HuffDeflate(puffed.data(), puff_size, out_compress->data(), comp_size));
159*07fb1d06SElliott Hughes }
160*07fb1d06SElliott Hughes
161*07fb1d06SElliott Hughes // Decompresses from |puffed| into |uncompress| and checks its equality with
162*07fb1d06SElliott Hughes // |original|.
Decompress(const Buffer & puffed,const Buffer & original,Buffer * uncompress)163*07fb1d06SElliott Hughes void Decompress(const Buffer& puffed,
164*07fb1d06SElliott Hughes const Buffer& original,
165*07fb1d06SElliott Hughes Buffer* uncompress) {
166*07fb1d06SElliott Hughes uncompress->resize(original.size());
167*07fb1d06SElliott Hughes auto uncomp_size = uncompress->size();
168*07fb1d06SElliott Hughes auto puffed_size = puffed.size();
169*07fb1d06SElliott Hughes ASSERT_TRUE(DecompressPuff(puffed.data(), &puffed_size, uncompress->data(),
170*07fb1d06SElliott Hughes &uncomp_size));
171*07fb1d06SElliott Hughes ASSERT_EQ(puffed_size, puffed.size());
172*07fb1d06SElliott Hughes ASSERT_EQ(uncomp_size, original.size());
173*07fb1d06SElliott Hughes uncompress->resize(uncomp_size);
174*07fb1d06SElliott Hughes ASSERT_EQ(original, *uncompress);
175*07fb1d06SElliott Hughes }
176*07fb1d06SElliott Hughes
CheckSample(const Buffer original,const Buffer compressed,const Buffer puffed)177*07fb1d06SElliott Hughes void CheckSample(const Buffer original,
178*07fb1d06SElliott Hughes const Buffer compressed,
179*07fb1d06SElliott Hughes const Buffer puffed) {
180*07fb1d06SElliott Hughes Buffer puff, uncompress, huff;
181*07fb1d06SElliott Hughes TestPuffDeflate(compressed, puffed, &puff);
182*07fb1d06SElliott Hughes TestHuffDeflate(puffed, compressed, &huff);
183*07fb1d06SElliott Hughes Decompress(puffed, original, &uncompress);
184*07fb1d06SElliott Hughes }
185*07fb1d06SElliott Hughes
CheckBitExtentsPuffAndHuff(const Buffer & deflate_buffer,const vector<BitExtent> & deflate_extents,const Buffer & puff_buffer,const vector<ByteExtent> & puff_extents)186*07fb1d06SElliott Hughes void CheckBitExtentsPuffAndHuff(const Buffer& deflate_buffer,
187*07fb1d06SElliott Hughes const vector<BitExtent>& deflate_extents,
188*07fb1d06SElliott Hughes const Buffer& puff_buffer,
189*07fb1d06SElliott Hughes const vector<ByteExtent>& puff_extents) {
190*07fb1d06SElliott Hughes auto puffer = std::make_shared<Puffer>();
191*07fb1d06SElliott Hughes auto deflate_stream = MemoryStream::CreateForRead(deflate_buffer);
192*07fb1d06SElliott Hughes ASSERT_TRUE(deflate_stream->Seek(0));
193*07fb1d06SElliott Hughes vector<ByteExtent> out_puff_extents;
194*07fb1d06SElliott Hughes uint64_t puff_size;
195*07fb1d06SElliott Hughes ASSERT_TRUE(FindPuffLocations(deflate_stream, deflate_extents,
196*07fb1d06SElliott Hughes &out_puff_extents, &puff_size));
197*07fb1d06SElliott Hughes EXPECT_EQ(puff_size, puff_buffer.size());
198*07fb1d06SElliott Hughes EXPECT_EQ(out_puff_extents, puff_extents);
199*07fb1d06SElliott Hughes
200*07fb1d06SElliott Hughes auto src_puffin_stream =
201*07fb1d06SElliott Hughes PuffinStream::CreateForPuff(std::move(deflate_stream), puffer,
202*07fb1d06SElliott Hughes puff_size, deflate_extents, puff_extents);
203*07fb1d06SElliott Hughes
204*07fb1d06SElliott Hughes Buffer out_puff_buffer(puff_buffer.size());
205*07fb1d06SElliott Hughes ASSERT_TRUE(src_puffin_stream->Read(out_puff_buffer.data(),
206*07fb1d06SElliott Hughes out_puff_buffer.size()));
207*07fb1d06SElliott Hughes EXPECT_EQ(out_puff_buffer, puff_buffer);
208*07fb1d06SElliott Hughes
209*07fb1d06SElliott Hughes auto huffer = std::make_shared<Huffer>();
210*07fb1d06SElliott Hughes Buffer out_deflate_buffer;
211*07fb1d06SElliott Hughes deflate_stream = MemoryStream::CreateForWrite(&out_deflate_buffer);
212*07fb1d06SElliott Hughes
213*07fb1d06SElliott Hughes src_puffin_stream =
214*07fb1d06SElliott Hughes PuffinStream::CreateForHuff(std::move(deflate_stream), huffer,
215*07fb1d06SElliott Hughes puff_size, deflate_extents, puff_extents);
216*07fb1d06SElliott Hughes
217*07fb1d06SElliott Hughes ASSERT_TRUE(
218*07fb1d06SElliott Hughes src_puffin_stream->Write(puff_buffer.data(), puff_buffer.size()));
219*07fb1d06SElliott Hughes EXPECT_EQ(out_deflate_buffer, deflate_buffer);
220*07fb1d06SElliott Hughes }
221*07fb1d06SElliott Hughes
222*07fb1d06SElliott Hughes protected:
223*07fb1d06SElliott Hughes Puffer puffer_;
224*07fb1d06SElliott Hughes Huffer huffer_;
225*07fb1d06SElliott Hughes };
226*07fb1d06SElliott Hughes
227*07fb1d06SElliott Hughes // Tests a simple buffer with uncompressed deflate block.
TEST_F(PuffinTest,UncompressedTest)228*07fb1d06SElliott Hughes TEST_F(PuffinTest, UncompressedTest) {
229*07fb1d06SElliott Hughes const Buffer kDeflate = {0x01, 0x05, 0x00, 0xFA, 0xFF,
230*07fb1d06SElliott Hughes 0x01, 0x02, 0x03, 0x04, 0x05};
231*07fb1d06SElliott Hughes const Buffer kPuff = {0x00, 0x00, 0x80, 0x04, 0x01, 0x02,
232*07fb1d06SElliott Hughes 0x03, 0x04, 0x05, 0xFF, 0x81};
233*07fb1d06SElliott Hughes CheckSample(kRaw5, kDeflate, kPuff);
234*07fb1d06SElliott Hughes }
235*07fb1d06SElliott Hughes
236*07fb1d06SElliott Hughes // Tests a simple buffer with uncompressed deflate block with length zero.
TEST_F(PuffinTest,ZeroLengthUncompressedTest)237*07fb1d06SElliott Hughes TEST_F(PuffinTest, ZeroLengthUncompressedTest) {
238*07fb1d06SElliott Hughes const Buffer kDeflate = {0x01, 0x00, 0x00, 0xFF, 0xFF};
239*07fb1d06SElliott Hughes const Buffer kPuff = {0x00, 0x00, 0x80, 0xFF, 0x81};
240*07fb1d06SElliott Hughes CheckSample(kRawEmpty, kDeflate, kPuff);
241*07fb1d06SElliott Hughes }
242*07fb1d06SElliott Hughes
243*07fb1d06SElliott Hughes // Tests a Fixed Huffman table compressed buffer with only one literal.
TEST_F(PuffinTest,OneLiteralFixedHuffmanTableTest)244*07fb1d06SElliott Hughes TEST_F(PuffinTest, OneLiteralFixedHuffmanTableTest) {
245*07fb1d06SElliott Hughes const Buffer kDeflate = {0x63, 0x04, 0x00};
246*07fb1d06SElliott Hughes const Buffer kPuff = {0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81};
247*07fb1d06SElliott Hughes CheckSample(kRaw1, kDeflate, kPuff);
248*07fb1d06SElliott Hughes }
249*07fb1d06SElliott Hughes
250*07fb1d06SElliott Hughes // Tests deflate of an empty buffer.
TEST_F(PuffinTest,EmptyTest)251*07fb1d06SElliott Hughes TEST_F(PuffinTest, EmptyTest) {
252*07fb1d06SElliott Hughes const Buffer kDeflate = {0x03, 0x00};
253*07fb1d06SElliott Hughes const Buffer kPuff = {0x00, 0x00, 0xA0, 0xFF, 0x81};
254*07fb1d06SElliott Hughes CheckSample(kRawEmpty, kDeflate, kPuff);
255*07fb1d06SElliott Hughes }
256*07fb1d06SElliott Hughes
257*07fb1d06SElliott Hughes // Tests a simple buffer with compress deflate block using fixed Huffman table.
TEST_F(PuffinTest,FixedHuffmanTableCompressedTest)258*07fb1d06SElliott Hughes TEST_F(PuffinTest, FixedHuffmanTableCompressedTest) {
259*07fb1d06SElliott Hughes const Buffer kDeflate = {0x63, 0x64, 0x62, 0x66, 0x61, 0x05, 0x00};
260*07fb1d06SElliott Hughes const Buffer kPuff = {0x00, 0x00, 0xA0, 0x04, 0x01, 0x02,
261*07fb1d06SElliott Hughes 0x03, 0x04, 0x05, 0xFF, 0x81};
262*07fb1d06SElliott Hughes CheckSample(kRaw5, kDeflate, kPuff);
263*07fb1d06SElliott Hughes }
264*07fb1d06SElliott Hughes
265*07fb1d06SElliott Hughes // Tests that uncompressed deflate blocks are not ignored when the output
266*07fb1d06SElliott Hughes // deflate location pointer is null.
TEST_F(PuffinTest,NoIgnoreUncompressedBlocksTest)267*07fb1d06SElliott Hughes TEST_F(PuffinTest, NoIgnoreUncompressedBlocksTest) {
268*07fb1d06SElliott Hughes const Buffer kDeflate = {0x01, 0x05, 0x00, 0xFA, 0xFF,
269*07fb1d06SElliott Hughes 0x01, 0x02, 0x03, 0x04, 0x05};
270*07fb1d06SElliott Hughes BufferBitReader bit_reader(kDeflate.data(), kDeflate.size());
271*07fb1d06SElliott Hughes Buffer puff_buffer(11); // Same size as |uncomp_puff| below.
272*07fb1d06SElliott Hughes BufferPuffWriter puff_writer(puff_buffer.data(), puff_buffer.size());
273*07fb1d06SElliott Hughes vector<BitExtent> deflates;
274*07fb1d06SElliott Hughes EXPECT_TRUE(puffer_.PuffDeflate(&bit_reader, &puff_writer, nullptr));
275*07fb1d06SElliott Hughes const Buffer kPuff = {0x00, 0x00, 0x80, 0x04, 0x01, 0x02,
276*07fb1d06SElliott Hughes 0x03, 0x04, 0x05, 0xFF, 0x81};
277*07fb1d06SElliott Hughes EXPECT_EQ(puff_writer.Size(), kPuff.size());
278*07fb1d06SElliott Hughes EXPECT_EQ(puff_buffer, kPuff);
279*07fb1d06SElliott Hughes }
280*07fb1d06SElliott Hughes
281*07fb1d06SElliott Hughes // Tests that uncompressed deflate blocks are ignored when the output
282*07fb1d06SElliott Hughes // deflate location pointer is valid.
TEST_F(PuffinTest,IgnoreUncompressedBlocksTest)283*07fb1d06SElliott Hughes TEST_F(PuffinTest, IgnoreUncompressedBlocksTest) {
284*07fb1d06SElliott Hughes const Buffer kDeflate = {0x01, 0x05, 0x00, 0xFA, 0xFF,
285*07fb1d06SElliott Hughes 0x01, 0x02, 0x03, 0x04, 0x05};
286*07fb1d06SElliott Hughes BufferBitReader bit_reader(kDeflate.data(), kDeflate.size());
287*07fb1d06SElliott Hughes BufferPuffWriter puff_writer(nullptr, 0);
288*07fb1d06SElliott Hughes vector<BitExtent> deflates;
289*07fb1d06SElliott Hughes EXPECT_TRUE(puffer_.PuffDeflate(&bit_reader, &puff_writer, &deflates));
290*07fb1d06SElliott Hughes EXPECT_TRUE(deflates.empty());
291*07fb1d06SElliott Hughes }
292*07fb1d06SElliott Hughes
293*07fb1d06SElliott Hughes namespace {
294*07fb1d06SElliott Hughes // It is actuall the content of the copyright header.
295*07fb1d06SElliott Hughes const Buffer kDynamicHTRaw = {
296*07fb1d06SElliott Hughes 0x0A, 0x2F, 0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x43, 0x6F, 0x70, 0x79, 0x72,
297*07fb1d06SElliott Hughes 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x31,
298*07fb1d06SElliott Hughes 0x37, 0x20, 0x54, 0x68, 0x65, 0x20, 0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69,
299*07fb1d06SElliott Hughes 0x64, 0x20, 0x4F, 0x70, 0x65, 0x6E, 0x20, 0x53, 0x6F, 0x75, 0x72, 0x63,
300*07fb1d06SElliott Hughes 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x0A, 0x2F, 0x2F,
301*07fb1d06SElliott Hughes 0x0A, 0x2F, 0x2F, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x64,
302*07fb1d06SElliott Hughes 0x20, 0x75, 0x6E, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x41,
303*07fb1d06SElliott Hughes 0x70, 0x61, 0x63, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73,
304*07fb1d06SElliott Hughes 0x65, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x32,
305*07fb1d06SElliott Hughes 0x2E, 0x30, 0x20, 0x28, 0x74, 0x68, 0x65, 0x20, 0x22, 0x4C, 0x69, 0x63,
306*07fb1d06SElliott Hughes 0x65, 0x6E, 0x73, 0x65, 0x22, 0x29, 0x3B, 0x0A, 0x2F, 0x2F, 0x20, 0x79,
307*07fb1d06SElliott Hughes 0x6F, 0x75, 0x20, 0x6D, 0x61, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x75,
308*07fb1d06SElliott Hughes 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6C, 0x65,
309*07fb1d06SElliott Hughes 0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x69, 0x6E, 0x20, 0x63,
310*07fb1d06SElliott Hughes 0x6F, 0x6D, 0x70, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x20, 0x77, 0x69,
311*07fb1d06SElliott Hughes 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E,
312*07fb1d06SElliott Hughes 0x73, 0x65, 0x2E, 0x0A, 0x2F, 0x2F, 0x20, 0x59, 0x6F, 0x75, 0x20, 0x6D,
313*07fb1d06SElliott Hughes 0x61, 0x79, 0x20, 0x6F, 0x62, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x61, 0x20,
314*07fb1d06SElliott Hughes 0x63, 0x6F, 0x70, 0x79, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
315*07fb1d06SElliott Hughes 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x20, 0x61, 0x74, 0x0A, 0x2F,
316*07fb1d06SElliott Hughes 0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x74,
317*07fb1d06SElliott Hughes 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x61, 0x70, 0x61,
318*07fb1d06SElliott Hughes 0x63, 0x68, 0x65, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x6C, 0x69, 0x63, 0x65,
319*07fb1d06SElliott Hughes 0x6E, 0x73, 0x65, 0x73, 0x2F, 0x4C, 0x49, 0x43, 0x45, 0x4E, 0x53, 0x45,
320*07fb1d06SElliott Hughes 0x2D, 0x32, 0x2E, 0x30, 0x0A, 0x2F, 0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x55,
321*07fb1d06SElliott Hughes 0x6E, 0x6C, 0x65, 0x73, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
322*07fb1d06SElliott Hughes 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63,
323*07fb1d06SElliott Hughes 0x61, 0x62, 0x6C, 0x65, 0x20, 0x6C, 0x61, 0x77, 0x20, 0x6F, 0x72, 0x20,
324*07fb1d06SElliott Hughes 0x61, 0x67, 0x72, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x69, 0x6E,
325*07fb1d06SElliott Hughes 0x20, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6E, 0x67, 0x2C, 0x20, 0x73, 0x6F,
326*07fb1d06SElliott Hughes 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0A, 0x2F, 0x2F, 0x20, 0x64, 0x69,
327*07fb1d06SElliott Hughes 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x20, 0x75, 0x6E,
328*07fb1d06SElliott Hughes 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65,
329*07fb1d06SElliott Hughes 0x6E, 0x73, 0x65, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x74, 0x72,
330*07fb1d06SElliott Hughes 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x6E,
331*07fb1d06SElliott Hughes 0x20, 0x22, 0x41, 0x53, 0x20, 0x49, 0x53, 0x22, 0x20, 0x42, 0x41, 0x53,
332*07fb1d06SElliott Hughes 0x49, 0x53, 0x2C, 0x0A, 0x2F, 0x2F, 0x20, 0x57, 0x49, 0x54, 0x48, 0x4F,
333*07fb1d06SElliott Hughes 0x55, 0x54, 0x20, 0x57, 0x41, 0x52, 0x52, 0x41, 0x4E, 0x54, 0x49, 0x45,
334*07fb1d06SElliott Hughes 0x53, 0x20, 0x4F, 0x52, 0x20, 0x43, 0x4F, 0x4E, 0x44, 0x49, 0x54, 0x49,
335*07fb1d06SElliott Hughes 0x4F, 0x4E, 0x53, 0x20, 0x4F, 0x46, 0x20, 0x41, 0x4E, 0x59, 0x20, 0x4B,
336*07fb1d06SElliott Hughes 0x49, 0x4E, 0x44, 0x2C, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20,
337*07fb1d06SElliott Hughes 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6F, 0x72, 0x20, 0x69,
338*07fb1d06SElliott Hughes 0x6D, 0x70, 0x6C, 0x69, 0x65, 0x64, 0x2E, 0x0A, 0x2F, 0x2F, 0x20, 0x53,
339*07fb1d06SElliott Hughes 0x65, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E,
340*07fb1d06SElliott Hughes 0x73, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
341*07fb1d06SElliott Hughes 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x6C, 0x61, 0x6E, 0x67,
342*07fb1d06SElliott Hughes 0x75, 0x61, 0x67, 0x65, 0x20, 0x67, 0x6F, 0x76, 0x65, 0x72, 0x6E, 0x69,
343*07fb1d06SElliott Hughes 0x6E, 0x67, 0x20, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F,
344*07fb1d06SElliott Hughes 0x6E, 0x73, 0x20, 0x61, 0x6E, 0x64, 0x0A, 0x2F, 0x2F, 0x20, 0x6C, 0x69,
345*07fb1d06SElliott Hughes 0x6D, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x75, 0x6E,
346*07fb1d06SElliott Hughes 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65,
347*07fb1d06SElliott Hughes 0x6E, 0x73, 0x65, 0x2E, 0x0A};
348*07fb1d06SElliott Hughes
349*07fb1d06SElliott Hughes // Dynamic huffman compressed deflate.
350*07fb1d06SElliott Hughes const Buffer kDynamicHTDeflate = {
351*07fb1d06SElliott Hughes 0x65, 0x91, 0x41, 0x6F, 0x9C, 0x30, 0x10, 0x85, 0xEF, 0xFB, 0x2B, 0x9E,
352*07fb1d06SElliott Hughes 0xF6, 0x94, 0x48, 0x5B, 0x48, 0x73, 0xA9, 0xD4, 0x9E, 0xE8, 0x66, 0xAB,
353*07fb1d06SElliott Hughes 0xA0, 0x46, 0x50, 0x2D, 0xA4, 0x51, 0x8E, 0x5E, 0x18, 0xD8, 0x89, 0x58,
354*07fb1d06SElliott Hughes 0xDB, 0xB5, 0x4D, 0xC9, 0xFE, 0xFB, 0x8E, 0x59, 0x22, 0x25, 0xAA, 0x2F,
355*07fb1d06SElliott Hughes 0xC8, 0xCC, 0xCC, 0x9B, 0xEF, 0x3D, 0xAF, 0xD2, 0x74, 0x95, 0xA6, 0xD8,
356*07fb1d06SElliott Hughes 0x1A, 0x7B, 0x76, 0xDC, 0x1F, 0x03, 0xAE, 0xB6, 0xD7, 0xB8, 0xBD, 0xF9,
357*07fb1d06SElliott Hughes 0xFC, 0x05, 0xF5, 0x91, 0x90, 0xE9, 0xD6, 0x19, 0x6E, 0x51, 0x5A, 0xD2,
358*07fb1d06SElliott Hughes 0xA8, 0xCC, 0xE8, 0x1A, 0xC2, 0x2F, 0x67, 0x5E, 0xA8, 0x09, 0xAB, 0xCB,
359*07fb1d06SElliott Hughes 0xE0, 0x03, 0x37, 0xA4, 0x3D, 0xB5, 0x18, 0x75, 0x4B, 0x0E, 0x21, 0x0E,
360*07fb1d06SElliott Hughes 0x59, 0xD5, 0xC8, 0x67, 0xA9, 0x6C, 0xF0, 0x9B, 0x9C, 0x67, 0xA3, 0x71,
361*07fb1d06SElliott Hughes 0x9B, 0xDC, 0xE0, 0x2A, 0x36, 0xAC, 0x97, 0xD2, 0xFA, 0xFA, 0x5B, 0x94,
362*07fb1d06SElliott Hughes 0x38, 0x9B, 0x11, 0x27, 0x75, 0x86, 0x36, 0x01, 0xA3, 0x27, 0xD1, 0x60,
363*07fb1d06SElliott Hughes 0x8F, 0x8E, 0x07, 0x02, 0xBD, 0x36, 0x64, 0x03, 0x58, 0xA3, 0x31, 0x27,
364*07fb1d06SElliott Hughes 0x3B, 0xB0, 0xD2, 0xB2, 0x7F, 0xE2, 0x70, 0x9C, 0xF7, 0x2C, 0x2A, 0x49,
365*07fb1d06SElliott Hughes 0xD4, 0x78, 0x5E, 0x34, 0xCC, 0x21, 0x28, 0x69, 0x57, 0x32, 0x60, 0xE5,
366*07fb1d06SElliott Hughes 0xD6, 0xBD, 0x6F, 0x84, 0x7A, 0x83, 0x9E, 0xCF, 0x31, 0x04, 0xFB, 0x35,
367*07fb1d06SElliott Hughes 0x4D, 0xA7, 0x69, 0x4A, 0xD4, 0x4C, 0x9C, 0x18, 0xD7, 0xA7, 0xC3, 0xA5,
368*07fb1d06SElliott Hughes 0xD7, 0xA7, 0x0F, 0xF9, 0x76, 0x57, 0x54, 0xBB, 0x4F, 0x42, 0xBD, 0x4C,
369*07fb1d06SElliott Hughes 0x3D, 0xEA, 0x81, 0xBC, 0x87, 0xA3, 0x3F, 0x23, 0x3B, 0x71, 0x7C, 0x38,
370*07fb1d06SElliott Hughes 0x43, 0x59, 0xA1, 0x6A, 0xD4, 0x41, 0x58, 0x07, 0x35, 0xC1, 0x38, 0xA8,
371*07fb1d06SElliott Hughes 0xDE, 0x91, 0xD4, 0x82, 0x89, 0xD4, 0x93, 0xE3, 0xC0, 0xBA, 0xDF, 0xC0,
372*07fb1d06SElliott Hughes 0x9B, 0x2E, 0x4C, 0xCA, 0x51, 0x94, 0x69, 0xD9, 0x07, 0xC7, 0x87, 0x31,
373*07fb1d06SElliott Hughes 0x7C, 0x08, 0xED, 0x8D, 0x51, 0xAC, 0xBF, 0x6F, 0x90, 0xD8, 0x94, 0xC6,
374*07fb1d06SElliott Hughes 0x3A, 0xAB, 0x90, 0x57, 0x6B, 0x7C, 0xCF, 0xAA, 0xBC, 0xDA, 0x44, 0x91,
375*07fb1d06SElliott Hughes 0xA7, 0xBC, 0xBE, 0x2F, 0x1F, 0x6B, 0x3C, 0x65, 0xFB, 0x7D, 0x56, 0xD4,
376*07fb1d06SElliott Hughes 0xF9, 0xAE, 0x42, 0xB9, 0xC7, 0xB6, 0x2C, 0xEE, 0xF2, 0x3A, 0x2F, 0x0B,
377*07fb1d06SElliott Hughes 0xB9, 0xFD, 0x40, 0x56, 0x3C, 0xE3, 0x67, 0x5E, 0xDC, 0x6D, 0x40, 0x12,
378*07fb1d06SElliott Hughes 0x99, 0xEC, 0xA1, 0x57, 0xEB, 0xA2, 0x03, 0xC1, 0xE4, 0x18, 0x27, 0xB5,
379*07fb1d06SElliott Hughes 0x73, 0x76, 0x15, 0xD1, 0x07, 0x84, 0xCE, 0x5C, 0x90, 0xBC, 0xA5, 0x86,
380*07fb1d06SElliott Hughes 0x3B, 0x6E, 0xC4, 0x9A, 0xEE, 0x47, 0xD5, 0x13, 0x7A, 0xF3, 0x97, 0x9C,
381*07fb1d06SElliott Hughes 0x16, 0x47, 0xB0, 0xE4, 0x4E, 0xEC, 0xE3, 0xB3, 0x7A, 0x01, 0x6C, 0xA3,
382*07fb1d06SElliott Hughes 0xCC, 0xC0, 0x27, 0x0E, 0x2A, 0xCC, 0xBF, 0xFE, 0xF3, 0x95, 0xAC, 0xFE,
383*07fb1d06SElliott Hughes 0x01};
384*07fb1d06SElliott Hughes
385*07fb1d06SElliott Hughes const Buffer kDynamicHTPuff = {
386*07fb1d06SElliott Hughes 0x00, 0x74, 0xC0, 0x0C, 0x11, 0x0C, 0x04, 0x63, 0x34, 0x32, 0x03, 0x04,
387*07fb1d06SElliott Hughes 0x05, 0x06, 0x1B, 0x07, 0x26, 0x03, 0x00, 0x07, 0x16, 0x08, 0x08, 0x00,
388*07fb1d06SElliott Hughes 0x00, 0x07, 0x09, 0x06, 0x06, 0x08, 0x09, 0x08, 0x15, 0x09, 0x00, 0x00,
389*07fb1d06SElliott Hughes 0x09, 0x09, 0x16, 0x06, 0x09, 0x07, 0x08, 0x07, 0x09, 0x00, 0x08, 0x06,
390*07fb1d06SElliott Hughes 0x00, 0x09, 0x08, 0x00, 0x06, 0x06, 0x09, 0x00, 0x07, 0x06, 0x06, 0x08,
391*07fb1d06SElliott Hughes 0x09, 0x08, 0x00, 0x08, 0x18, 0x05, 0x07, 0x06, 0x06, 0x04, 0x06, 0x06,
392*07fb1d06SElliott Hughes 0x07, 0x04, 0x08, 0x00, 0x06, 0x07, 0x05, 0x05, 0x05, 0x09, 0x05, 0x05,
393*07fb1d06SElliott Hughes 0x05, 0x06, 0x09, 0x06, 0x08, 0x07, 0x97, 0x09, 0x04, 0x05, 0x06, 0x07,
394*07fb1d06SElliott Hughes 0x06, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x09, 0x05, 0x15, 0x06, 0x00,
395*07fb1d06SElliott Hughes 0x05, 0x06, 0x04, 0x04, 0x04, 0x03, 0x04, 0x02, 0x03, 0x03, 0x05, 0x39,
396*07fb1d06SElliott Hughes 0x0A, 0x2F, 0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x43, 0x6F, 0x70, 0x79, 0x72,
397*07fb1d06SElliott Hughes 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x31,
398*07fb1d06SElliott Hughes 0x37, 0x20, 0x54, 0x68, 0x65, 0x20, 0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69,
399*07fb1d06SElliott Hughes 0x64, 0x20, 0x4F, 0x70, 0x65, 0x6E, 0x20, 0x53, 0x6F, 0x75, 0x72, 0x63,
400*07fb1d06SElliott Hughes 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x0A, 0x83, 0x00,
401*07fb1d06SElliott Hughes 0x38, 0x0F, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x64, 0x20, 0x75,
402*07fb1d06SElliott Hughes 0x6E, 0x64, 0x65, 0x72, 0x20, 0x74, 0x81, 0x00, 0x34, 0x02, 0x70, 0x61,
403*07fb1d06SElliott Hughes 0x63, 0x80, 0x00, 0x06, 0x84, 0x00, 0x19, 0x0E, 0x2C, 0x20, 0x56, 0x65,
404*07fb1d06SElliott Hughes 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x32, 0x2E, 0x30, 0x20, 0x28, 0x81,
405*07fb1d06SElliott Hughes 0x00, 0x20, 0x00, 0x22, 0x84, 0x00, 0x1A, 0x02, 0x22, 0x29, 0x3B, 0x81,
406*07fb1d06SElliott Hughes 0x00, 0x42, 0x0E, 0x79, 0x6F, 0x75, 0x20, 0x6D, 0x61, 0x79, 0x20, 0x6E,
407*07fb1d06SElliott Hughes 0x6F, 0x74, 0x20, 0x75, 0x73, 0x65, 0x80, 0x00, 0x43, 0x19, 0x69, 0x73,
408*07fb1d06SElliott Hughes 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74,
409*07fb1d06SElliott Hughes 0x20, 0x69, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x70, 0x6C, 0x69, 0x61, 0x6E,
410*07fb1d06SElliott Hughes 0x80, 0x00, 0x7F, 0x03, 0x77, 0x69, 0x74, 0x68, 0x82, 0x00, 0x67, 0x84,
411*07fb1d06SElliott Hughes 0x00, 0x45, 0x00, 0x2E, 0x81, 0x00, 0x43, 0x00, 0x59, 0x84, 0x00, 0x43,
412*07fb1d06SElliott Hughes 0x03, 0x6F, 0x62, 0x74, 0x61, 0x80, 0x00, 0x2E, 0x00, 0x61, 0x80, 0x00,
413*07fb1d06SElliott Hughes 0x30, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x66, 0x89, 0x00, 0x28, 0x01,
414*07fb1d06SElliott Hughes 0x20, 0x61, 0x85, 0x00, 0xB4, 0x82, 0x00, 0x00, 0x0B, 0x68, 0x74, 0x74,
415*07fb1d06SElliott Hughes 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x61, 0x82, 0x00, 0xB1,
416*07fb1d06SElliott Hughes 0x05, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x6C, 0x83, 0x00, 0x2B, 0x09, 0x73,
417*07fb1d06SElliott Hughes 0x2F, 0x4C, 0x49, 0x43, 0x45, 0x4E, 0x53, 0x45, 0x2D, 0x80, 0x00, 0xB5,
418*07fb1d06SElliott Hughes 0x84, 0x00, 0x35, 0x0C, 0x55, 0x6E, 0x6C, 0x65, 0x73, 0x73, 0x20, 0x72,
419*07fb1d06SElliott Hughes 0x65, 0x71, 0x75, 0x69, 0x72, 0x80, 0x00, 0xF1, 0x04, 0x62, 0x79, 0x20,
420*07fb1d06SElliott Hughes 0x61, 0x70, 0x80, 0x00, 0x95, 0x02, 0x63, 0x61, 0x62, 0x80, 0x00, 0xAB,
421*07fb1d06SElliott Hughes 0x0A, 0x6C, 0x61, 0x77, 0x20, 0x6F, 0x72, 0x20, 0x61, 0x67, 0x72, 0x65,
422*07fb1d06SElliott Hughes 0x80, 0x00, 0x1B, 0x01, 0x74, 0x6F, 0x81, 0x00, 0xB5, 0x10, 0x77, 0x72,
423*07fb1d06SElliott Hughes 0x69, 0x74, 0x69, 0x6E, 0x67, 0x2C, 0x20, 0x73, 0x6F, 0x66, 0x74, 0x77,
424*07fb1d06SElliott Hughes 0x61, 0x72, 0x65, 0x81, 0x00, 0x46, 0x08, 0x64, 0x69, 0x73, 0x74, 0x72,
425*07fb1d06SElliott Hughes 0x69, 0x62, 0x75, 0x74, 0x8A, 0x01, 0x34, 0x85, 0x00, 0xA3, 0x80, 0x00,
426*07fb1d06SElliott Hughes 0xFA, 0x89, 0x00, 0x20, 0x80, 0x01, 0x36, 0x10, 0x61, 0x6E, 0x20, 0x22,
427*07fb1d06SElliott Hughes 0x41, 0x53, 0x20, 0x49, 0x53, 0x22, 0x20, 0x42, 0x41, 0x53, 0x49, 0x53,
428*07fb1d06SElliott Hughes 0x2C, 0x81, 0x00, 0x44, 0x1E, 0x57, 0x49, 0x54, 0x48, 0x4F, 0x55, 0x54,
429*07fb1d06SElliott Hughes 0x20, 0x57, 0x41, 0x52, 0x52, 0x41, 0x4E, 0x54, 0x49, 0x45, 0x53, 0x20,
430*07fb1d06SElliott Hughes 0x4F, 0x52, 0x20, 0x43, 0x4F, 0x4E, 0x44, 0x49, 0x54, 0x49, 0x4F, 0x4E,
431*07fb1d06SElliott Hughes 0x80, 0x00, 0x0D, 0x0C, 0x46, 0x20, 0x41, 0x4E, 0x59, 0x20, 0x4B, 0x49,
432*07fb1d06SElliott Hughes 0x4E, 0x44, 0x2C, 0x20, 0x65, 0x80, 0x01, 0x32, 0x80, 0x00, 0x67, 0x03,
433*07fb1d06SElliott Hughes 0x65, 0x78, 0x70, 0x72, 0x81, 0x00, 0xC1, 0x80, 0x00, 0xA6, 0x00, 0x69,
434*07fb1d06SElliott Hughes 0x81, 0x01, 0x4E, 0x01, 0x65, 0x64, 0x82, 0x01, 0x3B, 0x02, 0x53, 0x65,
435*07fb1d06SElliott Hughes 0x65, 0x8A, 0x00, 0x82, 0x01, 0x66, 0x6F, 0x83, 0x00, 0x92, 0x07, 0x73,
436*07fb1d06SElliott Hughes 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x80, 0x00, 0xDA, 0x0C, 0x6E,
437*07fb1d06SElliott Hughes 0x67, 0x75, 0x61, 0x67, 0x65, 0x20, 0x67, 0x6F, 0x76, 0x65, 0x72, 0x6E,
438*07fb1d06SElliott Hughes 0x80, 0x00, 0xD1, 0x06, 0x20, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x81,
439*07fb1d06SElliott Hughes 0x01, 0xD6, 0x00, 0x73, 0x80, 0x00, 0xA0, 0x00, 0x64, 0x81, 0x00, 0x46,
440*07fb1d06SElliott Hughes 0x06, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x61, 0x74, 0x82, 0x00, 0x12, 0x8E,
441*07fb1d06SElliott Hughes 0x00, 0xD7, 0x01, 0x2E, 0x0A, 0xFF, 0x81};
442*07fb1d06SElliott Hughes } // namespace
443*07fb1d06SElliott Hughes
444*07fb1d06SElliott Hughes // Tests a compressed deflate block using dynamic Huffman table.
TEST_F(PuffinTest,DynamicHuffmanTableTest)445*07fb1d06SElliott Hughes TEST_F(PuffinTest, DynamicHuffmanTableTest) {
446*07fb1d06SElliott Hughes CheckSample(kDynamicHTRaw, kDynamicHTDeflate, kDynamicHTPuff);
447*07fb1d06SElliott Hughes }
448*07fb1d06SElliott Hughes
449*07fb1d06SElliott Hughes // Tests an uncompressed deflate block with invalid LEN/NLEN.
TEST_F(PuffinTest,PuffInvalidUncompressedLengthDeflateTest)450*07fb1d06SElliott Hughes TEST_F(PuffinTest, PuffInvalidUncompressedLengthDeflateTest) {
451*07fb1d06SElliott Hughes const Buffer kDeflate = {0x01, 0x05, 0x00, 0xFF, 0xFF,
452*07fb1d06SElliott Hughes 0x01, 0x02, 0x03, 0x04, 0x05};
453*07fb1d06SElliott Hughes Buffer puffed;
454*07fb1d06SElliott Hughes FailPuffDeflate(kDeflate, &puffed);
455*07fb1d06SElliott Hughes }
456*07fb1d06SElliott Hughes
457*07fb1d06SElliott Hughes // Tests puffing a block with invalid block header.
TEST_F(PuffinTest,PuffInvalidBlockHeaderDeflateTest)458*07fb1d06SElliott Hughes TEST_F(PuffinTest, PuffInvalidBlockHeaderDeflateTest) {
459*07fb1d06SElliott Hughes const Buffer kDeflate = {0x07};
460*07fb1d06SElliott Hughes Buffer puffed;
461*07fb1d06SElliott Hughes FailPuffDeflate(kDeflate, &puffed);
462*07fb1d06SElliott Hughes }
463*07fb1d06SElliott Hughes
464*07fb1d06SElliott Hughes // Tests puffing a block with final block bit unset so it returns false.
TEST_F(PuffinTest,PuffDeflateNoFinalBlockBitTest)465*07fb1d06SElliott Hughes TEST_F(PuffinTest, PuffDeflateNoFinalBlockBitTest) {
466*07fb1d06SElliott Hughes const Buffer kDeflate = {0x62, 0x04, 0x00};
467*07fb1d06SElliott Hughes const Buffer kPuff = {0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81};
468*07fb1d06SElliott Hughes CheckSample(kRaw1, kDeflate, kPuff);
469*07fb1d06SElliott Hughes }
470*07fb1d06SElliott Hughes
471*07fb1d06SElliott Hughes // Tests two deflate buffers concatenated, neither have their final bit set. It
472*07fb1d06SElliott Hughes // is a valid deflate and puff buffer.
TEST_F(PuffinTest,MultipleDeflateBufferNoFinabBitsTest)473*07fb1d06SElliott Hughes TEST_F(PuffinTest, MultipleDeflateBufferNoFinabBitsTest) {
474*07fb1d06SElliott Hughes const Buffer kDeflate = {0x62, 0x04, 0x88, 0x11, 0x00};
475*07fb1d06SElliott Hughes const Buffer kPuff = {0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
476*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81};
477*07fb1d06SElliott Hughes CheckSample(kRaw2, kDeflate, kPuff);
478*07fb1d06SElliott Hughes }
479*07fb1d06SElliott Hughes
480*07fb1d06SElliott Hughes // Tests two deflate buffers concatenated, the first one has final bit set,
481*07fb1d06SElliott Hughes // second one not. It is a valid deflate and puff buffer.
TEST_F(PuffinTest,MultipleDeflateBufferOneFinalBitTest)482*07fb1d06SElliott Hughes TEST_F(PuffinTest, MultipleDeflateBufferOneFinalBitTest) {
483*07fb1d06SElliott Hughes const Buffer kDeflate = {0x63, 0x04, 0x88, 0x11, 0x00};
484*07fb1d06SElliott Hughes const Buffer kPuff = {0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81,
485*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81};
486*07fb1d06SElliott Hughes CheckSample(kRaw2, kDeflate, kPuff);
487*07fb1d06SElliott Hughes }
488*07fb1d06SElliott Hughes
489*07fb1d06SElliott Hughes // Tests two deflate buffers concatenated, both have final bits set. It is a
490*07fb1d06SElliott Hughes // valid deflate and puff buffer.
TEST_F(PuffinTest,MultipleDeflateBufferBothFinalBitTest)491*07fb1d06SElliott Hughes TEST_F(PuffinTest, MultipleDeflateBufferBothFinalBitTest) {
492*07fb1d06SElliott Hughes const Buffer kDeflate = {0x63, 0x04, 0x8C, 0x11, 0x00};
493*07fb1d06SElliott Hughes const Buffer kPuff = {0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81,
494*07fb1d06SElliott Hughes 0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81};
495*07fb1d06SElliott Hughes CheckSample(kRaw2, kDeflate, kPuff);
496*07fb1d06SElliott Hughes }
497*07fb1d06SElliott Hughes
498*07fb1d06SElliott Hughes // When locating deflates, the puffer has to end when it hit a final block. Test
499*07fb1d06SElliott Hughes // that with two deflate buffers concatenated and both have final bits set.
TEST_F(PuffinTest,EndOnFinalBitTest)500*07fb1d06SElliott Hughes TEST_F(PuffinTest, EndOnFinalBitTest) {
501*07fb1d06SElliott Hughes const Buffer kDeflate = {0x63, 0x04, 0x8C, 0x11, 0x00};
502*07fb1d06SElliott Hughes BufferBitReader bit_reader(kDeflate.data(), kDeflate.size());
503*07fb1d06SElliott Hughes BufferPuffWriter puff_writer(nullptr, 0);
504*07fb1d06SElliott Hughes vector<BitExtent> deflates;
505*07fb1d06SElliott Hughes EXPECT_TRUE(puffer_.PuffDeflate(&bit_reader, &puff_writer, &deflates));
506*07fb1d06SElliott Hughes const vector<BitExtent> kExpectedDeflates = {{0, 18}};
507*07fb1d06SElliott Hughes EXPECT_EQ(deflates, kExpectedDeflates);
508*07fb1d06SElliott Hughes EXPECT_EQ(bit_reader.Offset(), 3);
509*07fb1d06SElliott Hughes }
510*07fb1d06SElliott Hughes
511*07fb1d06SElliott Hughes // TODO(ahassani): Add unittests for Failhuff too.
512*07fb1d06SElliott Hughes
513*07fb1d06SElliott Hughes namespace {
514*07fb1d06SElliott Hughes // The following is a sequence of bits starting from the top right and ends in
515*07fb1d06SElliott Hughes // bottom left. It represents the bits in |kGapDeflates|. Bits inside the
516*07fb1d06SElliott Hughes // brackets (including bits exactly under brackets) represent a deflate stream.
517*07fb1d06SElliott Hughes //
518*07fb1d06SElliott Hughes // } { } { }{ }
519*07fb1d06SElliott Hughes // 11000101 10000000 10001100 01010000 00010001 10001000 00000100 01100010
520*07fb1d06SElliott Hughes // 0xC5 0x80 0x8C 0x50 0x11 0x88 0x04 0x62
521*07fb1d06SElliott Hughes //
522*07fb1d06SElliott Hughes // } { } { } {
523*07fb1d06SElliott Hughes // 10001011 11111100 00000100 01100010 00000001 00011000 10111000 00001000
524*07fb1d06SElliott Hughes // 0x8B 0xFC 0x04 0x62 0x01 0x18 0xB8 0x08
525*07fb1d06SElliott Hughes //
526*07fb1d06SElliott Hughes // } { } { }{
527*07fb1d06SElliott Hughes // 10001011 00000001 00011000 10111111 11000000 01000110 00100000 00010001
528*07fb1d06SElliott Hughes // 0x8B 0x01 0x18 0xBF 0xC0 0x46 0x20 0x11
529*07fb1d06SElliott Hughes //
530*07fb1d06SElliott Hughes // { } { } {
531*07fb1d06SElliott Hughes // 11111100 00000100 01100010 11111111 00000001 00011000 10110000 00010001
532*07fb1d06SElliott Hughes // 0xFC 0x04 0x62 0xFF 0x01 0x18 0xB0 0x11
533*07fb1d06SElliott Hughes //
534*07fb1d06SElliott Hughes const Buffer kGapDeflates = {0x62, 0x04, 0x88, 0x11, 0x50, 0x8C, 0x80, 0xC5,
535*07fb1d06SElliott Hughes 0x08, 0xB8, 0x18, 0x01, 0x62, 0x04, 0xFC, 0x8B,
536*07fb1d06SElliott Hughes 0x11, 0x20, 0x46, 0xC0, 0xBF, 0x18, 0x01, 0x8B,
537*07fb1d06SElliott Hughes 0x11, 0xB0, 0x18, 0x01, 0xFF, 0x62, 0x04, 0xFC};
538*07fb1d06SElliott Hughes
539*07fb1d06SElliott Hughes const Buffer kGapPuffs = {0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 0
540*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 7
541*07fb1d06SElliott Hughes 0x01, // raw 14
542*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 15
543*07fb1d06SElliott Hughes 0x01, 0x01, // raw 22
544*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 24
545*07fb1d06SElliott Hughes 0x07, // raw 31
546*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 32
547*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 39
548*07fb1d06SElliott Hughes 0x3F, 0x03, // raw 46
549*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 48
550*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 55
551*07fb1d06SElliott Hughes 0x03, 0x3F, // raw 62
552*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 64
553*07fb1d06SElliott Hughes 0x03, // raw 71
554*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 72
555*07fb1d06SElliott Hughes 0x03, // raw 79
556*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 80
557*07fb1d06SElliott Hughes 0xFF, // raw 87
558*07fb1d06SElliott Hughes 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81, // puff 88
559*07fb1d06SElliott Hughes 0x3F}; // raw 95
560*07fb1d06SElliott Hughes
561*07fb1d06SElliott Hughes // The fifth deflate (and its puff in kGapPuffExtents) is for zero length
562*07fb1d06SElliott Hughes // deflate corner case.
563*07fb1d06SElliott Hughes const vector<BitExtent> kGapSubblockDeflateExtents = {
564*07fb1d06SElliott Hughes {0, 18}, {18, 18}, {37, 18}, {57, 18}, {75, 0}, {78, 18}, {96, 18},
565*07fb1d06SElliott Hughes {122, 18}, {140, 18}, {166, 18}, {186, 18}, {206, 18}, {232, 18}};
566*07fb1d06SElliott Hughes
567*07fb1d06SElliott Hughes const vector<ByteExtent> kGapPuffExtents = {
568*07fb1d06SElliott Hughes {0, 7}, {7, 7}, {15, 7}, {24, 7}, {31, 0}, {32, 7}, {39, 7},
569*07fb1d06SElliott Hughes {48, 7}, {55, 7}, {64, 7}, {72, 7}, {80, 7}, {88, 7}};
570*07fb1d06SElliott Hughes } // namespace
571*07fb1d06SElliott Hughes
TEST_F(PuffinTest,BitExtentPuffAndHuffTest)572*07fb1d06SElliott Hughes TEST_F(PuffinTest, BitExtentPuffAndHuffTest) {
573*07fb1d06SElliott Hughes CheckBitExtentsPuffAndHuff(kGapDeflates, kGapSubblockDeflateExtents,
574*07fb1d06SElliott Hughes kGapPuffs, kGapPuffExtents);
575*07fb1d06SElliott Hughes }
576*07fb1d06SElliott Hughes
TEST_F(PuffinTest,ExcludeBadDistanceCaches)577*07fb1d06SElliott Hughes TEST_F(PuffinTest, ExcludeBadDistanceCaches) {
578*07fb1d06SElliott Hughes BufferBitReader br(kProblematicCache.data(), kProblematicCache.size());
579*07fb1d06SElliott Hughes BufferPuffWriter pw(nullptr, 0);
580*07fb1d06SElliott Hughes
581*07fb1d06SElliott Hughes // The first two bits of this data should be ignored.
582*07fb1d06SElliott Hughes br.CacheBits(2);
583*07fb1d06SElliott Hughes br.DropBits(2);
584*07fb1d06SElliott Hughes
585*07fb1d06SElliott Hughes vector<BitExtent> deflates, empty;
586*07fb1d06SElliott Hughes Puffer puffer(true);
587*07fb1d06SElliott Hughes EXPECT_TRUE(puffer.PuffDeflate(&br, &pw, &deflates));
588*07fb1d06SElliott Hughes EXPECT_EQ(deflates, empty);
589*07fb1d06SElliott Hughes }
590*07fb1d06SElliott Hughes
TEST_F(PuffinTest,NoExcludeBadDistanceCaches)591*07fb1d06SElliott Hughes TEST_F(PuffinTest, NoExcludeBadDistanceCaches) {
592*07fb1d06SElliott Hughes BufferBitReader br(kProblematicCache.data(), kProblematicCache.size());
593*07fb1d06SElliott Hughes BufferPuffWriter pw(nullptr, 0);
594*07fb1d06SElliott Hughes
595*07fb1d06SElliott Hughes // The first two bits of this data should be ignored.
596*07fb1d06SElliott Hughes br.CacheBits(2);
597*07fb1d06SElliott Hughes br.DropBits(2);
598*07fb1d06SElliott Hughes
599*07fb1d06SElliott Hughes vector<BitExtent> deflates;
600*07fb1d06SElliott Hughes Puffer puffer; // The default value for excluding bad distance cache should
601*07fb1d06SElliott Hughes // be false.
602*07fb1d06SElliott Hughes EXPECT_TRUE(puffer.PuffDeflate(&br, &pw, &deflates));
603*07fb1d06SElliott Hughes EXPECT_EQ(deflates, kProblematicCacheDeflateExtents);
604*07fb1d06SElliott Hughes }
605*07fb1d06SElliott Hughes
606*07fb1d06SElliott Hughes } // namespace puffin
607