Browse Source

Lint cleanup.
(from_chars): Report out-of-range values more precisely.
(off_from_chars): Do not allow negative offsets.
(uid_from_chars): Allow negative uids.

Paul Eggert 25 years ago
parent
commit
aa904fd8ec
1 changed files with 52 additions and 29 deletions
  1. 52 29
      src/list.c

+ 52 - 29
src/list.c

@@ -222,7 +222,7 @@ list_archive (void)
 	    }
 	}
       if (multi_volume_option)
-	assign_string (&save_name, NULL);
+	assign_string (&save_name, 0);
       fputc ('\n', stdlis);
       fflush (stdlis);
       return;
@@ -243,7 +243,7 @@ list_archive (void)
   skip_file (current_stat.st_size);
 
   if (multi_volume_option)
-    assign_string (&save_name, NULL);
+    assign_string (&save_name, 0);
 }
 
 /*-----------------------------------------------------------------------.
@@ -262,7 +262,7 @@ list_archive (void)
    bytes in the header as type char.  I think the type char was unsigned
    on the PDP-11, but it's signed on the Next and Sun.  It looks like the
    sources to BSD tar were never changed to compute the checksum
-   currectly, so both the Sun and Next add the bytes of the header as
+   correctly, so both the Sun and Next add the bytes of the header as
    signed chars.  This doesn't cause a problem until you get a file with
    a name containing characters with the high bit set.  So read_header
    computes two checksums -- signed and unsigned.  */
@@ -293,7 +293,7 @@ read_header (void)
       unsigned_sum = 0;
       signed_sum = 0;
       p = header->buffer;
-      for (i = sizeof (*header); i-- != 0;)
+      for (i = sizeof *header; i-- != 0;)
 	{
 	  unsigned_sum += (unsigned char) *p;
 	  signed_sum += signed_char (*p++);
@@ -304,7 +304,7 @@ read_header (void)
 
       /* Adjust checksum to count the "chksum" field as blanks.  */
 
-      for (i = sizeof (header->header.chksum); i-- != 0;)
+      for (i = sizeof header->header.chksum; i-- != 0;)
 	{
 	  unsigned_sum -= (unsigned char) header->header.chksum[i];
 	  signed_sum -= signed_char (header->header.chksum[i]);
@@ -313,9 +313,8 @@ read_header (void)
       signed_sum += ' ' * sizeof header->header.chksum;
 
       parsed_sum = from_chars (header->header.chksum,
-			       sizeof header->header.chksum,
-			       (char *) 0, (uintmax_t) 0,
-			       (uintmax_t) TYPE_MAXIMUM (int));
+			       sizeof header->header.chksum, 0,
+			       (uintmax_t) 0, (uintmax_t) TYPE_MAXIMUM (int));
       if (parsed_sum == (uintmax_t) -1)
 	return HEADER_FAILURE;
 
@@ -344,12 +343,12 @@ read_header (void)
 	  size = current_stat.st_size;
 	  if (size != current_stat.st_size)
 	    FATAL_ERROR ((0, 0, _("Memory exhausted")));
-	  bp = *longp = (char *) xmalloc (size);
+	  bp = *longp = xmalloc (size);
 
 	  for (; size > 0; size -= written)
 	    {
 	      data_block = find_next_block ();
-	      if (data_block == NULL)
+	      if (! data_block)
 		{
 		  ERROR ((0, 0, _("Unexpected EOF on archive file")));
 		  break;
@@ -540,7 +539,12 @@ from_chars (char const *where0, size_t digs, char const *type,
       do
 	{
 	  if (value << LG_8 >> LG_8 != value)
-	    goto out_of_range;
+	    {
+	      ERROR ((0, 0,
+		      _("Archive octal string `%.*s' is out of %s range"),
+		      (int) digs, where0, type));
+	      return -1;
+	    }
 	  value = (value << LG_8) | (*where++ - '0');
 	}
       while (where != lim && ISODIGIT (*where));
@@ -563,7 +567,12 @@ from_chars (char const *where0, size_t digs, char const *type,
 	     && (dig = base64_map[(unsigned char) *where]) < 64)
 	{
 	  if (value << LG_64 >> LG_64 != value)
-	    goto out_of_range;
+	    {
+	      ERROR ((0, 0,
+		      _("Archive signed base 64 string `%.*s' is out of %s range"),
+		      (int) digs, where0, type));
+	      return -1;
+	    }
 	  value = (value << LG_64) | dig;
 	  where++;
 	}
@@ -578,7 +587,7 @@ from_chars (char const *where0, size_t digs, char const *type,
 
 	  if (!o)
 	    {
-	      o = clone_quoting_options ((struct quoting_options *) 0);
+	      o = clone_quoting_options (0);
 	      set_quoting_style (o, c_quoting_style);
 	    }
 
@@ -586,7 +595,7 @@ from_chars (char const *where0, size_t digs, char const *type,
 	    lim--;
 	  quotearg_buffer (buf, sizeof buf, where0, lim - where, o);
 	  ERROR ((0, 0,
-		  _("Header contains `%.*s' where numeric %s value expected"),
+		  _("Archive contains `%.*s' where numeric %s value expected"),
 		  (int) sizeof buf, buf, type));
 	}
 
@@ -596,10 +605,22 @@ from_chars (char const *where0, size_t digs, char const *type,
   if (value <= (negative ? minus_minval : maxval))
     return negative ? -value : value;
 
- out_of_range:
   if (type)
-    ERROR ((0, 0, _("Numeric value `%.*s' is out of range for %s"),
-	    (int) digs, where0, type));
+    {
+      char minval_buf[UINTMAX_STRSIZE_BOUND + 1];
+      char maxval_buf[UINTMAX_STRSIZE_BOUND];
+      char value_buf[UINTMAX_STRSIZE_BOUND + 1];
+      char *minval_string = STRINGIFY_BIGINT (minus_minval, minval_buf + 1);
+      char *value_string = STRINGIFY_BIGINT (value, value_buf + 1);
+      if (negative)
+	*--value_string = '-';
+      if (minus_minval)
+	*--minval_string = '-';
+      ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"),
+	      value_string, type,
+	      minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));
+    }
+
   return -1;
 }
 
@@ -651,8 +672,9 @@ mode_from_chars (const char *p, size_t s)
 off_t
 off_from_chars (const char *p, size_t s)
 {
-  return from_chars (p, s, "off_t",
-		     - (uintmax_t) TYPE_MINIMUM (off_t),
+  /* Negative offsets are not allowed in tar files, so invoke
+     from_chars with minimum value 0, not TYPE_MINIMUM (off_t).  */
+  return from_chars (p, s, "off_t", (uintmax_t) 0,
 		     (uintmax_t) TYPE_MAXIMUM (off_t));
 }
 
@@ -674,7 +696,8 @@ time_from_chars (const char *p, size_t s)
 uid_t
 uid_from_chars (const char *p, size_t s)
 {
-  return from_chars (p, s, "uid_t", (uintmax_t) 0,
+  return from_chars (p, s, "uid_t",
+		     - (uintmax_t) TYPE_MINIMUM (uid_t),
 		     (uintmax_t) TYPE_MAXIMUM (uid_t));
 }
 
@@ -723,8 +746,8 @@ isotime (time_t time)
     }
   else
     {
-      /* The timestamp cannot be broken down, most likely because it
-	 is a huge timestamp.  Convert it as an integer,
+      /* The time stamp cannot be broken down, most likely because it
+	 is out of range.  Convert it as an integer,
 	 right-adjusted in a field with the same width as the usual
 	 19-byte 4-year ISO time format.  */
       uintmax_t abstime = time < 0 ? - (uintmax_t) time : time;
@@ -796,7 +819,7 @@ void
 print_header (void)
 {
   char modes[11];
-  char const *timestamp;
+  char const *time_stamp;
   /* These hold formatted ints.  */
   char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
   char *user, *group;
@@ -885,7 +908,7 @@ print_header (void)
 
       decode_mode (current_stat.st_mode, modes + 1);
 
-      /* Timestamp.  */
+      /* Time stamp.  */
 
       longie = current_stat.st_mtime;
 #if USE_OLD_CTIME
@@ -893,16 +916,16 @@ print_header (void)
 	char *ct = ctime (&longie);
 	if (ct)
 	  {
-	    timestamp = ct + 4;
+	    time_stamp = ct + 4;
 	    for (ct += 16; ct[4] != '\n'; ct++)
 	      ct[0] = ct[4];
 	    ct[0] = '\0';
 	  }
 	else
-	  timestamp = "??? ?? ??:?? ????";
+	  time_stamp = "??? ?? ??:?? ????";
       }
 #else
-      timestamp = isotime (longie);
+      time_stamp = isotime (longie);
 #endif
 
       /* User and group names.  */
@@ -953,7 +976,7 @@ print_header (void)
 	ugswidth = pad;
 
       fprintf (stdlis, "%s %s/%s %*s%s %s",
-	       modes, user, group, ugswidth - pad, "", size, timestamp);
+	       modes, user, group, ugswidth - pad, "", size, time_stamp);
 
       name = quote_copy_string (current_file_name);
       if (name)
@@ -1079,7 +1102,7 @@ skip_file (off_t size)
   while (size > 0)
     {
       x = find_next_block ();
-      if (x == NULL)
+      if (! x)
 	FATAL_ERROR ((0, 0, _("Unexpected EOF on archive file")));
 
       set_next_block_after (x);