]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
stdbuf: improve size checking
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 22 Oct 2019 21:31:52 +0000 (14:31 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 22 Oct 2019 22:04:43 +0000 (15:04 -0700)
* 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
src/libstdbuf.c

index 018bc4eb332fc6e68a6bec86b3aa90866b900c06..de795757c6985c7b6536f0f5b3df05ab95937214 100644 (file)
@@ -165,6 +165,7 @@ gnulib_modules="
   memcmp2
   mempcpy
   memrchr
+  minmax
   mgetgroups
   mkancesdirs
   mkdir
index 4d8131de5e14fa519d0af5f8431343a4f3bf94fb..999e365ae5d095ff81542e8d342066ea88817a40 100644 (file)
@@ -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)