I installed the attached patches to fix some minor glitches with
programs like 'shuf' failing to reject invalid arguments like '-n 0x'
where the trailing 'x' is ignored. The last two patches do the real
work; the others are minor cleanups.
>From d4cbfaeca1e838a0d0373adfbd133a9f5eaa8e87 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 22 Oct 2019 11:34:56 -0700
Subject: [PATCH 1/5] build: re-enable type-limits checking
* configure.ac: When --enable-gcc-warnings is used, omit
-Wno-type-limits. The need for -Wno-type-limits has passed, now
that intprops.h uses builtin primitives for GCC 5 and later, given
that recent GCCs issue type-limits warnings only for non-constant
expressions. --enable-gcc-warnings is not intended for use with
old compilers, so we can drop -Wno-type-limits now.
---
configure.ac | 2 --
1 file changed, 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index d90c710e3..292ae0bf2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -134,7 +134,6 @@ if test "$gl_gcc_warnings" = yes; then
nw="$nw -Wswitch-enum" # Too many warnings for now
nw="$nw -Wswitch-default" # Too many warnings for now
nw="$nw -Wstack-protector" # not worth working around
- nw="$nw -Wtype-limits" # False alarms for portable code
nw="$nw -Wformat-overflow=2" # False alarms due to GCC bug 80776
nw="$nw -Wformat-truncation=2" # False alarm in ls.c, probably related
# things I might fix soon:
@@ -155,7 +154,6 @@ if test "$gl_gcc_warnings" = yes; then
gl_WARN_ADD([$w])
done
gl_WARN_ADD([-Wno-sign-compare]) # Too many warnings for now
- gl_WARN_ADD([-Wno-type-limits]) # False alarms for portable code
gl_WARN_ADD([-Wno-unused-parameter]) # Too many warnings for now
gl_WARN_ADD([-Wno-format-nonliteral])
--
2.21.0
>From 6778871f67c6a66aacc76b0a63ff26c8b72dce87 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 22 Oct 2019 12:52:52 -0700
Subject: [PATCH 2/5] =?UTF-8?q?build:=20don=E2=80=99t=20worry=20about=20lo?=
=?UTF-8?q?gical-op=20checking?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* configure.ac: Remove code tailoring --enable-gcc-warnings
to GCC 4.7 and earlier, as developers no longer need to worry
about GCCs that old.
---
configure.ac | 6 ------
1 file changed, 6 deletions(-)
diff --git a/configure.ac b/configure.ac
index 292ae0bf2..18c5a99bd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,7 +128,6 @@ if test "$gl_gcc_warnings" = yes; then
nw="$nw -Wunreachable-code" # Too many warnings for now
nw="$nw -Wpadded" # Our structs are not padded
nw="$nw -Wredundant-decls" # openat.h declares e.g., mkdirat
- nw="$nw -Wlogical-op" # Too many warnings until GCC 4.8.0
nw="$nw -Wformat-nonliteral" # who.c and pinky.c strftime uses
nw="$nw -Wnested-externs" # use of XARGMATCH/verify_function__
nw="$nw -Wswitch-enum" # Too many warnings for now
@@ -157,11 +156,6 @@ if test "$gl_gcc_warnings" = yes; then
gl_WARN_ADD([-Wno-unused-parameter]) # Too many warnings for now
gl_WARN_ADD([-Wno-format-nonliteral])
- # Enable this warning only with gcc-4.8 and newer. Before that
- # bounds checking as done in truncate.c was incorrectly flagged.
- # See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43772
- gl_GCC_VERSION_IFELSE([4], [8], [gl_WARN_ADD([-Wlogical-op])])
-
# clang is unduly picky about some things.
AC_CACHE_CHECK([whether the compiler is clang], [utils_cv_clang],
[AC_COMPILE_IFELSE(
--
2.21.0
>From 95c705bdc03c89cdf774f90ee68452ebd46b400a Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 22 Oct 2019 12:58:07 -0700
Subject: [PATCH 3/5] shuf: improve randperm overflow checking
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* gl/lib/randperm.c: Include randperm.h first, since it’s the API.
Include stdint.h, count-leading-zeros.h, verify.h.
(floor_lg): Rename from ceil_log (which was not actually
implementing the ceiling!) and implement the floor using
count_leading_zeros.
(randperm_bound): Use floor_lg, not ceil_log. Use uintmax_t
instead of size_t in case the size gets large on a 32-bit host.
* gl/modules/randperm (Depends-on): Add count-leading-zeros, stdint.
---
gl/lib/randperm.c | 27 ++++++++++++++++-----------
gl/modules/randperm | 2 ++
2 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/gl/lib/randperm.c b/gl/lib/randperm.c
index ce69222e9..b079aba33 100644
--- a/gl/lib/randperm.c
+++ b/gl/lib/randperm.c
@@ -19,24 +19,29 @@
#include <config.h>
-#include "hash.h"
#include "randperm.h"
#include <limits.h>
+#include <stdint.h>
#include <stdlib.h>
+#include "count-leading-zeros.h"
+#include "hash.h"
+#include "verify.h"
#include "xalloc.h"
-/* Return the ceiling of the log base 2 of N. If N is zero, return
- an unspecified value. */
+/* Return the floor of the log base 2 of N. If N is zero, return -1. */
-static size_t _GL_ATTRIBUTE_CONST
-ceil_lg (size_t n)
+static int _GL_ATTRIBUTE_CONST
+floor_lg (size_t n)
{
- size_t b = 0;
- for (n--; n != 0; n /= 2)
- b++;
- return b;
+ verify (SIZE_WIDTH <= ULLONG_WIDTH);
+ return (n == 0 ? -1
+ : SIZE_WIDTH <= UINT_WIDTH
+ ? UINT_WIDTH - 1 - count_leading_zeros (n)
+ : SIZE_WIDTH <= ULONG_WIDTH
+ ? ULONG_WIDTH - 1 - count_leading_zeros_l (n)
+ : ULLONG_WIDTH - 1 - count_leading_zeros_ll (n));
}
/* Return an upper bound on the number of random bytes needed to
@@ -48,10 +53,10 @@ randperm_bound (size_t h, size_t n)
{
/* Upper bound on number of bits needed to generate the first number
of the permutation. */
- size_t lg_n = ceil_lg (n);
+ uintmax_t lg_n = floor_lg (n) + 1;
/* Upper bound on number of bits needed to generated the first H elements. */
- size_t ar = lg_n * h;
+ uintmax_t ar = lg_n * h;
/* Convert the bit count to a byte count. */
size_t bound = (ar + CHAR_BIT - 1) / CHAR_BIT;
diff --git a/gl/modules/randperm b/gl/modules/randperm
index 1fa261290..e3b347140 100644
--- a/gl/modules/randperm
+++ b/gl/modules/randperm
@@ -6,7 +6,9 @@ lib/randperm.c
lib/randperm.h
Depends-on:
+count-leading-zeros
randint
+stdint
xalloc
hash
--
2.21.0
>From 9e324d0ed790a455078da0f593b0502c0533f7c5 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 22 Oct 2019 14:31:52 -0700
Subject: [PATCH 4/5] stdbuf: improve size checking
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* bootstrap.conf (gnulib_modules): Add minmax.
* src/libstdbuf.c: Include stdint.h, minmax.h.
(apply_mode): Don’t assume SIZE_MAX <= ULONG_MAX.
Improve checking for invalid sizes.
---
bootstrap.conf | 1 +
src/libstdbuf.c | 37 ++++++++++++++++++++-----------------
2 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/bootstrap.conf b/bootstrap.conf
index 018bc4eb3..de795757c 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -165,6 +165,7 @@ gnulib_modules="
memcmp2
mempcpy
memrchr
+ minmax
mgetgroups
mkancesdirs
mkdir
diff --git a/src/libstdbuf.c b/src/libstdbuf.c
index 4d8131de5..999e365ae 100644
--- a/src/libstdbuf.c
+++ b/src/libstdbuf.c
@@ -18,7 +18,9 @@
#include <config.h>
#include <stdio.h>
+#include <stdint.h>
#include "system.h"
+#include "minmax.h"
/* Deactivate config.h's "rpl_"-prefixed definition of malloc,
since we don't link gnulib here, and the replacement isn't
@@ -90,7 +92,7 @@ apply_mode (FILE *stream, const char *mode)
{
char *buf = NULL;
int setvbuf_mode;
- size_t size = 0;
+ uintmax_t size = 0;
if (*mode == '0')
setvbuf_mode = _IONBF;
@@ -99,27 +101,28 @@ apply_mode (FILE *stream, const char *mode)
else
{
setvbuf_mode = _IOFBF;
- verify (SIZE_MAX <= ULONG_MAX);
- size = strtoul (mode, NULL, 10);
- if (size > 0)
- {
- if (!(buf = malloc (size))) /* will be freed by fclose() */
- {
- /* We could defer the allocation to libc, however since
- glibc currently ignores the combination of NULL buffer
- with non zero size, we'll fail here. */
- fprintf (stderr,
- _("failed to allocate a %" PRIuMAX
- " byte stdio buffer\n"), (uintmax_t) size);
- return;
- }
- }
- else
+ char *mode_end;
+ size = strtoumax (mode, &mode_end, 10);
+ if (size == 0 || *mode_end)
{
fprintf (stderr, _("invalid buffering mode %s for %s\n"),
mode, fileno_to_name (fileno (stream)));
return;
}
+
+ buf = size <= SIZE_MAX ? malloc (size) : NULL;
+ if (!buf)
+ {
+ /* We could defer the allocation to libc, however since
+ glibc currently ignores the combination of NULL buffer
+ with non zero size, we'll fail here. */
+ fprintf (stderr,
+ _("failed to allocate a %" PRIuMAX
+ " byte stdio buffer\n"),
+ size);
+ return;
+ }
+ /* buf will be freed by fclose. */
}
if (setvbuf (stream, buf, setvbuf_mode, size) != 0)
--
2.21.0
>From 931d7173277f803f96ebb46605c0c6d2684fa98d Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 22 Oct 2019 14:55:24 -0700
Subject: [PATCH 5/5] all: improve parsing of numeric arguments
This addresses a longstanding "update all callers" FIXME in
lib/xstrtol.c, by having programs check that numbers do not
have unknown suffixes. The problem was also reported for
'shuf' by my student Maggie Huang while reimplementing a shuf
subset in Python as an exercise in UCLA Computer Science 35L:
https://web.cs.ucla.edu/classes/fall19/cs35L/assign/assign3.html
This patch also improves the portability of the code to unusual
platforms where ULONG_MAX < SIZE_MAX.
* NEWS: Mention user-visible changes.
* src/chgrp.c (parse_group):
* src/chroot.c (parse_additional_groups):
* src/du.c (main):
* src/install.c (get_ids):
* src/join.c (string_to_join_field):
* src/ls.c (decode_switches):
* src/md5sum.c (split_3):
* src/shuf.c (main):
* src/sort.c (specify_nthreads):
* src/uniq.c (size_opt, main):
Use uintmax_t instead of unsigned long, for portability
to oddball platforms where unsigned long is not wide enough.
* src/du.c (main):
* src/expr.c (mpz_init_set_str) [!HAVE_GMP]:
* src/install.c (get_ids):
* src/ls.c (decode_switches):
* src/mknod.c (main):
* src/ptx.c (main):
* src/shuf.c (main):
* src/sort.c (specify_nmerge, specify_nthreads):
Reject numbers with suffixes.
* src/md5sum.c (split_3): Simplify.
---
NEWS | 7 +++++++
src/chgrp.c | 4 ++--
src/chroot.c | 5 +++--
src/du.c | 8 ++++----
src/expr.c | 2 +-
src/install.c | 8 ++++----
src/join.c | 5 ++---
src/ls.c | 19 ++++++++-----------
src/md5sum.c | 21 +++++++++------------
src/mknod.c | 4 ++--
src/ptx.c | 4 ++--
src/shuf.c | 4 ++--
src/sort.c | 6 +++---
src/uniq.c | 9 ++++-----
14 files changed, 53 insertions(+), 53 deletions(-)
diff --git a/NEWS b/NEWS
index 476c02aed..300a799ae 100644
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,13 @@ GNU coreutils NEWS -*- outline -*-
** Changes in behavior
+ Several programs now check that numbers end properly. For example,
+ 'du -d 1x' now reports an error instead of silently ignoring the 'x'.
+ Affected programs and options include du -d, expr's numeric operands
+ on non-GMP builds, install -g and -o, ls's TABSIZE environment
+ variable, mknod b and c, ptx -g and -w, shuf -n, and sort --batch-size
+ and --parallel.
+
date now parses military time zones in accordance with common usage:
"A" to "M" are equivalent to UTC+1 to UTC+12
"N" to "Y" are equivalent to UTC-1 to UTC-12
diff --git a/src/chgrp.c b/src/chgrp.c
index dfd39ae5e..b7393eef6 100644
--- a/src/chgrp.c
+++ b/src/chgrp.c
@@ -87,8 +87,8 @@ parse_group (const char *name)
gid = grp->gr_gid;
else
{
- unsigned long int tmp;
- if (! (xstrtoul (name, NULL, 10, &tmp, "") == LONGINT_OK
+ uintmax_t tmp;
+ if (! (xstrtoumax (name, NULL, 10, &tmp, "") == LONGINT_OK
&& tmp <= GID_T_MAX))
die (EXIT_FAILURE, 0, _("invalid group: %s"),
quote (name));
diff --git a/src/chroot.c b/src/chroot.c
index 42ea5fa92..ea55e7527 100644
--- a/src/chroot.c
+++ b/src/chroot.c
@@ -106,9 +106,10 @@ parse_additional_groups (char const *groups, GETGROUPS_T **pgids,
for (tmp = strtok (buffer, ","); tmp; tmp = strtok (NULL, ","))
{
struct group *g;
- unsigned long int value;
+ uintmax_t value;
- if (xstrtoul (tmp, NULL, 10, &value, "") == LONGINT_OK && value <= MAXGID)
+ if (xstrtoumax (tmp, NULL, 10, &value, "") == LONGINT_OK
+ && value <= MAXGID)
{
while (isspace (to_uchar (*tmp)))
tmp++;
diff --git a/src/du.c b/src/du.c
index 43c348159..a44b22e46 100644
--- a/src/du.c
+++ b/src/du.c
@@ -807,12 +807,12 @@ main (int argc, char **argv)
case 'd': /* --max-depth=N */
{
- unsigned long int tmp_ulong;
- if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
- && tmp_ulong <= SIZE_MAX)
+ uintmax_t tmp;
+ if (xstrtoumax (optarg, NULL, 0, &tmp, "") == LONGINT_OK
+ && tmp <= SIZE_MAX)
{
max_depth_specified = true;
- max_depth = tmp_ulong;
+ max_depth = tmp;
}
else
{
diff --git a/src/expr.c b/src/expr.c
index 3ce61b203..08d7277ec 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -60,7 +60,7 @@ static void mpz_init_set_ui (mpz_t z, unsigned long int i) { z[0] = i; }
static int
mpz_init_set_str (mpz_t z, char *s, int base)
{
- return xstrtoimax (s, NULL, base, z, NULL) == LONGINT_OK ? 0 : -1;
+ return xstrtoimax (s, NULL, base, z, "") == LONGINT_OK ? 0 : -1;
}
static void
mpz_add (mpz_t r, mpz_t a0, mpz_t b0)
diff --git a/src/install.c b/src/install.c
index bde69c994..8b02be965 100644
--- a/src/install.c
+++ b/src/install.c
@@ -583,8 +583,8 @@ get_ids (void)
pw = getpwnam (owner_name);
if (pw == NULL)
{
- unsigned long int tmp;
- if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
+ uintmax_t tmp;
+ if (xstrtoumax (owner_name, NULL, 0, &tmp, "") != LONGINT_OK
|| UID_T_MAX < tmp)
die (EXIT_FAILURE, 0, _("invalid user %s"),
quote (owner_name));
@@ -602,8 +602,8 @@ get_ids (void)
gr = getgrnam (group_name);
if (gr == NULL)
{
- unsigned long int tmp;
- if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
+ uintmax_t tmp;
+ if (xstrtoumax (group_name, NULL, 0, &tmp, "") != LONGINT_OK
|| GID_T_MAX < tmp)
die (EXIT_FAILURE, 0, _("invalid group %s"),
quote (group_name));
diff --git a/src/join.c b/src/join.c
index dd0ce42bc..64156a22c 100644
--- a/src/join.c
+++ b/src/join.c
@@ -839,10 +839,9 @@ static size_t
string_to_join_field (char const *str)
{
size_t result;
- unsigned long int val;
- verify (SIZE_MAX <= ULONG_MAX);
+ uintmax_t val;
- strtol_error s_err = xstrtoul (str, NULL, 10, &val, "");
+ strtol_error s_err = xstrtoumax (str, NULL, 10, &val, "");
if (s_err == LONGINT_OVERFLOW || (s_err == LONGINT_OK && SIZE_MAX < val))
val = SIZE_MAX;
else if (s_err != LONGINT_OK || val == 0)
diff --git a/src/ls.c b/src/ls.c
index 034087f26..d02653b48 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -1902,18 +1902,15 @@ decode_switches (int argc, char **argv)
tabsize = 8;
if (p)
{
- unsigned long int tmp_ulong;
- if (xstrtoul (p, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
- && tmp_ulong <= SIZE_MAX)
- {
- tabsize = tmp_ulong;
- }
+ uintmax_t tmp;
+ if (xstrtoumax (p, NULL, 0, &tmp, "") == LONGINT_OK
+ && tmp <= SIZE_MAX)
+ tabsize = tmp;
else
- {
- error (0, 0,
- _("ignoring invalid tab size in environment variable TABSIZE: %s"),
- quote (p));
- }
+ error (0, 0,
+ _("ignoring invalid tab size in environment variable TABSIZE:"
+ " %s"),
+ quote (p));
}
}
diff --git a/src/md5sum.c b/src/md5sum.c
index f75b6de02..de847ccb2 100644
--- a/src/md5sum.c
+++ b/src/md5sum.c
@@ -450,26 +450,23 @@ split_3 (char *s, size_t s_len,
ptrdiff_t algo = argmatch (algo_name, algorithm_out_string, NULL, 0);
if (algo < 0)
return false;
- else
- b2_algorithm = algo;
+ b2_algorithm = algo;
if (openssl_format)
s[--i] = '(';
+ b2_length = blake2_max_len[b2_algorithm] * 8;
if (length_specified)
{
- unsigned long int tmp_ulong;
- if (xstrtoul (s + i, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
- && 0 < tmp_ulong && tmp_ulong <= blake2_max_len[b2_algorithm] * 8
- && tmp_ulong % 8 == 0)
- b2_length = tmp_ulong;
- else
+ uintmax_t length;
+ char *siend;
+ if (! (xstrtoumax (s + i, &siend, 0, &length, NULL) == LONGINT_OK
+ && 0 < length && length <= b2_length
+ && length % 8 == 0))
return false;
- while (ISDIGIT (s[i]))
- ++i;
+ i = siend - s;
+ b2_length = length;
}
- else
- b2_length = blake2_max_len[b2_algorithm] * 8;
digest_hex_bytes = b2_length / 4;
#endif
diff --git a/src/mknod.c b/src/mknod.c
index 7f7cbc739..3f430af46 100644
--- a/src/mknod.c
+++ b/src/mknod.c
@@ -230,12 +230,12 @@ main (int argc, char **argv)
uintmax_t i_major, i_minor;
dev_t device;
- if (xstrtoumax (s_major, NULL, 0, &i_major, NULL) != LONGINT_OK
+ if (xstrtoumax (s_major, NULL, 0, &i_major, "") != LONGINT_OK
|| i_major != (major_t) i_major)
die (EXIT_FAILURE, 0,
_("invalid major device number %s"), quote (s_major));
- if (xstrtoumax (s_minor, NULL, 0, &i_minor, NULL) != LONGINT_OK
+ if (xstrtoumax (s_minor, NULL, 0, &i_minor, "") != LONGINT_OK
|| i_minor != (minor_t) i_minor)
die (EXIT_FAILURE, 0,
_("invalid minor device number %s"), quote (s_minor));
diff --git a/src/ptx.c b/src/ptx.c
index 3f2344055..779b78c90 100644
--- a/src/ptx.c
+++ b/src/ptx.c
@@ -1940,7 +1940,7 @@ main (int argc, char **argv)
case 'g':
{
intmax_t tmp;
- if (! (xstrtoimax (optarg, NULL, 0, &tmp, NULL) == LONGINT_OK
+ if (! (xstrtoimax (optarg, NULL, 0, &tmp, "") == LONGINT_OK
&& 0 < tmp && tmp <= PTRDIFF_MAX))
die (EXIT_FAILURE, 0, _("invalid gap width: %s"),
quote (optarg));
@@ -1967,7 +1967,7 @@ main (int argc, char **argv)
case 'w':
{
intmax_t tmp;
- if (! (xstrtoimax (optarg, NULL, 0, &tmp, NULL) == LONGINT_OK
+ if (! (xstrtoimax (optarg, NULL, 0, &tmp, "") == LONGINT_OK
&& 0 < tmp && tmp <= PTRDIFF_MAX))
die (EXIT_FAILURE, 0, _("invalid line width: %s"),
quote (optarg));
diff --git a/src/shuf.c b/src/shuf.c
index 6a1aa0158..37a5a5554 100644
--- a/src/shuf.c
+++ b/src/shuf.c
@@ -440,8 +440,8 @@ main (int argc, char **argv)
case 'n':
{
- unsigned long int argval;
- strtol_error e = xstrtoul (optarg, NULL, 10, &argval, NULL);
+ uintmax_t argval;
+ strtol_error e = xstrtoumax (optarg, NULL, 10, &argval, "");
if (e == LONGINT_OK)
head_lines = MIN (head_lines, argval);
diff --git a/src/sort.c b/src/sort.c
index 360a1f140..b2336894f 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -1330,7 +1330,7 @@ specify_nmerge (int oi, char c, char const *s)
{
uintmax_t n;
struct rlimit rlimit;
- enum strtol_error e = xstrtoumax (s, NULL, 10, &n, NULL);
+ enum strtol_error e = xstrtoumax (s, NULL, 10, &n, "");
/* Try to find out how many file descriptors we'll be able
to open. We need at least nmerge + 3 (STDIN_FILENO,
@@ -1443,8 +1443,8 @@ specify_sort_size (int oi, char c, char const *s)
static size_t
specify_nthreads (int oi, char c, char const *s)
{
- unsigned long int nthreads;
- enum strtol_error e = xstrtoul (s, NULL, 10, &nthreads, "");
+ uintmax_t nthreads;
+ enum strtol_error e = xstrtoumax (s, NULL, 10, &nthreads, "");
if (e == LONGINT_OVERFLOW)
return SIZE_MAX;
if (e != LONGINT_OK)
diff --git a/src/uniq.c b/src/uniq.c
index 9600ec094..836473624 100644
--- a/src/uniq.c
+++ b/src/uniq.c
@@ -240,10 +240,9 @@ strict_posix2 (void)
static size_t
size_opt (char const *opt, char const *msgid)
{
- unsigned long int size;
- verify (SIZE_MAX <= ULONG_MAX);
+ uintmax_t size;
- switch (xstrtoul (opt, NULL, 10, &size, ""))
+ switch (xstrtoumax (opt, NULL, 10, &size, ""))
{
case LONGINT_OK:
case LONGINT_OVERFLOW:
@@ -539,10 +538,10 @@ main (int argc, char **argv)
{
case 1:
{
- unsigned long int size;
+ uintmax_t size;
if (optarg[0] == '+'
&& ! strict_posix2 ()
- && xstrtoul (optarg, NULL, 10, &size, "") == LONGINT_OK
+ && xstrtoumax (optarg, NULL, 10, &size, "") == LONGINT_OK
&& size <= SIZE_MAX)
skip_chars = size;
else if (nfiles == 2)
--
2.21.0