>From 9e324d0ed790a455078da0f593b0502c0533f7c5 Mon Sep 17 00:00:00 2001 From: Paul Eggert 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 #include +#include #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