Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: net/base/bzip2_filter_unittest.cc

Issue 466038: Remove bzip2 decoding support completely. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/bzip2_filter.cc ('k') | net/base/filter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <fstream>
6 #include <iostream>
7
8 #if defined(USE_SYSTEM_LIBBZ2)
9 #include <bzlib.h>
10 #else
11 #include "third_party/bzip2/bzlib.h"
12 #endif
13
14 #include "base/file_util.h"
15 #include "base/path_service.h"
16 #include "base/scoped_ptr.h"
17 #include "net/base/bzip2_filter.h"
18 #include "net/base/filter_unittest.h"
19 #include "net/base/io_buffer.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "testing/platform_test.h"
22
23 namespace {
24
25 const char* kExtraData = "Test Data, More Test Data, Even More Data of Test";
26 const int kExtraDataBufferSize = 49;
27 const int kDefaultBufferSize = 4096;
28 const int kSmallBufferSize = 128;
29 const int kMaxBufferSize = 1048576; // 1048576 == 2^20 == 1 MB
30
31 const char kApplicationOctetStream[] = "application/octet-stream";
32
33 // These tests use the path service, which uses autoreleased objects on the
34 // Mac, so this needs to be a PlatformTest.
35 class BZip2FilterUnitTest : public PlatformTest {
36 protected:
37 virtual void SetUp() {
38 PlatformTest::SetUp();
39
40 bzip2_encode_buffer_ = NULL;
41
42 // Get the path of source data file.
43 FilePath file_path;
44 PathService::Get(base::DIR_SOURCE_ROOT, &file_path);
45 file_path = file_path.AppendASCII("net");
46 file_path = file_path.AppendASCII("data");
47 file_path = file_path.AppendASCII("filter_unittests");
48 file_path = file_path.AppendASCII("google.txt");
49
50 // Read data from the file into buffer.
51 ASSERT_TRUE(file_util::ReadFileToString(file_path, &source_buffer_));
52
53 // Append the extra data to end of source
54 source_buffer_.append(kExtraData, kExtraDataBufferSize);
55
56 // Encode the whole data with bzip2 for next testing
57 bzip2_data_stream_.reset(new bz_stream);
58 ASSERT_TRUE(bzip2_data_stream_.get());
59 memset(bzip2_data_stream_.get(), 0, sizeof(bz_stream));
60
61 int result = BZ2_bzCompressInit(bzip2_data_stream_.get(),
62 9, // 900k block size
63 0, // quiet
64 0); // default work factor
65 ASSERT_EQ(BZ_OK, result);
66
67 bzip2_encode_buffer_ = new char[kDefaultBufferSize];
68 ASSERT_TRUE(bzip2_encode_buffer_ != NULL);
69 bzip2_encode_len_ = kDefaultBufferSize;
70
71 bzip2_data_stream_->next_in = const_cast<char*>(source_buffer());
72 bzip2_data_stream_->avail_in = source_len();
73 bzip2_data_stream_->next_out = bzip2_encode_buffer_;
74 bzip2_data_stream_->avail_out = bzip2_encode_len_;
75 do {
76 result = BZ2_bzCompress(bzip2_data_stream_.get(), BZ_FINISH);
77 } while (result == BZ_FINISH_OK);
78
79 ASSERT_EQ(BZ_STREAM_END, result);
80 result = BZ2_bzCompressEnd(bzip2_data_stream_.get());
81 ASSERT_EQ(BZ_OK, result);
82 bzip2_encode_len_ = bzip2_data_stream_->total_out_lo32;
83
84 // Make sure we wrote something; otherwise not sure what to expect
85 ASSERT_GT(bzip2_encode_len_, 0);
86 ASSERT_LE(bzip2_encode_len_, kDefaultBufferSize);
87 }
88
89 virtual void TearDown() {
90 delete[] bzip2_encode_buffer_;
91 bzip2_encode_buffer_ = NULL;
92
93 PlatformTest::TearDown();
94 }
95
96 // Use filter to decode compressed data, and compare the decoding result with
97 // the orginal Data.
98 // Parameters: Source and source_len are original data and its size.
99 // Encoded_source and encoded_source_len are compressed data and its size.
100 // Output_buffer_size specifies the size of buffer to read out data from
101 // filter.
102 // get_extra_data specifies whether get the extra data because maybe some
103 // server might send extra data after finish sending compress data.
104 void DecodeAndCompareWithFilter(Filter* filter,
105 const char* source,
106 int source_len,
107 const char* encoded_source,
108 int encoded_source_len,
109 int output_buffer_size,
110 bool get_extra_data) {
111 // Make sure we have enough space to hold the decoding output.
112 ASSERT_LE(source_len, kDefaultBufferSize);
113 ASSERT_LE(output_buffer_size, kDefaultBufferSize);
114
115 int total_output_len = kDefaultBufferSize;
116 if (get_extra_data)
117 total_output_len += kExtraDataBufferSize;
118 char decode_buffer[kDefaultBufferSize + kExtraDataBufferSize];
119 char* decode_next = decode_buffer;
120 int decode_avail_size = total_output_len;
121
122 const char* encode_next = encoded_source;
123 int encode_avail_size = encoded_source_len;
124
125 Filter::FilterStatus code = Filter::FILTER_OK;
126 while (code != Filter::FILTER_DONE) {
127 int encode_data_len;
128 if (get_extra_data && !encode_avail_size)
129 break;
130 encode_data_len = std::min(encode_avail_size,
131 filter->stream_buffer_size());
132 memcpy(filter->stream_buffer()->data(), encode_next, encode_data_len);
133 filter->FlushStreamBuffer(encode_data_len);
134 encode_next += encode_data_len;
135 encode_avail_size -= encode_data_len;
136
137 while (1) {
138 int decode_data_len = std::min(decode_avail_size, output_buffer_size);
139
140 code = filter->ReadData(decode_next, &decode_data_len);
141 decode_next += decode_data_len;
142 decode_avail_size -= decode_data_len;
143
144 ASSERT_TRUE(code != Filter::FILTER_ERROR);
145
146 if (code == Filter::FILTER_NEED_MORE_DATA ||
147 code == Filter::FILTER_DONE) {
148 if (code == Filter::FILTER_DONE && get_extra_data)
149 code = Filter::FILTER_OK;
150 else
151 break;
152 }
153 }
154 }
155
156 // Compare the decoding result with source data
157 int decode_total_data_len = total_output_len - decode_avail_size;
158 EXPECT_TRUE(decode_total_data_len == source_len);
159 EXPECT_EQ(memcmp(source, decode_buffer, source_len), 0);
160 }
161
162 // Unsafe function to use filter to decode compressed data.
163 // Parameters: Source and source_len are compressed data and its size.
164 // Dest is the buffer for decoding results. Upon entry, *dest_len is the size
165 // of the dest buffer. Upon exit, *dest_len is the number of chars written
166 // into the buffer.
167 Filter::FilterStatus DecodeAllWithFilter(Filter* filter,
168 const char* source,
169 int source_len,
170 char* dest,
171 int* dest_len) {
172 memcpy(filter->stream_buffer()->data(), source, source_len);
173 filter->FlushStreamBuffer(source_len);
174 return filter->ReadData(dest, dest_len);
175 }
176
177 const char* source_buffer() const { return source_buffer_.data(); }
178 int source_len() const {
179 return static_cast<int>(source_buffer_.size()) - kExtraDataBufferSize;
180 }
181
182 std::string source_buffer_;
183
184 scoped_ptr<bz_stream> bzip2_data_stream_;
185 char* bzip2_encode_buffer_;
186 int bzip2_encode_len_;
187 };
188
189 // Basic scenario: decoding bzip2 data with big enough buffer.
190 TEST_F(BZip2FilterUnitTest, DecodeBZip2) {
191 // Decode the compressed data with filter
192 std::vector<Filter::FilterType> filter_types;
193 filter_types.push_back(Filter::FILTER_TYPE_BZIP2);
194 MockFilterContext filter_context(kDefaultBufferSize);
195 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context));
196 ASSERT_TRUE(filter.get());
197 memcpy(filter->stream_buffer()->data(), bzip2_encode_buffer_,
198 bzip2_encode_len_);
199 filter->FlushStreamBuffer(bzip2_encode_len_);
200
201 char bzip2_decode_buffer[kDefaultBufferSize];
202 int bzip2_decode_size = kDefaultBufferSize;
203 Filter::FilterStatus result =
204 filter->ReadData(bzip2_decode_buffer, &bzip2_decode_size);
205 ASSERT_EQ(Filter::FILTER_DONE, result);
206
207 // Compare the decoding result with source data
208 EXPECT_TRUE(bzip2_decode_size == source_len());
209 EXPECT_EQ(memcmp(source_buffer(), bzip2_decode_buffer, source_len()), 0);
210 }
211
212 // Tests we can call filter repeatedly to get all the data decoded.
213 // To do that, we create a filter with a small buffer that can not hold all
214 // the input data.
215 TEST_F(BZip2FilterUnitTest, DecodeWithSmallInputBuffer) {
216 std::vector<Filter::FilterType> filter_types;
217 filter_types.push_back(Filter::FILTER_TYPE_BZIP2);
218 MockFilterContext filter_context(kSmallBufferSize);
219 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context));
220 ASSERT_TRUE(filter.get());
221 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(),
222 bzip2_encode_buffer_, bzip2_encode_len_,
223 kDefaultBufferSize, false);
224 }
225
226 // Tests we can decode when caller has small buffer to read out from filter.
227 TEST_F(BZip2FilterUnitTest, DecodeWithSmallOutputBuffer) {
228 std::vector<Filter::FilterType> filter_types;
229 filter_types.push_back(Filter::FILTER_TYPE_BZIP2);
230 MockFilterContext filter_context(kDefaultBufferSize);
231 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context));
232 ASSERT_TRUE(filter.get());
233 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(),
234 bzip2_encode_buffer_, bzip2_encode_len_,
235 kSmallBufferSize, false);
236 }
237
238 // Tests we can still decode with just 1 byte buffer in the filter.
239 // The purpose of this tests are two: (1) Verify filter can parse partial BZip2
240 // header correctly. (2) Sometimes the filter will consume input without
241 // generating output. Verify filter can handle it correctly.
242 TEST_F(BZip2FilterUnitTest, DecodeWithOneByteInputBuffer) {
243 std::vector<Filter::FilterType> filter_types;
244 filter_types.push_back(Filter::FILTER_TYPE_BZIP2);
245 MockFilterContext filter_context(1);
246 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context));
247 ASSERT_TRUE(filter.get());
248 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(),
249 bzip2_encode_buffer_, bzip2_encode_len_,
250 kDefaultBufferSize, false);
251 }
252
253 // Tests we can still decode with just 1 byte buffer in the filter and just 1
254 // byte buffer in the caller.
255 TEST_F(BZip2FilterUnitTest, DecodeWithOneByteInputAndOutputBuffer) {
256 std::vector<Filter::FilterType> filter_types;
257 filter_types.push_back(Filter::FILTER_TYPE_BZIP2);
258 MockFilterContext filter_context(1);
259 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context));
260 ASSERT_TRUE(filter.get());
261 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(),
262 bzip2_encode_buffer_, bzip2_encode_len_, 1, false);
263 }
264
265 // Decoding bzip2 stream with corrupted data.
266 TEST_F(BZip2FilterUnitTest, DecodeCorruptedData) {
267 char corrupt_data[kDefaultBufferSize];
268 int corrupt_data_len = bzip2_encode_len_;
269 memcpy(corrupt_data, bzip2_encode_buffer_, bzip2_encode_len_);
270
271 char corrupt_decode_buffer[kDefaultBufferSize];
272 int corrupt_decode_size = kDefaultBufferSize;
273
274 // Decode the correct data with filter
275 std::vector<Filter::FilterType> filter_types;
276 filter_types.push_back(Filter::FILTER_TYPE_BZIP2);
277 MockFilterContext filter_context(kDefaultBufferSize);
278 scoped_ptr<Filter> filter1(Filter::Factory(filter_types, filter_context));
279 ASSERT_TRUE(filter1.get());
280
281 Filter::FilterStatus code = DecodeAllWithFilter(filter1.get(),
282 corrupt_data,
283 corrupt_data_len,
284 corrupt_decode_buffer,
285 &corrupt_decode_size);
286
287 // Expect failures
288 EXPECT_TRUE(code == Filter::FILTER_DONE);
289
290 // Decode the corrupted data with filter
291 scoped_ptr<Filter> filter2(Filter::Factory(filter_types, filter_context));
292 ASSERT_TRUE(filter2.get());
293
294 int pos = corrupt_data_len / 2;
295 corrupt_data[pos] = !corrupt_data[pos];
296
297 code = DecodeAllWithFilter(filter2.get(),
298 corrupt_data,
299 corrupt_data_len,
300 corrupt_decode_buffer,
301 &corrupt_decode_size);
302
303 // Expect failures
304 EXPECT_TRUE(code != Filter::FILTER_DONE);
305 }
306
307 // Decoding bzip2 stream with missing data.
308 TEST_F(BZip2FilterUnitTest, DecodeMissingData) {
309 char corrupt_data[kDefaultBufferSize];
310 int corrupt_data_len = bzip2_encode_len_;
311 memcpy(corrupt_data, bzip2_encode_buffer_, bzip2_encode_len_);
312
313 int pos = corrupt_data_len / 2;
314 int len = corrupt_data_len - pos - 1;
315 memmove(&corrupt_data[pos], &corrupt_data[pos+1], len);
316 --corrupt_data_len;
317
318 // Decode the corrupted data with filter
319 std::vector<Filter::FilterType> filter_types;
320 filter_types.push_back(Filter::FILTER_TYPE_BZIP2);
321 MockFilterContext filter_context(kDefaultBufferSize);
322 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context));
323 ASSERT_TRUE(filter.get());
324 char corrupt_decode_buffer[kDefaultBufferSize];
325 int corrupt_decode_size = kDefaultBufferSize;
326
327 Filter::FilterStatus code = DecodeAllWithFilter(filter.get(),
328 corrupt_data,
329 corrupt_data_len,
330 corrupt_decode_buffer,
331 &corrupt_decode_size);
332 // Expect failures
333 EXPECT_TRUE(code != Filter::FILTER_DONE);
334 }
335
336 // Decoding bzip2 stream with corrupted header.
337 TEST_F(BZip2FilterUnitTest, DecodeCorruptedHeader) {
338 char corrupt_data[kDefaultBufferSize];
339 int corrupt_data_len = bzip2_encode_len_;
340 memcpy(corrupt_data, bzip2_encode_buffer_, bzip2_encode_len_);
341
342 corrupt_data[2] = !corrupt_data[2];
343
344 // Decode the corrupted data with filter
345 std::vector<Filter::FilterType> filter_types;
346 filter_types.push_back(Filter::FILTER_TYPE_BZIP2);
347 MockFilterContext filter_context(kDefaultBufferSize);
348 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context));
349 ASSERT_TRUE(filter.get());
350 char corrupt_decode_buffer[kDefaultBufferSize];
351 int corrupt_decode_size = kDefaultBufferSize;
352
353 Filter::FilterStatus code = DecodeAllWithFilter(filter.get(),
354 corrupt_data,
355 corrupt_data_len,
356 corrupt_decode_buffer,
357 &corrupt_decode_size);
358
359 // Expect failures
360 EXPECT_TRUE(code == Filter::FILTER_ERROR);
361 }
362
363 // Tests we can decode all compress data and get extra data which is
364 // appended to compress data stream by some server when it finish
365 // sending compress data.
366 TEST_F(BZip2FilterUnitTest, DecodeWithExtraDataAndSmallOutputBuffer) {
367 char more_data[kDefaultBufferSize + kExtraDataBufferSize];
368 int more_data_len = bzip2_encode_len_ + kExtraDataBufferSize;
369 memcpy(more_data, bzip2_encode_buffer_, bzip2_encode_len_);
370 memcpy(more_data + bzip2_encode_len_, kExtraData, kExtraDataBufferSize);
371
372 std::vector<Filter::FilterType> filter_types;
373 filter_types.push_back(Filter::FILTER_TYPE_BZIP2);
374 MockFilterContext filter_context(kDefaultBufferSize);
375 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context));
376 ASSERT_TRUE(filter.get());
377 DecodeAndCompareWithFilter(filter.get(),
378 source_buffer(),
379 source_len() + kExtraDataBufferSize,
380 more_data,
381 more_data_len,
382 kSmallBufferSize,
383 true);
384 }
385
386 TEST_F(BZip2FilterUnitTest, DecodeWithExtraDataAndSmallInputBuffer) {
387 char more_data[kDefaultBufferSize + kExtraDataBufferSize];
388 int more_data_len = bzip2_encode_len_ + kExtraDataBufferSize;
389 memcpy(more_data, bzip2_encode_buffer_, bzip2_encode_len_);
390 memcpy(more_data + bzip2_encode_len_, kExtraData, kExtraDataBufferSize);
391
392 std::vector<Filter::FilterType> filter_types;
393 filter_types.push_back(Filter::FILTER_TYPE_BZIP2);
394 MockFilterContext filter_context(kSmallBufferSize);
395 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context));
396 ASSERT_TRUE(filter.get());
397 DecodeAndCompareWithFilter(filter.get(),
398 source_buffer(),
399 source_len() + kExtraDataBufferSize,
400 more_data,
401 more_data_len,
402 kDefaultBufferSize,
403 true);
404 }
405
406 } // namespace
OLDNEW
« no previous file with comments | « net/base/bzip2_filter.cc ('k') | net/base/filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698