changeset 18302:93ffcec1bbd4

xstrtol: prohibit monstrosities like "1bB" Problem reported by Young Mo Kang in: http://bugs.gnu.org/23388 * lib/xstrtol.c (__xstrtol): Allow trailing second suffixes like "B" only if the first suffix needs a base. * tests/test-xstrtol.sh: Test this.
author Paul Eggert <eggert@cs.ucla.edu>
date Wed, 27 Apr 2016 12:10:54 -0700
parents 41c14c70d2f1
children 8b34efae5441
files ChangeLog lib/xstrtol.c tests/test-xstrtol.sh
diffstat 3 files changed, 32 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Apr 21 12:20:58 2016 +0100
+++ b/ChangeLog	Wed Apr 27 12:10:54 2016 -0700
@@ -1,3 +1,11 @@
+2016-04-27  Paul Eggert  <eggert@cs.ucla.edu>
+
+	xstrtol: prohibit monstrosities like "1bB"
+	Problem reported by Young Mo Kang in: http://bugs.gnu.org/23388
+	* lib/xstrtol.c (__xstrtol): Allow trailing second suffixes like
+	"B" only if the first suffix needs a base.
+	* tests/test-xstrtol.sh: Test this.
+
 2016-04-21  Pádraig Brady  <P@draigBrady.com>
 
 	xstrtod: reinstate setting of *result upon ERANGE
--- a/lib/xstrtol.c	Thu Apr 21 12:20:58 2016 +0100
+++ b/lib/xstrtol.c	Wed Apr 27 12:10:54 2016 -0700
@@ -148,8 +148,11 @@
           return err | LONGINT_INVALID_SUFFIX_CHAR;
         }
 
-      if (strchr (valid_suffixes, '0'))
+      switch (**p)
         {
+        case 'E': case 'G': case 'g': case 'k': case 'K': case 'M': case 'm':
+        case 'P': case 'T': case 't': case 'Y': case 'Z':
+
           /* The "valid suffix" '0' is a special flag meaning that
              an optional second suffix is allowed, which can change
              the base.  A suffix "B" (e.g. "100MB") stands for a power
@@ -157,19 +160,20 @@
              a power of 1024.  If no suffix (e.g. "100M"), assume
              power-of-1024.  */
 
-          switch (p[0][1])
-            {
-            case 'i':
-              if (p[0][2] == 'B')
-                suffixes += 2;
-              break;
+          if (strchr (valid_suffixes, '0'))
+            switch (p[0][1])
+              {
+              case 'i':
+                if (p[0][2] == 'B')
+                  suffixes += 2;
+                break;
 
-            case 'B':
-            case 'D': /* 'D' is obsolescent */
-              base = 1000;
-              suffixes++;
-              break;
-            }
+              case 'B':
+              case 'D': /* 'D' is obsolescent */
+                base = 1000;
+                suffixes++;
+                break;
+              }
         }
 
       switch (**p)
@@ -179,6 +183,9 @@
           break;
 
         case 'B':
+          /* This obsolescent first suffix is distinct from the 'B'
+             second suffix above.  E.g., 'tar -L 1000B' means change
+             the tape after writing 1000 KiB of data.  */
           overflow = bkm_scale (&tmp, 1024);
           break;
 
--- a/tests/test-xstrtol.sh	Thu Apr 21 12:20:58 2016 +0100
+++ b/tests/test-xstrtol.sh	Wed Apr 27 12:10:54 2016 -0700
@@ -16,6 +16,7 @@
 test-xstrtol 010 >> out 2>&1 || result=1
 # suffix without integer is valid
 test-xstrtol MiB >> out 2>&1 || result=1
+test-xstrtol 1bB >> out 2>&1 && result=1
 
 # test xstrtoul
 test-xstrtoul 1 >> out 2>&1 || result=1
@@ -27,6 +28,7 @@
 test-xstrtoul 9x >> out 2>&1 && result=1
 test-xstrtoul 010 >> out 2>&1 || result=1
 test-xstrtoul MiB >> out 2>&1 || result=1
+test-xstrtoul 1bB >> out 2>&1 && result=1
 
 # Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
 # does not understand '\r'.
@@ -51,6 +53,7 @@
 invalid suffix in X argument '9x'
 010->8 ()
 MiB->1048576 ()
+invalid suffix in X argument '1bB'
 1->1 ()
 invalid X argument '-1'
 1k->1024 ()
@@ -60,6 +63,7 @@
 invalid suffix in X argument '9x'
 010->8 ()
 MiB->1048576 ()
+invalid suffix in X argument '1bB'
 EOF
 
 compare expected out || result=1