Eric Blake <[EMAIL PROTECTED]> wrote:
> src/incremen.c makes the invalid assumption that ino_t is no bigger than
> long. But since the 1.5.x release of cygwin (keyed by
> __CYGWIN_USE_BIG_TYPES__ in headers), long is 4 bytes, while ino_t is 8
> bytes. This bug appears to be the cause of the breakage of test 20 of
> tar-1.15.1 on cygwin, since --listed output was being truncated.
Thanks for reporting. Please try attached patch.
Regards,
Sergey
Index: src/incremen.c
===================================================================
RCS file: /cvsroot/tar/tar/src/incremen.c,v
retrieving revision 1.29
diff -p -u -r1.29 incremen.c
--- src/incremen.c 22 Jun 2005 06:24:39 -0000 1.29
+++ src/incremen.c 16 Aug 2005 08:40:00 -0000
@@ -309,6 +309,30 @@ get_directory_contents (char *dir_name,
+static uintmax_t
+getnum (char *p, char **endp)
+{
+ uintmax_t n = 0;
+
+ while (*p && isspace (*p))
+ p++;
+
+ for (;ISDIGIT (*p); p++)
+ {
+ uintmax_t n10 = n * 10;
+ uintmax_t c = n10 + *p - '0';
+ if (n10 / 10 != n || c < n10)
+ {
+ errno = ERANGE;
+ n = -1;
+ break;
+ }
+ n = c;
+ }
+ *endp = p;
+ return n;
+}
+
static FILE *listed_incremental_stream;
void
@@ -344,8 +368,9 @@ read_directory_file (void)
char *ebuf;
int n;
long lineno = 1;
- unsigned long u = (errno = 0, strtoul (buf, &ebuf, 10));
+ uintmax_t u = (errno = 0, strtoul (buf, &ebuf, 10));
time_t t = u;
+
if (buf == ebuf || (u == 0 && errno == EINVAL))
ERROR ((0, 0, "%s:1: %s", quotearg_colon (listed_incremental_option),
_("Invalid time stamp")));
@@ -373,8 +398,8 @@ read_directory_file (void)
buf[n - 1] = '\0';
errno = 0;
- dev = u = strtoul (strp, &ebuf, 10);
- if (strp == ebuf || (u == 0 && errno == EINVAL))
+ dev = u = getnum (strp, &ebuf);
+ if (!isspace (*ebuf))
ERROR ((0, 0, "%s:%ld: %s",
quotearg_colon (listed_incremental_option), lineno,
_("Invalid device number")));
@@ -385,8 +410,8 @@ read_directory_file (void)
strp = ebuf;
errno = 0;
- ino = u = strtoul (strp, &ebuf, 10);
- if (strp == ebuf || (u == 0 && errno == EINVAL))
+ ino = u = getnum (strp, &ebuf);
+ if (!isspace (*ebuf))
ERROR ((0, 0, "%s:%ld: %s",
quotearg_colon (listed_incremental_option), lineno,
_("Invalid inode number")));
@@ -419,11 +444,15 @@ write_directory_file_entry (void *entry,
if (directory->found)
{
int e;
+ char buf[UINTMAX_STRSIZE_BOUND];
char *str = quote_copy_string (directory->name);
- fprintf (fp, "+%lu %lu %s\n" + ! directory->nfs,
- (unsigned long) directory->device_number,
- (unsigned long) directory->inode_number,
- str ? str : directory->name);
+
+ if (directory->nfs)
+ fprintf (fp, "+");
+ fprintf (fp, "%s ", umaxtostr (directory->device_number, buf));
+ fprintf (fp, "%s ", umaxtostr (directory->inode_number, buf));
+ fprintf (fp, "%s\n", str ? str : directory->name);
+
e = errno;
if (str)
free (str);
_______________________________________________
Bug-tar mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-tar