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