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

Reply via email to