summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/join.c13
-rw-r--r--src/sort.c9
-rw-r--r--src/uniq.c25
3 files changed, 26 insertions, 21 deletions
diff --git a/src/join.c b/src/join.c
index 77a389604..b113c543b 100644
--- a/src/join.c
+++ b/src/join.c
@@ -599,7 +599,8 @@ add_field (int file, size_t field)
/* Convert a string of decimal digits, STR (the 1-based join field number),
to an integral value. Upon successful conversion, return one less
- (the zero-based field number). If it cannot be converted, give a
+ (the zero-based field number). Silently convert too-large values
+ to SIZE_MAX - 1. Otherwise, if a value cannot be converted, give a
diagnostic and exit. */
static size_t
@@ -607,16 +608,12 @@ string_to_join_field (char const *str)
{
size_t result;
unsigned long int val;
+ verify (SIZE_MAX <= ULONG_MAX);
strtol_error s_err = xstrtoul (str, NULL, 10, &val, "");
if (s_err == LONGINT_OVERFLOW || (s_err == LONGINT_OK && SIZE_MAX < val))
- {
- error (EXIT_FAILURE, 0,
- _("value %s is so large that it is not representable"),
- quote (str));
- }
-
- if (s_err != LONGINT_OK || val == 0)
+ val = SIZE_MAX;
+ else if (s_err != LONGINT_OK || val == 0)
error (EXIT_FAILURE, 0, _("invalid field number: %s"), quote (str));
result = val - 1;
diff --git a/src/sort.c b/src/sort.c
index feaf5a5bc..f03237cb3 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -2170,7 +2170,8 @@ check_ordering_compatibility (void)
/* Parse the leading integer in STRING and store the resulting value
(which must fit into size_t) into *VAL. Return the address of the
- suffix after the integer. If MSGID is NULL, return NULL after
+ suffix after the integer. If the value is too large, silently
+ substitute SIZE_MAX. If MSGID is NULL, return NULL after
failure; otherwise, report MSGID and exit on failure. */
static char const *
@@ -2189,10 +2190,8 @@ parse_field_count (char const *string, size_t *val, char const *msgid)
/* Fall through. */
case LONGINT_OVERFLOW:
case LONGINT_OVERFLOW | LONGINT_INVALID_SUFFIX_CHAR:
- if (msgid)
- error (SORT_FAILURE, 0, _("%s: count `%.*s' too large"),
- _(msgid), (int) (suffix - string), string);
- return NULL;
+ *val = SIZE_MAX;
+ break;
case LONGINT_INVALID:
if (msgid)
diff --git a/src/uniq.c b/src/uniq.c
index 0d60961f6..6c38ed807 100644
--- a/src/uniq.c
+++ b/src/uniq.c
@@ -172,17 +172,26 @@ Fields are skipped before chars.\n\
exit (status);
}
-/* Convert OPT to size_t, reporting an error using MSGID if it does
- not fit. */
+/* Convert OPT to size_t, reporting an error using MSGID if OPT is
+ invalid. Silently convert too-large values to SIZE_MAX. */
static size_t
size_opt (char const *opt, char const *msgid)
{
unsigned long int size;
- if (xstrtoul (opt, NULL, 10, &size, "") != LONGINT_OK
- || SIZE_MAX < size)
- error (EXIT_FAILURE, 0, "%s: %s", opt, _(msgid));
- return size;
+ verify (SIZE_MAX <= ULONG_MAX);
+
+ switch (xstrtoul (opt, NULL, 10, &size, ""))
+ {
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ break;
+
+ default:
+ error (EXIT_FAILURE, 0, "%s: %s", opt, _(msgid));
+ }
+
+ return MIN (size, SIZE_MAX);
}
/* Given a linebuffer LINE,
@@ -472,8 +481,8 @@ main (int argc, char **argv)
skip_fields = 0;
if (!DECIMAL_DIGIT_ACCUMULATE (skip_fields, optc - '0', size_t))
- error (EXIT_FAILURE, 0, "%s",
- _("invalid number of fields to skip"));
+ skip_fields = SIZE_MAX;
+
skip_field_option_type = SFO_OBSOLETE;
}
break;