From 8a5845e4e34c046758af3729acf9221b8b6c01ae Mon Sep 17 00:00:00 2001 From: teivah Date: Tue, 3 May 2022 09:54:48 +0000 Subject: [PATCH] encoding/base32: decoder output depends on chunking of underlying reader After an analysis, I figured that a way to do it could be to check, after the call to readEncodedData whether the decoder already saw the end or not. Fixes #38657 Change-Id: I06fd718ea4ee6ded2cb26c2866b28581ad86e271 GitHub-Last-Rev: d0b7bb38e4301a2ae9b8e588944488dbd88b39c4 GitHub-Pull-Request: golang/go#52631 Reviewed-on: https://go-review.googlesource.com/c/go/+/403315 Run-TryBot: Ian Lance Taylor Auto-Submit: Ian Lance Taylor TryBot-Result: Gopher Robot Run-TryBot: Ian Lance Taylor Reviewed-by: David Chase Reviewed-by: Ian Lance Taylor --- src/encoding/base32/base32.go | 3 ++ src/encoding/base32/base32_test.go | 52 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/encoding/base32/base32.go b/src/encoding/base32/base32.go index 5f3af4c8bb..fa6e42e26c 100644 --- a/src/encoding/base32/base32.go +++ b/src/encoding/base32/base32.go @@ -445,6 +445,9 @@ func (d *decoder) Read(p []byte) (n int, err error) { if d.nbuf < min { return 0, d.err } + if nn > 0 && d.end { + return 0, CorruptInputError(0) + } // Decode chunk into p, or d.out and then p if p is too small. var nr int diff --git a/src/encoding/base32/base32_test.go b/src/encoding/base32/base32_test.go index dbd2b613b4..323d04e68b 100644 --- a/src/encoding/base32/base32_test.go +++ b/src/encoding/base32/base32_test.go @@ -627,6 +627,58 @@ func TestBufferedDecodingSameError(t *testing.T) { } } +func TestBufferedDecodingPadding(t *testing.T) { + testcases := []struct { + chunks []string + expectedError string + }{ + {[]string{ + "I4======", + "==", + }, "unexpected EOF"}, + + {[]string{ + "I4======N4======", + }, "illegal base32 data at input byte 2"}, + + {[]string{ + "I4======", + "N4======", + }, "illegal base32 data at input byte 0"}, + + {[]string{ + "I4======", + "========", + }, "illegal base32 data at input byte 0"}, + + {[]string{ + "I4I4I4I4", + "I4======", + "I4======", + }, "illegal base32 data at input byte 0"}, + } + + for _, testcase := range testcases { + testcase := testcase + pr, pw := io.Pipe() + go func() { + for _, chunk := range testcase.chunks { + _, _ = pw.Write([]byte(chunk)) + } + _ = pw.Close() + }() + + decoder := NewDecoder(StdEncoding, pr) + _, err := io.ReadAll(decoder) + + if err == nil && len(testcase.expectedError) != 0 { + t.Errorf("case %q: got nil error, want %v", testcase.chunks, testcase.expectedError) + } else if err.Error() != testcase.expectedError { + t.Errorf("case %q: got %v, want %v", testcase.chunks, err, testcase.expectedError) + } + } +} + func TestEncodedDecodedLen(t *testing.T) { type test struct { in int -- 2.50.0