1 |
jpp |
1.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 |
|
|
|