diff options
author | Pádraig Brady <P@draigBrady.com> | 2014-12-16 12:36:39 +0000 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2014-12-19 11:56:20 +0000 |
commit | 6894816c653adef54f3a85becbf75a865d6d39d6 (patch) | |
tree | 82bb3126d3c8cfaeebc950bd03a52a4f5e0f056c /src/pr.c | |
parent | 178f8e79dcd1e0b8bbb3b04da664d05eaae56186 (diff) | |
download | coreutils-6894816c653adef54f3a85becbf75a865d6d39d6.tar.xz |
diagnose too-large numbers better
Following on from commit v8.23-82-gaddae94, consistently diagnose
numbers that are too large, so as to distinguish from other errors,
and make the limits obvious.
* gl/modules/xdectoint: A new module implementing xdecto[iu]max(),
which handles the common case of parsing a bounded integer and
exiting with a diagnostic on error.
* gl/lib/xdectoimax.c: The signed variant.
* gl/lib/xdectoint.c: The parameterized implementation.
* gl/lib/xdectoint.h: The interface.
* gl/lib/xdectoumax.c: The unsigned variant.
* bootstrap.conf: Reference the new module.
* cfg.mk (exclude_file_name_regexp--sc_require_config_h_first):
Exclude the parameterized templates.
* src/csplit.c: Output EOVERFLOW or ERANGE errors if appropriate.
* src/fmt.c: Likewise.
* src/fold.c: Likewise.
* src/head.c: Likewise.
* src/ls.c: Likewise.
* src/nl.c: Likewise.
* src/nproc.c: Likewise.
* src/shred.c: Likewise.
* src/shuf.c: Likewise.
* src/stdbuf.c: Likewise.
* src/stty.c: Likewise.
* src/tail.c: Likewise.
* src/truncate.c: Likewise.
* src/split.c: Likewise.
* src/pr.c: Likewise.
* tests/pr/pr-tests.pl: Adjust to avoid matching errno diagnostic.
* tests/fmt/base.pl: Likewise.
* tests/split/l-chunk.sh: Likewise.
* tests/misc/shred-negative.sh: Likewise.
* tests/misc/tail.pl: Likewise. Also remove the redundant
existing ERR_SUBST from test err-6.
* tests/ls/hex-option.sh: Check HEX/OCT options.
* tests/misc/shred-size.sh: Likewise.
* tests/misc/stty-row-col.sh: Likewise.
Diffstat (limited to 'src/pr.c')
-rw-r--r-- | src/pr.c | 98 |
1 files changed, 35 insertions, 63 deletions
@@ -322,6 +322,7 @@ #include "stdio--.h" #include "strftime.h" #include "xstrtol.h" +#include "xdectoint.h" /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" @@ -424,6 +425,8 @@ static bool skip_to_page (uintmax_t page); static void print_header (void); static void pad_across_to (int position); static void add_line_number (COLUMN *p); +static void getoptnum (const char *n_str, int min, int *num, + const char *errfmt); static void getoptarg (char *arg, char switch_char, char *character, int *number); static void print_files (int number_of_files, char **av); @@ -820,18 +823,12 @@ first_last_page (int oi, char c, char const *pages) /* Parse column count string S, and if it's valid (1 or larger and within range of the type of 'columns') set the global variables - columns and explicit_columns and return true. - Otherwise, exit with a diagnostic. */ + columns and explicit_columns. Otherwise, exit with a diagnostic. */ + static void parse_column_count (char const *s) { - long int tmp_long; - if (xstrtol (s, NULL, 10, &tmp_long, "") != LONGINT_OK - || !(1 <= tmp_long && tmp_long <= INT_MAX)) - error (EXIT_FAILURE, 0, - _("invalid number of columns: %s"), quote (s)); - - columns = tmp_long; + getoptnum (s, 1, &columns, _("invalid number of columns")); explicit_columns = true; } @@ -966,18 +963,9 @@ main (int argc, char **argv) join_lines = true; break; case 'l': - { - long int tmp_long; - if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK - || tmp_long <= 0 || tmp_long > INT_MAX) - { - error (EXIT_FAILURE, 0, - _("'-l PAGE_LENGTH' invalid number of lines: %s"), - quote (optarg)); - } - lines_per_page = tmp_long; - break; - } + getoptnum (optarg, 1, &lines_per_page, + _("'-l PAGE_LENGTH' invalid number of lines")); + break; case 'm': parallel_files = true; storing_columns = false; @@ -990,28 +978,13 @@ main (int argc, char **argv) break; case 'N': skip_count = false; - { - long int tmp_long; - if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK - || tmp_long > INT_MAX) - { - error (EXIT_FAILURE, 0, - _("'-N NUMBER' invalid starting line number: %s"), - quote (optarg)); - } - start_line_num = tmp_long; - break; - } + getoptnum (optarg, INT_MIN, &start_line_num, + _("'-N NUMBER' invalid starting line number")); + break; case 'o': - { - long int tmp_long; - if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK - || tmp_long < 0 || tmp_long > INT_MAX) - error (EXIT_FAILURE, 0, - _("'-o MARGIN' invalid line offset: %s"), quote (optarg)); - chars_per_margin = tmp_long; - break; - } + getoptnum (optarg, 0, &chars_per_margin, + _("'-o MARGIN' invalid line offset")); + break; case 'r': ignore_failed_opens = true; break; @@ -1045,29 +1018,19 @@ main (int argc, char **argv) old_options = true; old_w = true; { - long int tmp_long; - if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK - || tmp_long <= 0 || tmp_long > INT_MAX) - error (EXIT_FAILURE, 0, - _("'-w PAGE_WIDTH' invalid number of characters: %s"), - quote (optarg)); - if (!truncate_lines) - chars_per_line = tmp_long; - break; + int tmp_cpl; + getoptnum (optarg, 1, &tmp_cpl, + _("'-w PAGE_WIDTH' invalid number of characters")); + if (! truncate_lines) + chars_per_line = tmp_cpl; } + break; case 'W': old_w = false; /* dominates -w */ truncate_lines = true; - { - long int tmp_long; - if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK - || tmp_long <= 0 || tmp_long > INT_MAX) - error (EXIT_FAILURE, 0, - _("'-W PAGE_WIDTH' invalid number of characters: %s"), - quote (optarg)); - chars_per_line = tmp_long; - break; - } + getoptnum (optarg, 1, &chars_per_line, + _("'-W PAGE_WIDTH' invalid number of characters")); + break; case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); default: @@ -1173,6 +1136,15 @@ main (int argc, char **argv) return failed_opens ? EXIT_FAILURE : EXIT_SUCCESS; } +/* Parse numeric arguments, ensuring MIN <= number <= INT_MAX. */ + +static void +getoptnum (const char *n_str, int min, int *num, const char *err) +{ + intmax_t tnum = xdectoimax (n_str, min, INT_MAX, "", err, 0); + *num = tnum; +} + /* Parse options of the form -scNNN. Example: -nck, where 'n' is the option, c is the optional number @@ -1188,9 +1160,9 @@ getoptarg (char *arg, char switch_char, char *character, int *number) { long int tmp_long; if (xstrtol (arg, NULL, 10, &tmp_long, "") != LONGINT_OK - || tmp_long <= 0 || tmp_long > INT_MAX) + || tmp_long <= 0 || INT_MAX < tmp_long) { - error (0, 0, + error (0, INT_MAX < tmp_long ? EOVERFLOW : errno, _("'-%c' extra characters or invalid number in the argument: %s"), switch_char, quote (arg)); usage (EXIT_FAILURE); |