mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
dd: fix parsing of numbers with more than two multipliers
* src/dd.c (parse_integer): Use recursion to support more than two multipliers. Also protect suffix[-1] access to ensure we don't inspect before the passed string. * tests/dd/bytes.sh: Add test cases. * doc/coreutils.texi (dd invocation): Note the support for specifying many multipliers in a number. * NEWS: Mention the bug fix. Fixes https://bugs.debian.org/1037275
This commit is contained in:
4
NEWS
4
NEWS
@@ -11,6 +11,10 @@ GNU coreutils NEWS -*- outline -*-
|
||||
cksum again diagnoses read errors in its default CRC32 mode.
|
||||
[bug introduced in coreutils-9.0]
|
||||
|
||||
dd again supports more than two multipliers for numbers.
|
||||
Previously numbers of the form '1024x1024x32' gave "invalid number" errors.
|
||||
[bug introduced in coreutils-9.1]
|
||||
|
||||
factor, numfmt, and tsort now diagnose read errors on the input.
|
||||
[This bug was present in "the beginning".]
|
||||
|
||||
|
||||
@@ -9818,7 +9818,7 @@ can be followed by a multiplier: @samp{b}=512, @samp{c}=1,
|
||||
standard block size suffixes like @samp{k}=1024 (@pxref{Block size}).
|
||||
These multipliers are GNU extensions to POSIX, except that
|
||||
POSIX allows @var{bytes} to be followed by @samp{k}, @samp{b}, and
|
||||
@samp{x@var{m}}.
|
||||
@samp{x@var{m}}. Note @samp{x@var{m}} can be used more than once in a number.
|
||||
Block sizes (i.e., specified by @var{bytes} strings) must be nonzero.
|
||||
|
||||
Any block size you specify via @samp{bs=}, @samp{ibs=}, @samp{obs=}, @samp{cbs=}
|
||||
|
||||
8
src/dd.c
8
src/dd.c
@@ -1428,7 +1428,7 @@ parse_integer (char const *str, strtol_error *invalid)
|
||||
intmax_t result;
|
||||
|
||||
if ((e & ~LONGINT_OVERFLOW) == LONGINT_INVALID_SUFFIX_CHAR
|
||||
&& suffix[-1] != 'B' && *suffix == 'B')
|
||||
&& *suffix == 'B' && str < suffix && suffix[-1] != 'B')
|
||||
{
|
||||
suffix++;
|
||||
if (!*suffix)
|
||||
@@ -1436,10 +1436,10 @@ parse_integer (char const *str, strtol_error *invalid)
|
||||
}
|
||||
|
||||
if ((e & ~LONGINT_OVERFLOW) == LONGINT_INVALID_SUFFIX_CHAR
|
||||
&& *suffix == 'x' && ! (suffix[-1] == 'B' && strchr (suffix + 1, 'B')))
|
||||
&& *suffix == 'x')
|
||||
{
|
||||
uintmax_t o;
|
||||
strtol_error f = xstrtoumax (suffix + 1, &suffix, 10, &o, suffixes);
|
||||
strtol_error f = LONGINT_OK;
|
||||
intmax_t o = parse_integer (suffix + 1, &f);
|
||||
if ((f & ~LONGINT_OVERFLOW) != LONGINT_OK)
|
||||
{
|
||||
e = f;
|
||||
|
||||
@@ -60,4 +60,16 @@ for operands in "oseek=8B" "seek=8 oflag=seek_bytes"; do
|
||||
compare expected2 out2 || fail=1
|
||||
done
|
||||
|
||||
# Check recursive integer parsing
|
||||
for oseek in '1x2x4 oflag=seek_bytes' '1Bx2x4' '1Bx8' '2Bx4B' '2x4B'; do
|
||||
# seek bytes
|
||||
echo abcdefghijklm |
|
||||
dd oseek=$oseek bs=5 > out 2> /dev/null || fail=1
|
||||
compare expected out || fail=1
|
||||
done
|
||||
|
||||
# Negative checks for integer parsing
|
||||
for count in B B1 Bx1 KBB BB KBb KBx x1 1x 1xx1; do
|
||||
returns_ 1 dd count=$count </dev/null >/dev/null || fail=1
|
||||
done
|
||||
Exit $fail
|
||||
|
||||
Reference in New Issue
Block a user