From aa904fd8ec95f5d23db78b3dd81a1f7aeb18035d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 23 Aug 1999 09:55:55 +0000 Subject: [PATCH] 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. --- src/list.c | 81 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 29 deletions(-) diff --git a/src/list.c b/src/list.c index 474651c..5067a86 100644 --- a/src/list.c +++ b/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); -- 2.45.2