summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2000-12-03 10:18:04 +0000
committerJim Meyering <jim@meyering.net>2000-12-03 10:18:04 +0000
commitd183ecddcd77fe02ed158ee6470ff4a8192ed763 (patch)
treeb8ba90d9e712aa39725f6571434bd7d5b541394c /src
parente30c09b4cb9b5e2d7a845029a98c40d61920a1ea (diff)
downloadcoreutils-d183ecddcd77fe02ed158ee6470ff4a8192ed763.tar.xz
Make od print valid addresses for offsets of 2^32 and larger. (cont'd)
(MAX_ADDRESS_LENGTH): Don't hard-code as a literal. Rather, define in terms of the type, off_t. (string_min): Declare to be of type size_t. (flag_dump_strings): Declare to be of type int. (print_s_char): Declare the n_bytes parameter and the local, `i', to be of type off_t. (print_char): Likewise. (print_s_short): Likewise. (print_short): Likewise. (print_int): Likewise. (print_long): Likewise. (print_long_long): Likewise. (print_float): Likewise. (print_double): Likewise. (print_long_double): Likewise. (dump_hexl_mode_trailer): Likewise. (print_named_ascii): Likewise. (print_ascii): Likewise. (write_block): Likewise. (print_ascii): Declare local, `print_function' with a prototype. Change a few `>' comparisons to the equivalent `<' form. (parse_options): Declare `tmp' to be of type uintmax_t. Use xstrtoumax, not xstrtoul. Fail if the specified offset if larger than OFF_T_MAX. (dump_strings): Declare local `i' to be of type size_t. Remove the now-unnecessary cast-to-off_t. (main) [IF_LINT]: Initialize desired_width to avoid a warning. Declare `tmp' to be of type uintmax_t. Use xstrtoumax, not xstrtoul. Fail if minimum string length is larger than SIZE_MAX. Fail if specified width is larger than ULONG_MAX.
Diffstat (limited to 'src')
-rw-r--r--src/od.c130
1 files changed, 66 insertions, 64 deletions
diff --git a/src/od.c b/src/od.c
index 7f7cec67d..26afa8128 100644
--- a/src/od.c
+++ b/src/od.c
@@ -153,16 +153,17 @@ static const char *const charname[33] =
/* A printf control string for printing a file offset. */
static const char *output_address_fmt_string;
-/* FIXME: make this the number of octal digits in an unsigned long. */
-#define MAX_ADDRESS_LENGTH 13
+/* The number of octal digits required to represent the largest off_t value. */
+#define MAX_ADDRESS_LENGTH \
+ ((sizeof (off_t) * BITSPERBYTE + BITSPERBYTE - 1) / 3)
/* Space for a normal address, a space, a pseudo address, parentheses
around the pseudo address, and a trailing zero byte. */
static char address_fmt_buffer[2 * MAX_ADDRESS_LENGTH + 4];
static char address_pad[MAX_ADDRESS_LENGTH + 1];
-static unsigned long int string_min;
-static unsigned long int flag_dump_strings;
+static size_t string_min;
+static int flag_dump_strings;
/* Non-zero if we should recognize the pre-POSIX non-option arguments
that specified at most one file and optional arguments specifying
@@ -359,10 +360,9 @@ lcm (unsigned int u, unsigned int v)
}
static void
-print_s_char (long unsigned int n_bytes, const char *block,
- const char *fmt_string)
+print_s_char (off_t n_bytes, const char *block, const char *fmt_string)
{
- int i;
+ off_t i;
for (i = n_bytes; i > 0; i--)
{
int tmp = (unsigned) *(const unsigned char *) block;
@@ -375,10 +375,9 @@ print_s_char (long unsigned int n_bytes, const char *block,
}
static void
-print_char (long unsigned int n_bytes, const char *block,
- const char *fmt_string)
+print_char (off_t n_bytes, const char *block, const char *fmt_string)
{
- int i;
+ off_t i;
for (i = n_bytes; i > 0; i--)
{
unsigned int tmp = *(const unsigned char *) block;
@@ -388,10 +387,9 @@ print_char (long unsigned int n_bytes, const char *block,
}
static void
-print_s_short (long unsigned int n_bytes, const char *block,
- const char *fmt_string)
+print_s_short (off_t n_bytes, const char *block, const char *fmt_string)
{
- int i;
+ off_t i;
for (i = n_bytes / sizeof (unsigned short); i > 0; i--)
{
int tmp = (unsigned) *(const unsigned short *) block;
@@ -404,10 +402,9 @@ print_s_short (long unsigned int n_bytes, const char *block,
}
static void
-print_short (long unsigned int n_bytes, const char *block,
- const char *fmt_string)
+print_short (off_t n_bytes, const char *block, const char *fmt_string)
{
- int i;
+ off_t i;
for (i = n_bytes / sizeof (unsigned short); i > 0; i--)
{
unsigned int tmp = *(const unsigned short *) block;
@@ -417,10 +414,9 @@ print_short (long unsigned int n_bytes, const char *block,
}
static void
-print_int (long unsigned int n_bytes, const char *block,
- const char *fmt_string)
+print_int (off_t n_bytes, const char *block, const char *fmt_string)
{
- int i;
+ off_t i;
for (i = n_bytes / sizeof (unsigned int); i > 0; i--)
{
unsigned int tmp = *(const unsigned int *) block;
@@ -430,10 +426,9 @@ print_int (long unsigned int n_bytes, const char *block,
}
static void
-print_long (long unsigned int n_bytes, const char *block,
- const char *fmt_string)
+print_long (off_t n_bytes, const char *block, const char *fmt_string)
{
- int i;
+ off_t i;
for (i = n_bytes / sizeof (unsigned long); i > 0; i--)
{
unsigned long tmp = *(const unsigned long *) block;
@@ -444,10 +439,9 @@ print_long (long unsigned int n_bytes, const char *block,
#ifdef HAVE_UNSIGNED_LONG_LONG
static void
-print_long_long (long unsigned int n_bytes, const char *block,
- const char *fmt_string)
+print_long_long (off_t n_bytes, const char *block, const char *fmt_string)
{
- int i;
+ off_t i;
for (i = n_bytes / sizeof (unsigned long long); i > 0; i--)
{
unsigned long long tmp = *(const unsigned long long *) block;
@@ -458,10 +452,9 @@ print_long_long (long unsigned int n_bytes, const char *block,
#endif
static void
-print_float (long unsigned int n_bytes, const char *block,
- const char *fmt_string)
+print_float (off_t n_bytes, const char *block, const char *fmt_string)
{
- int i;
+ off_t i;
for (i = n_bytes / sizeof (float); i > 0; i--)
{
float tmp = *(const float *) block;
@@ -471,10 +464,9 @@ print_float (long unsigned int n_bytes, const char *block,
}
static void
-print_double (long unsigned int n_bytes, const char *block,
- const char *fmt_string)
+print_double (off_t n_bytes, const char *block, const char *fmt_string)
{
- int i;
+ off_t i;
for (i = n_bytes / sizeof (double); i > 0; i--)
{
double tmp = *(const double *) block;
@@ -485,10 +477,9 @@ print_double (long unsigned int n_bytes, const char *block,
#ifdef HAVE_LONG_DOUBLE
static void
-print_long_double (long unsigned int n_bytes, const char *block,
- const char *fmt_string)
+print_long_double (off_t n_bytes, const char *block, const char *fmt_string)
{
- int i;
+ off_t i;
for (i = n_bytes / sizeof (LONG_DOUBLE); i > 0; i--)
{
LONG_DOUBLE tmp = *(const LONG_DOUBLE *) block;
@@ -500,9 +491,9 @@ print_long_double (long unsigned int n_bytes, const char *block,
#endif
static void
-dump_hexl_mode_trailer (long unsigned int n_bytes, const char *block)
+dump_hexl_mode_trailer (off_t n_bytes, const char *block)
{
- int i;
+ off_t i;
fputs (" >", stdout);
for (i = n_bytes; i > 0; i--)
{
@@ -515,10 +506,10 @@ dump_hexl_mode_trailer (long unsigned int n_bytes, const char *block)
}
static void
-print_named_ascii (long unsigned int n_bytes, const char *block,
+print_named_ascii (off_t n_bytes, const char *block,
const char *unused_fmt_string ATTRIBUTE_UNUSED)
{
- int i;
+ off_t i;
for (i = n_bytes; i > 0; i--)
{
unsigned int c = *(const unsigned char *) block;
@@ -542,10 +533,10 @@ print_named_ascii (long unsigned int n_bytes, const char *block,
}
static void
-print_ascii (long unsigned int n_bytes, const char *block,
+print_ascii (off_t n_bytes, const char *block,
const char *unused_fmt_string ATTRIBUTE_UNUSED)
{
- int i;
+ off_t i;
for (i = n_bytes; i > 0; i--)
{
unsigned int c = *(const unsigned char *) block;
@@ -647,7 +638,7 @@ decode_one_format (const char *s_orig, const char *s, const char **next,
enum output_format fmt;
const char *pre_fmt_string;
char *fmt_string;
- void (*print_function) ();
+ void (*print_function) PARAMS ((off_t, const char *, const char *));
const char *p;
unsigned int c;
unsigned int field_width = 0;
@@ -697,7 +688,7 @@ decode_one_format (const char *s_orig, const char *s, const char **next,
size = sizeof (int);
else
{
- if (size > MAX_INTEGRAL_TYPE_SIZE
+ if (MAX_INTEGRAL_TYPE_SIZE < size
|| integral_type_size[size] == NO_SIZE)
{
error (0, 0, _("invalid type string `%s';\n\
@@ -1005,7 +996,7 @@ skip (off_t n_skip)
n_skip and go on to the next file. */
if (S_ISREG (file_stats.st_mode))
{
- if (n_skip >= file_stats.st_size)
+ if (file_stats.st_size <= n_skip)
{
n_skip -= file_stats.st_size;
if (in_stream != stdin && fclose (in_stream) == EOF)
@@ -1028,10 +1019,10 @@ skip (off_t n_skip)
/* Seek didn't work or wasn't attempted; position the file pointer
by reading. */
- for (j = n_skip / BUFSIZ; j >= 0; j--)
+ for (j = n_skip / BUFSIZ; 0 <= j; j--)
{
char buf[BUFSIZ];
- size_t n_bytes_to_read = (j > 0
+ size_t n_bytes_to_read = (0 < j
? BUFSIZ
: n_skip % BUFSIZ);
size_t n_bytes_read;
@@ -1091,7 +1082,7 @@ format_address_label (off_t address)
only when it has not been padded to length BYTES_PER_BLOCK. */
static void
-write_block (off_t current_offset, long unsigned int n_bytes,
+write_block (off_t current_offset, off_t n_bytes,
const char *prev_block, const char *curr_block)
{
static int first = 1;
@@ -1256,7 +1247,7 @@ read_block (size_t n, char *block, size_t *n_bytes_in_buffer)
{
int err;
- assert (n > 0 && n <= bytes_per_block);
+ assert (0 < n && n <= bytes_per_block);
*n_bytes_in_buffer = 0;
@@ -1333,7 +1324,7 @@ parse_old_offset (const char *s)
int radix;
off_t offset;
enum strtol_error s_err;
- long unsigned int tmp;
+ uintmax_t tmp;
if (*s == '\0')
return -1;
@@ -1355,12 +1346,15 @@ parse_old_offset (const char *s)
radix = 8;
}
- s_err = xstrtoul (s, NULL, radix, &tmp, "Bb");
+ s_err = xstrtoumax (s, NULL, radix, &tmp, "Bb");
if (s_err != LONGINT_OK)
{
STRTOL_FAIL_WARN (s, _("old-style offset"), s_err);
return -1;
}
+ if (OFF_T_MAX < tmp)
+ error (EXIT_FAILURE, 0,
+ _("%s is larger than the maximum file size on this system"), s);
offset = tmp;
return offset;
}
@@ -1477,15 +1471,14 @@ dump_strings (void)
err = 0;
while (1)
{
- unsigned int i;
+ size_t i;
int c;
/* See if the next `string_min' chars are all printing chars. */
tryline:
if (limit_bytes_to_format
- && address >= (n_bytes_to_skip + max_bytes_to_format -
- (off_t) string_min))
+ && address >= (n_bytes_to_skip + max_bytes_to_format - string_min))
break;
for (i = 0; i < string_min; i++)
@@ -1610,7 +1603,7 @@ main (int argc, char **argv)
unsigned int i;
unsigned int l_c_m;
unsigned int address_pad_len;
- unsigned long int desired_width;
+ unsigned long int desired_width IF_LINT (= 0);
int width_specified = 0;
int n_failed_decodes = 0;
int err;
@@ -1661,7 +1654,7 @@ main (int argc, char **argv)
while ((c = getopt_long (argc, argv, "abcdfhilos::xw::A:j:N:t:v",
long_options, NULL)) != -1)
{
- unsigned long int tmp;
+ uintmax_t tmp;
enum strtol_error s_err;
switch (c)
@@ -1702,7 +1695,7 @@ it must be one character from [doxn]"),
break;
case 'j':
- s_err = xstrtoul (optarg, NULL, 0, &tmp, "bkm");
+ s_err = xstrtoumax (optarg, NULL, 0, &tmp, "bkm");
n_bytes_to_skip = tmp;
if (s_err != LONGINT_OK)
STRTOL_FATAL_ERROR (optarg, _("skip argument"), s_err);
@@ -1711,17 +1704,15 @@ it must be one character from [doxn]"),
case 'N':
limit_bytes_to_format = 1;
- /* FIXME: if off_t is long long and that's an 8-byte type,
- use xstrtouq here. */
- s_err = xstrtoul (optarg, NULL, 0, &tmp, "bkm");
+ s_err = xstrtoumax (optarg, NULL, 0, &tmp, "bkm");
max_bytes_to_format = tmp;
if (s_err != LONGINT_OK)
STRTOL_FATAL_ERROR (optarg, _("limit argument"), s_err);
- if (tmp > LONG_MAX)
+ if (OFF_T_MAX < tmp)
error (EXIT_FAILURE, 0,
- _("specified number of bytes `%s' is larger than \
-the maximum\nrepresentable value of type `long'"), optarg);
+ _("%s is larger than the maximum file size on this system"),
+ optarg);
break;
case 's':
@@ -1729,11 +1720,18 @@ the maximum\nrepresentable value of type `long'"), optarg);
string_min = 3;
else
{
- s_err = xstrtoul (optarg, NULL, 0, &string_min, "bkm");
+ s_err = xstrtoumax (optarg, NULL, 0, &tmp, "bkm");
if (s_err != LONGINT_OK)
STRTOL_FATAL_ERROR (optarg, _("minimum string length"), s_err);
+
+ /* The minimum string length may be no larger than SIZE_MAX,
+ since we may allocate a buffer of this size. */
+ if (SIZE_MAX < tmp)
+ error (EXIT_FAILURE, 0, _("%s is too large"), optarg);
+
+ string_min = tmp;
}
- ++flag_dump_strings;
+ flag_dump_strings = 1;
break;
case 't':
@@ -1783,9 +1781,13 @@ the maximum\nrepresentable value of type `long'"), optarg);
}
else
{
- s_err = xstrtoul (optarg, NULL, 10, &desired_width, "");
+ uintmax_t w_tmp;
+ s_err = xstrtoumax (optarg, NULL, 10, &w_tmp, "");
if (s_err != LONGINT_OK)
STRTOL_FATAL_ERROR (optarg, _("width specification"), s_err);
+ if (ULONG_MAX < w_tmp)
+ error (EXIT_FAILURE, 0, _("%s is too large"), optarg);
+ desired_width = w_tmp;
}
break;