summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2019-10-22 14:31:52 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2019-10-22 15:04:43 -0700
commited2db6886bc4dfa5be7c0a3a72a45024fdafe29f (patch)
tree4c6f8c3d55305f1894aef432e2039d7918588a18
parentshuf: improve randperm overflow checking (diff)
downloadcoreutils-ed2db6886bc4dfa5be7c0a3a72a45024fdafe29f.tar.gz
coreutils-ed2db6886bc4dfa5be7c0a3a72a45024fdafe29f.zip
stdbuf: improve size checking
* 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.
-rw-r--r--bootstrap.conf1
-rw-r--r--src/libstdbuf.c37
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)