diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2010-08-24 16:50:31 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2010-08-24 16:50:49 -0700 |
commit | a59c819beb4886ee43f16dfd80ec1151fda1abe6 (patch) | |
tree | a2ae6da893d6e0f430612a8b09decf98da28639f /scripts | |
parent | 57b11473b0135b1e092cf045f94635c934c7c63f (diff) | |
download | tar-a59c819beb4886ee43f16dfd80ec1151fda1abe6.tar.gz |
tar: don't assume size of a sparse file chunk fits in size_t
* src/tar.h (struct sp_array): Change numbytes from size_t to off_t.
All uses changed.
* scripts/xsparse.c (struct sp_array): Likewise.
Include <stdint.h>, for SIZE_MAX.
(expand_sparse): Don't try to allocate a buffer bigger than
SIZE_MAX bytes.
* src/common.h (SIZE_TO_CHARS, size_to_chars, SIZE_FROM_HEADER):
(size_from_header): Remove decls.
* src/create.c (size_to_chars): Remove.
* src/list.c (size_from_header): Remove.
* src/sparse.c (sparse_extract_region, check_data_region):
(oldgnu_add_sparse, oldgnu_store_sparse_info, pax_decode_header):
Don't assume chunk sizes fit in size_t.
(oldgnu_add_sparse): Check for off_t overflow.
* src/xheader.c (sparse_numbytes_decoder, sparse_map_decoder):
Likewise.
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/xsparse.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/scripts/xsparse.c b/scripts/xsparse.c index fd91b487..14d5658c 100644 --- a/scripts/xsparse.c +++ b/scripts/xsparse.c @@ -1,7 +1,7 @@ /* xsparse - expands compressed sparse file images extracted from GNU tar archives. - Copyright (C) 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2010 Free Software Foundation, Inc. Written by Sergey Poznyakoff @@ -20,6 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <stdlib.h> +#include <stdint.h> #include <stdio.h> #include <stdarg.h> #include <string.h> @@ -39,7 +40,7 @@ struct sp_array { off_t offset; - size_t numbytes; + off_t numbytes; }; char *progname; @@ -226,7 +227,7 @@ read_xheader (char *name) } else if (strcmp (kw, "numbytes") == 0) { - sparse_map[i++].numbytes = string_to_size (val, NULL); + sparse_map[i++].numbytes = string_to_off (val, NULL); } else if (strcmp (kw, "map") == 0) { @@ -236,7 +237,7 @@ read_xheader (char *name) if (*val != ',') die (1, "bad GNU.sparse.map: expected `,' but found `%c'", *val); - sparse_map[i].numbytes = string_to_size (val+1, &val); + sparse_map[i].numbytes = string_to_off (val+1, &val); if (*val != ',') { if (!(*val == 0 && i == sparse_map_size-1)) @@ -277,7 +278,7 @@ read_map (FILE *ifp) get_line (nbuf, sizeof nbuf, ifp); sparse_map[i].offset = string_to_off (nbuf, NULL); get_line (nbuf, sizeof nbuf, ifp); - sparse_map[i].numbytes = string_to_size (nbuf, NULL); + sparse_map[i].numbytes = string_to_off (nbuf, NULL); } fseeko (ifp, ((ftell (ifp) + BLOCKSIZE - 1) / BLOCKSIZE) * BLOCKSIZE, @@ -288,12 +289,15 @@ void expand_sparse (FILE *sfp, int ofd) { size_t i; - size_t maxbytes = 0; + off_t max_numbytes = 0; + size_t maxbytes; char *buffer; for (i = 0; i < sparse_map_size; i++) - if (maxbytes < sparse_map[i].numbytes) - maxbytes = sparse_map[i].numbytes; + if (max_numbytes < sparse_map[i].numbytes) + max_numbytes = sparse_map[i].numbytes; + + maxbytes = max_numbytes < SIZE_MAX ? max_numbytes : SIZE_MAX; for (buffer = malloc (maxbytes); !buffer; maxbytes /= 2) if (maxbytes == 0) @@ -301,7 +305,7 @@ expand_sparse (FILE *sfp, int ofd) for (i = 0; i < sparse_map_size; i++) { - size_t size = sparse_map[i].numbytes; + off_t size = sparse_map[i].numbytes; if (size == 0) ftruncate (ofd, sparse_map[i].offset); |