1 |
From c5161728f1f445810fd0e7630fc4c68f5c233007 Mon Sep 17 00:00:00 2001 |
2 |
From: Pavel Raiskup <praiskup@redhat.com> |
3 |
Date: Mon, 18 Jul 2016 10:26:36 +0200 |
4 |
Subject: [PATCH 1/2] This is a combination of 3 commits. == |
5 |
|
6 |
And there is one downstream patch for API incompatibility because we |
7 |
applied 3.X patch against 2.8.3 version. |
8 |
|
9 |
== The first commit's message is: == |
10 |
|
11 |
Issue 175: Simplify filter bidding code. |
12 |
|
13 |
SVN-Revision: 3663 |
14 |
|
15 |
Generated by: |
16 |
git show d00167e1 libarchive/archive_read_support_filter_compress.c |
17 |
|
18 |
== This is the 2nd commit message: == |
19 |
|
20 |
Issue 547: problems with compress bidder |
21 |
|
22 |
The code previously was not very careful about verifying the |
23 |
compression parameters. This led to cases where it failed to |
24 |
reject invalid compressed data at the beginning. The invalid |
25 |
left shift was one symptom of this. |
26 |
|
27 |
The code is now more careful: It verifies that the compression |
28 |
parameter byte exists and verifies that the maximum code size |
29 |
is <= 16 bits. |
30 |
|
31 |
This also includes some new tests to verify that truncated or |
32 |
otherwise invalid compressed data is rejected. |
33 |
|
34 |
== This is the 3rd commit message: == |
35 |
|
36 |
add missing tests to automake |
37 |
--- |
38 |
Makefile.am | 1 + |
39 |
.../archive_read_support_compression_compress.c | 25 ++++--- |
40 |
libarchive/test/test_read_filter_compress.c | 80 ++++++++++++++++++++++ |
41 |
3 files changed, 96 insertions(+), 10 deletions(-) |
42 |
create mode 100644 libarchive/test/test_read_filter_compress.c |
43 |
|
44 |
diff --git a/Makefile.am b/Makefile.am |
45 |
index 61e8da4..9844b3c 100644 |
46 |
--- a/Makefile.am |
47 |
+++ b/Makefile.am |
48 |
@@ -252,6 +252,7 @@ libarchive_test_SOURCES= \ |
49 |
libarchive/test/test_read_disk_entry_from_file.c \ |
50 |
libarchive/test/test_read_extract.c \ |
51 |
libarchive/test/test_read_file_nonexistent.c \ |
52 |
+ libarchive/test/test_read_filter_compress.c \ |
53 |
libarchive/test/test_read_format_ar.c \ |
54 |
libarchive/test/test_read_format_cpio_bin.c \ |
55 |
libarchive/test/test_read_format_cpio_bin_Z.c \ |
56 |
diff --git a/libarchive/archive_read_support_compression_compress.c b/libarchive/archive_read_support_compression_compress.c |
57 |
index 2461975..09a6cbd 100644 |
58 |
--- a/libarchive/archive_read_support_compression_compress.c |
59 |
+++ b/libarchive/archive_read_support_compression_compress.c |
60 |
@@ -174,23 +174,22 @@ compress_bidder_bid(struct archive_read_filter_bidder *self, |
61 |
|
62 |
(void)self; /* UNUSED */ |
63 |
|
64 |
- buffer = __archive_read_filter_ahead(filter, 2, &avail); |
65 |
+ /* Shortest valid compress file is 3 bytes. */ |
66 |
+ buffer = __archive_read_filter_ahead(filter, 3, &avail); |
67 |
|
68 |
if (buffer == NULL) |
69 |
return (0); |
70 |
|
71 |
bits_checked = 0; |
72 |
- if (buffer[0] != 037) /* Verify first ID byte. */ |
73 |
+ /* First two bytes are the magic value */ |
74 |
+ if (buffer[0] != 0x1F || buffer[1] != 0x9D) |
75 |
return (0); |
76 |
- bits_checked += 8; |
77 |
- |
78 |
- if (buffer[1] != 0235) /* Verify second ID byte. */ |
79 |
+ /* Third byte holds compression parameters. */ |
80 |
+ if (buffer[2] & 0x20) /* Reserved bit, must be zero. */ |
81 |
return (0); |
82 |
- bits_checked += 8; |
83 |
- |
84 |
- /* |
85 |
- * TODO: Verify more. |
86 |
- */ |
87 |
+ if (buffer[2] & 0x40) /* Reserved bit, must be zero. */ |
88 |
+ return (0); |
89 |
+ bits_checked += 18; |
90 |
|
91 |
return (bits_checked); |
92 |
} |
93 |
@@ -232,7 +231,13 @@ compress_bidder_init(struct archive_read_filter *self) |
94 |
(void)getbits(self, 8); /* Skip first signature byte. */ |
95 |
(void)getbits(self, 8); /* Skip second signature byte. */ |
96 |
|
97 |
+ /* Get compression parameters. */ |
98 |
code = getbits(self, 8); |
99 |
+ if ((code & 0x1f) > 16) { |
100 |
+ archive_set_error(&self->archive->archive, -1, |
101 |
+ "Invalid compressed data"); |
102 |
+ return (ARCHIVE_FATAL); |
103 |
+ } |
104 |
state->maxcode_bits = code & 0x1f; |
105 |
state->maxcode = (1 << state->maxcode_bits); |
106 |
state->use_reset_code = code & 0x80; |
107 |
diff --git a/libarchive/test/test_read_filter_compress.c b/libarchive/test/test_read_filter_compress.c |
108 |
new file mode 100644 |
109 |
index 0000000..03a1d5f |
110 |
--- /dev/null |
111 |
+++ b/libarchive/test/test_read_filter_compress.c |
112 |
@@ -0,0 +1,80 @@ |
113 |
+/*- |
114 |
+ * Copyright (c) 2003-2008 Tim Kientzle |
115 |
+ * All rights reserved. |
116 |
+ * |
117 |
+ * Redistribution and use in source and binary forms, with or without |
118 |
+ * modification, are permitted provided that the following conditions |
119 |
+ * are met: |
120 |
+ * 1. Redistributions of source code must retain the above copyright |
121 |
+ * notice, this list of conditions and the following disclaimer. |
122 |
+ * 2. Redistributions in binary form must reproduce the above copyright |
123 |
+ * notice, this list of conditions and the following disclaimer in the |
124 |
+ * documentation and/or other materials provided with the distribution. |
125 |
+ * |
126 |
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR |
127 |
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
128 |
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
129 |
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, |
130 |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
131 |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
132 |
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
133 |
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
134 |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
135 |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
136 |
+ */ |
137 |
+#include "test.h" |
138 |
+ |
139 |
+DEFINE_TEST(test_read_filter_compress_truncated) |
140 |
+{ |
141 |
+ const char data[] = {0x1f, 0x9d}; |
142 |
+ struct archive *a; |
143 |
+ |
144 |
+ assert((a = archive_read_new()) != NULL); |
145 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); |
146 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); |
147 |
+ assertEqualIntA(a, ARCHIVE_FATAL, |
148 |
+ archive_read_open_memory(a, data, sizeof(data))); |
149 |
+ |
150 |
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); |
151 |
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); |
152 |
+} |
153 |
+ |
154 |
+ |
155 |
+DEFINE_TEST(test_read_filter_compress_empty2) |
156 |
+{ |
157 |
+ const char data[] = {0x1f, 0x9d, 0x10}; |
158 |
+ struct archive *a; |
159 |
+ struct archive_entry *ae; |
160 |
+ |
161 |
+ assert((a = archive_read_new()) != NULL); |
162 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); |
163 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); |
164 |
+ assertEqualIntA(a, ARCHIVE_OK, |
165 |
+ archive_read_open_memory(a, data, sizeof(data))); |
166 |
+ |
167 |
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); |
168 |
+ |
169 |
+ /* Verify that the format detection worked. */ |
170 |
+ assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); |
171 |
+ assertEqualString(archive_filter_name(a, 0), "compress (.Z)"); |
172 |
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_EMPTY); |
173 |
+ |
174 |
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); |
175 |
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); |
176 |
+} |
177 |
+ |
178 |
+ |
179 |
+DEFINE_TEST(test_read_filter_compress_invalid) |
180 |
+{ |
181 |
+ const char data[] = {0x1f, 0x9d, 0x11}; |
182 |
+ struct archive *a; |
183 |
+ |
184 |
+ assert((a = archive_read_new()) != NULL); |
185 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); |
186 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); |
187 |
+ assertEqualIntA(a, ARCHIVE_FATAL, |
188 |
+ archive_read_open_memory(a, data, sizeof(data))); |
189 |
+ |
190 |
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); |
191 |
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); |
192 |
+} |
193 |
-- |
194 |
2.7.4 |
195 |
|
196 |
From 3efc62f095768b3a92eef347d223bc013f988a18 Mon Sep 17 00:00:00 2001 |
197 |
From: Pavel Raiskup <praiskup@redhat.com> |
198 |
Date: Mon, 18 Jul 2016 12:31:30 +0200 |
199 |
Subject: [PATCH 2/2] fix testsuite |
200 |
|
201 |
--- |
202 |
libarchive/test/test_read_filter_compress.c | 28 ++++++++++++++++------------ |
203 |
1 file changed, 16 insertions(+), 12 deletions(-) |
204 |
|
205 |
diff --git a/libarchive/test/test_read_filter_compress.c b/libarchive/test/test_read_filter_compress.c |
206 |
index 03a1d5f..b92a944 100644 |
207 |
--- a/libarchive/test/test_read_filter_compress.c |
208 |
+++ b/libarchive/test/test_read_filter_compress.c |
209 |
@@ -26,28 +26,32 @@ |
210 |
|
211 |
DEFINE_TEST(test_read_filter_compress_truncated) |
212 |
{ |
213 |
- const char data[] = {0x1f, 0x9d}; |
214 |
+ char data[] = {0x1f, 0x9d}; |
215 |
struct archive *a; |
216 |
+ struct archive_entry *ae; |
217 |
|
218 |
assert((a = archive_read_new()) != NULL); |
219 |
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); |
220 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_compress(a)); |
221 |
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); |
222 |
- assertEqualIntA(a, ARCHIVE_FATAL, |
223 |
- archive_read_open_memory(a, data, sizeof(data))); |
224 |
+ /* this is ARCHIVE_OK because 2.8.3 does not bid the format here yet .. */ |
225 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, data, sizeof(data))); |
226 |
+ /* .. but it must fail here */ |
227 |
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); |
228 |
+ |
229 |
|
230 |
assertEqualInt(ARCHIVE_OK, archive_read_close(a)); |
231 |
- assertEqualInt(ARCHIVE_OK, archive_read_free(a)); |
232 |
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); |
233 |
} |
234 |
|
235 |
|
236 |
DEFINE_TEST(test_read_filter_compress_empty2) |
237 |
{ |
238 |
- const char data[] = {0x1f, 0x9d, 0x10}; |
239 |
+ char data[] = {0x1f, 0x9d, 0x10}; |
240 |
struct archive *a; |
241 |
struct archive_entry *ae; |
242 |
|
243 |
assert((a = archive_read_new()) != NULL); |
244 |
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); |
245 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_compress(a)); |
246 |
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); |
247 |
assertEqualIntA(a, ARCHIVE_OK, |
248 |
archive_read_open_memory(a, data, sizeof(data))); |
249 |
@@ -55,12 +59,12 @@ DEFINE_TEST(test_read_filter_compress_empty2) |
250 |
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); |
251 |
|
252 |
/* Verify that the format detection worked. */ |
253 |
- assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); |
254 |
- assertEqualString(archive_filter_name(a, 0), "compress (.Z)"); |
255 |
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); |
256 |
+ assertEqualString(archive_compression_name(a), "compress (.Z)"); |
257 |
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_EMPTY); |
258 |
|
259 |
assertEqualInt(ARCHIVE_OK, archive_read_close(a)); |
260 |
- assertEqualInt(ARCHIVE_OK, archive_read_free(a)); |
261 |
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); |
262 |
} |
263 |
|
264 |
|
265 |
@@ -70,11 +74,11 @@ DEFINE_TEST(test_read_filter_compress_invalid) |
266 |
struct archive *a; |
267 |
|
268 |
assert((a = archive_read_new()) != NULL); |
269 |
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); |
270 |
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_compress(a)); |
271 |
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); |
272 |
assertEqualIntA(a, ARCHIVE_FATAL, |
273 |
archive_read_open_memory(a, data, sizeof(data))); |
274 |
|
275 |
assertEqualInt(ARCHIVE_OK, archive_read_close(a)); |
276 |
- assertEqualInt(ARCHIVE_OK, archive_read_free(a)); |
277 |
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); |
278 |
} |
279 |
-- |
280 |
2.7.4 |
281 |
|