>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