/* Functions for dealing with sparse files
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010 Free Software
- Foundation, Inc.
+ Copyright 2003-2007, 2010, 2013 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Public License for more details.
You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+ with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <system.h>
#include <inttostr.h>
return add_finish;
sp.offset = OFF_FROM_HEADER (s->offset);
sp.numbytes = OFF_FROM_HEADER (s->numbytes);
- if (sp.offset < 0
- || sp.offset + sp.numbytes < 0
+ if (sp.offset < 0 || sp.numbytes < 0
+ || INT_ADD_OVERFLOW (sp.offset, sp.numbytes)
|| file->stat_info->stat.st_size < sp.offset + sp.numbytes
|| file->stat_info->archive_file_size < 0)
return add_fail;
{
/* NOTE! st_size was initialized from the header
which actually contains archived size. The following fixes it */
+ off_t realsize = OFF_FROM_HEADER (current_header->oldgnu_header.realsize);
file->stat_info->archive_file_size = file->stat_info->stat.st_size;
- file->stat_info->stat.st_size =
- OFF_FROM_HEADER (current_header->oldgnu_header.realsize);
- return true;
+ file->stat_info->stat.st_size = max (0, realsize);
+ return 0 <= realsize;
}
/* Convert old GNU format sparse data to internal representation */
{
/* NOTE! st_size was initialized from the header
which actually contains archived size. The following fixes it */
+ off_t realsize = OFF_FROM_HEADER (current_header->star_in_header.realsize);
file->stat_info->archive_file_size = file->stat_info->stat.st_size;
- file->stat_info->stat.st_size =
- OFF_FROM_HEADER (current_header->star_in_header.realsize);
- return true;
+ file->stat_info->stat.st_size = max (0, realsize);
+ return 0 <= realsize;
}
/* Convert STAR format sparse data to internal representation */
if (!ISDIGIT (*arg))
return false;
+ errno = 0;
u = strtoumax (arg, &arg_lim, 10);
if (! (u <= maxval && errno != ERANGE) || *arg_lim)