Sync with gnulib 6ed53f13bc39d9a0252549e98a2a59441fb2351f.

lib/strutil/xstrtol.c: prohibit monstrosities like "1bB".

Problem reported by Young Mo Kang in: http://bugs.gnu.org/23388.

(xstrtoumax): Allow trailing second suffixes like "B" only if the first
suffix needs a base.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2016-05-01 08:44:00 +03:00
parent abbfde35b2
commit bdb81cd482

View File

@ -142,30 +142,47 @@ xstrtoumax (const char *s, char **ptr, int base, uintmax_t * val, const char *va
base = 1024;
if (strchr (valid_suffixes, '0') != NULL)
switch (**p)
{
/* 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
of 1000, whereas a suffix "iB" (e.g. "100MiB") stands for
a power of 1024. If no suffix (e.g. "100M"), assume
power-of-1024. */
switch (p[0][1])
case 'E':
case 'G':
case 'g':
case 'k':
case 'K':
case 'M':
case 'm':
case 'P':
case 'T':
case 't':
case 'Y':
case 'Z':
if (strchr (valid_suffixes, '0') != NULL)
{
case 'i':
if (p[0][2] == 'B')
suffixes += 2;
break;
/* 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
of 1000, whereas a suffix "iB" (e.g. "100MiB") stands for
a power of 1024. If no suffix (e.g. "100M"), assume
power-of-1024. */
case 'B':
case 'D': /* 'D' is obsolescent */
base = 1000;
suffixes++;
break;
default:
break;
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;
default:
break;
}
}
default:
break;
}
switch (**p)
@ -175,6 +192,9 @@ xstrtoumax (const char *s, char **ptr, int base, uintmax_t * val, const char *va
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;