1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
Index: lib/libarchive/archive_read_support_compression_none.c
===================================================================
RCS file: /home/ncvs/src/lib/libarchive/archive_read_support_compression_none.c,v
retrieving revision 1.8
diff -u -I__FBSDID -r1.8 archive_read_support_compression_none.c
--- lib/libarchive/archive_read_support_compression_none.c 29 Aug 2006 04:59:25 -0000 1.8
+++ lib/libarchive/archive_read_support_compression_none.c 2 Nov 2006 05:17:28 -0000
@@ -257,7 +257,9 @@
}
/*
- * Skip at most request bytes. Skipped data is marked as consumed.
+ * Skip forward by exactly the requested bytes or else return
+ * ARCHIVE_FATAL. Note that this differs from the contract for
+ * read_ahead, which does not gaurantee a minimum count.
*/
static ssize_t
archive_decompressor_none_skip(struct archive *a, size_t request)
@@ -287,9 +289,7 @@
if (request == 0)
return (total_bytes_skipped);
/*
- * If no client_skipper is provided, just read the old way. It is very
- * likely that after skipping, the request has not yet been fully
- * satisfied (and is still > 0). In that case, read as well.
+ * If a client_skipper was provided, try that first.
*/
if (a->client_skipper != NULL) {
bytes_skipped = (a->client_skipper)(a, a->client_data,
@@ -307,6 +307,12 @@
a->raw_position += bytes_skipped;
state->client_avail = state->client_total = 0;
}
+ /*
+ * Note that client_skipper will usually not satisfy the
+ * full request (due to low-level blocking concerns),
+ * so even if client_skipper is provided, we may still
+ * have to use ordinary reads to finish out the request.
+ */
while (request > 0) {
const void* dummy_buffer;
ssize_t bytes_read;
@@ -314,6 +320,12 @@
&dummy_buffer, request);
if (bytes_read < 0)
return (bytes_read);
+ if (bytes_read == 0) {
+ /* We hit EOF before we satisfied the skip request. */
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Truncated input file (need to skip %d bytes)", (int)request);
+ return (ARCHIVE_FATAL);
+ }
assert(bytes_read >= 0); /* precondition for cast below */
min = minimum((size_t)bytes_read, request);
bytes_read = archive_decompressor_none_read_consume(a, min);
|