summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2010-08-24 16:50:31 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2010-08-24 16:50:49 -0700
commita59c819beb4886ee43f16dfd80ec1151fda1abe6 (patch)
treea2ae6da893d6e0f430612a8b09decf98da28639f /scripts
parent57b11473b0135b1e092cf045f94635c934c7c63f (diff)
downloadtar-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.c22
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);