* src/basenc.c (has_padding): A more robust helper to
identify padding in the presence of trailing newlines.
(do_decode): Use has_padding() rather than just looking
at the last character.
* tests/basenc/base64.pl: Fully test commit v9.4-53-g378dc38f4
by ensuring partially padded data is diagnosed.
baddecode9 is the case fixed in this commit.
* NEWS: Mention the bug fix.
---
NEWS | 4 ++++
src/basenc.c | 18 +++++++++++++++++-
tests/basenc/base64.pl | 10 ++++++++--
3 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/NEWS b/NEWS
index db9076c34..283d8046d 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,10 @@ GNU coreutils NEWS -*-
outline -*-
Previously it would have silently assumed 512 for any larger values.
[bug introduced in coreutils-9.6]
+ 'base32' and 'base64' when decoding will again diagnose partially
+ padded data that ends with a newline.
+ [bug introduced in coreutils-9.5]
+
'basenc -d -i' will now strip '=' characters from the input
in encodings where padding characters are not valid.
[bug introduced with the basenc program in coreutils-8.31]
diff --git a/src/basenc.c b/src/basenc.c
index 84789e2de..090404ee4 100644
--- a/src/basenc.c
+++ b/src/basenc.c
@@ -1446,6 +1446,22 @@ do_encode (FILE *in, char const *infile, FILE *out,
idx_t wrap_column)
finish_and_exit (in, infile);
}
+/* Returns TRUE if BUF of length LEN
+ ends with a '=' character.
+ Trailing '\n' characters are ignored. */
+ATTRIBUTE_PURE
+static bool
+has_padding (char const *buf, size_t len)
+{
+ while (len--)
+ {
+ if (buf[len] == '\n')
+ continue;
+ return buf[len] == '=';
+ }
+ return false;
+}
+
static _Noreturn void
do_decode (FILE *in, char const *infile, FILE *out, bool ignore_garbage)
{
@@ -1504,7 +1520,7 @@ do_decode (FILE *in, char const *infile, FILE *out, bool
ignore_garbage)
/* auto pad input (at eof). */
idx_t auto_padding = REQUIRED_PADDING (ctx.i);
- if (auto_padding && (sum == 0 || inbuf[sum - 1] != '='))
+ if (auto_padding && ! has_padding (inbuf, sum))
{
affirm (auto_padding <= sizeof (padbuf));
IF_LINT (free (inbuf));
diff --git a/tests/basenc/base64.pl b/tests/basenc/base64.pl
index 0aabc7b01..9ba24cf47 100755
--- a/tests/basenc/base64.pl
+++ b/tests/basenc/base64.pl
@@ -122,10 +122,12 @@ sub gen_tests($)
if ($prog eq "base64")
{
push @Tests, (
+ ['paddec1', '--decode', {IN=>'aQ'}, {OUT=>"i"}],
+ ['paddec2', '--decode', {IN=>'Zzw'}, {OUT=>"g<"}],
+ ['paddec3', '--decode', {IN=>'MTIzNA==MTIzNA'}, {OUT=>"12341234"}],
+ ['paddec4', '--decode', {IN=>"MTIzNA==\nMTIzNA"}, {OUT=>"12341234"}],
['baddecode', '--decode', {IN=>'a'}, {OUT=>""},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
- ['paddecode2', '--decode', {IN=>'aQ'}, {OUT=>"i"}],
- ['paddecode3', '--decode', {IN=>'Zzw'}, {OUT=>"g<"}],
['baddecode4', '--decode', {IN=>'Zz='}, {OUT=>"g"},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
['baddecode5', '--decode', {IN=>'Z==='}, {OUT=>""},
@@ -133,6 +135,10 @@ sub gen_tests($)
['baddecode6', '--decode', {IN=>'SB=='}, {OUT=>"H"},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
['baddecode7', '--decode', {IN=>'SGVsbG9='}, {OUT=>"Hello"},
+ {ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
+ ['baddecode8', '--decode', {IN=>'MTIzNA='}, {OUT=>"1234"},
+ {ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
+ ['baddecode9', '--decode', {IN=>"MTIzNA=\n"}, {OUT=>"1234"},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}]
);
}
--
2.50.1