strings: Improve code to detect excessively large minimum string lengths.
authorNick Clifton <nickc@redhat.com>
Fri, 30 Jun 2023 12:54:03 +0000 (13:54 +0100)
committerNick Clifton <nickc@redhat.com>
Fri, 30 Jun 2023 12:54:03 +0000 (13:54 +0100)
  PR 30598
  * strings.c (set_string_min): New function. (main): Use it. (print_unicode_stream): Calculate buffer size using a size_t.

binutils/ChangeLog
binutils/strings.c

index f06aba238bba42969795ec74ae25a1e6ebcae60a..bfbba8f6ee94c5ee72a0fad29bf4361167939f0c 100644 (file)
@@ -1,3 +1,10 @@
+2023-06-30  Nick Clifton  <nickc@redhat.com>
+
+       PR 30598
+       * strings.c (set_string_min): New function.
+       (main): Use it.
+       (print_unicode_stream): Calculate buffer size using a size_t.
+
 2023-06-30  Nick Clifton  <nickc@redhat.com>
 
        PR 30595
index f7214fc12282712a9b069919f75711dc293c8f49..eb4ec9e270c1d544a2e6ce1c2fd297ecbad323fc 100644 (file)
@@ -171,13 +171,37 @@ static void usage (FILE *, int) ATTRIBUTE_NORETURN;
 \f
 int main (int, char **);
 
+static void
+set_string_min (const char * arg)
+{
+  char *s;
+  unsigned long l = strtoul (arg, &s, 0);
+
+  if (s != NULL && *s != 0)
+    fatal (_("invalid integer argument %s"), arg);
+
+  string_min = (unsigned int) l;
+
+  if (l != (unsigned long) string_min)
+    fatal (_("minimum string length is too big: %s"), arg);
+    
+  if (string_min < 1)
+    fatal (_("minimum string length is too small: %s"), arg);
+
+  /* PR 30595: Look for minimum string lengths that overflow an 'int'.  */
+  if (string_min + 1 == 0)
+    fatal (_("minimum string length %s is too big"), arg);
+
+  /* FIXME: Should we warn for unreasonably large minimum
+     string lengths, even if technically they will work ?  */
+}
+
 int
 main (int argc, char **argv)
 {
   int optc;
   int exit_status = 0;
   bool files_given = false;
-  char *s;
   int numeric_opt = 0;
 
   setlocale (LC_ALL, "");
@@ -224,9 +248,7 @@ main (int argc, char **argv)
          usage (stdout, 0);
 
        case 'n':
-         string_min = (int) strtoul (optarg, &s, 0);
-         if (s != NULL && *s != 0)
-           fatal (_("invalid integer argument %s"), optarg);
+         set_string_min (optarg);
          break;
 
        case 'w':
@@ -310,19 +332,7 @@ main (int argc, char **argv)
     encoding = 'S';
 
   if (numeric_opt != 0)
-    {
-      string_min = (int) strtoul (argv[numeric_opt - 1] + 1, &s, 0);
-      if (s != NULL && *s != 0)
-       fatal (_("invalid integer argument %s"), argv[numeric_opt - 1] + 1);
-    }
-
-  if (string_min < 1)
-    fatal (_("invalid minimum string length %d"), string_min);
-  /* PR 30595: Look for excessive minimum string lengths.
-     The "(4 * string_min) + 1" is because this is the value
-     used to allocate space in print_unicode_stream().  */
-  else if (string_min == -1U || ((4 * string_min) + 1) == 0)
-    fatal (_("minimum string length %#x is too big"), string_min);
+    set_string_min (argv[numeric_opt - 1] + 1);
 
   switch (encoding)
     {
@@ -1220,7 +1230,9 @@ print_unicode_stream (const char * filename,
     }
 
   /* Allocate space for string_min 4-byte utf-8 characters.  */
-  unsigned char * print_buf = xmalloc ((4 * string_min) + 1);
+  size_t amt = string_min;
+  amt = (4 * amt) + 1;
+  unsigned char * print_buf = xmalloc (amt);
   /* We should never have to put back more than 4 bytes.  */
   unsigned char putback_buf[5];
   unsigned int num_putback = 0;