summaryrefslogtreecommitdiff
path: root/src/uniq.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2006-12-13 22:03:54 +0100
committerJim Meyering <jim@meyering.net>2006-12-13 22:03:54 +0100
commitec95137cc376119f634610a7683a296fc7b78ea4 (patch)
tree52d315f085e18022db44722d7e58f3e4635d84d9 /src/uniq.c
parentae3ee95eb8372ec5947e3c790c6ea77bc703c160 (diff)
downloadcoreutils-ec95137cc376119f634610a7683a296fc7b78ea4.tar.xz
Remove some arbitrary restrictions on size fields,
so that commands like "sort -k 18446744073709551616" no longer fail merely because 18446744073709551616 doesn't fit in uintmax_t. The trick is that these fields can all be treated as effectively infinity; their exact values don't matter, since no internal buffer can be that long. * src/join.c (string_to_join_field): Verify that SIZE_MAX <= ULONG_MAX if the code assumes this. Silently truncate too-large values to SIZE_MAX, as the remaining code will do the right thing in this case. * src/sort.c (parse_field_count): Likewise. * src/uniq.c (size_opt, main): Likewise. * tests/join/Test.pm (bigfield): New test. * tests/sort/Test.pm (bigfield): New test. * tests/uniq/Test.pm (121): New test. Signed-off-by: Jim Meyering <jim@meyering.net>
Diffstat (limited to 'src/uniq.c')
-rw-r--r--src/uniq.c25
1 files changed, 17 insertions, 8 deletions
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;