@@ -6,6 +6,7 @@ package base32
66
77import (
88 "bytes"
9+ "errors"
910 "io"
1011 "io/ioutil"
1112 "strings"
@@ -123,6 +124,160 @@ func TestDecoder(t *testing.T) {
123124 }
124125}
125126
127+ type badReader struct {
128+ data []byte
129+ errs []error
130+ called int
131+ limit int
132+ }
133+
134+ // Populates p with data, returns a count of the bytes written and an
135+ // error. The error returned is taken from badReader.errs, with each
136+ // invocation of Read returning the next error in this slice, or io.EOF,
137+ // if all errors from the slice have already been returned. The
138+ // number of bytes returned is determined by the size of the input buffer
139+ // the test passes to decoder.Read and will be a multiple of 8, unless
140+ // badReader.limit is non zero.
141+ func (b * badReader ) Read (p []byte ) (int , error ) {
142+ lim := len (p )
143+ if b .limit != 0 && b .limit < lim {
144+ lim = b .limit
145+ }
146+ if len (b .data ) < lim {
147+ lim = len (b .data )
148+ }
149+ for i := range p [:lim ] {
150+ p [i ] = b .data [i ]
151+ }
152+ b .data = b .data [lim :]
153+ err := io .EOF
154+ if b .called < len (b .errs ) {
155+ err = b .errs [b .called ]
156+ }
157+ b .called ++
158+ return lim , err
159+ }
160+
161+ // TestIssue20044 tests that decoder.Read behaves correctly when the caller
162+ // supplied reader returns an error.
163+ func TestIssue20044 (t * testing.T ) {
164+ badErr := errors .New ("bad reader error" )
165+ testCases := []struct {
166+ r badReader
167+ res string
168+ err error
169+ dbuflen int
170+ }{
171+ // Check valid input data accompanied by an error is processed and the error is propagated.
172+ {r : badReader {data : []byte ("MY======" ), errs : []error {badErr }},
173+ res : "f" , err : badErr },
174+ // Check a read error accompanied by input data consisting of newlines only is propagated.
175+ {r : badReader {data : []byte ("\n \n \n \n \n \n \n \n " ), errs : []error {badErr , nil }},
176+ res : "" , err : badErr },
177+ // Reader will be called twice. The first time it will return 8 newline characters. The
178+ // second time valid base32 encoded data and an error. The data should be decoded
179+ // correctly and the error should be propagated.
180+ {r : badReader {data : []byte ("\n \n \n \n \n \n \n \n MY======" ), errs : []error {nil , badErr }},
181+ res : "f" , err : badErr , dbuflen : 8 },
182+ // Reader returns invalid input data (too short) and an error. Verify the reader
183+ // error is returned.
184+ {r : badReader {data : []byte ("MY=====" ), errs : []error {badErr }},
185+ res : "" , err : badErr },
186+ // Reader returns invalid input data (too short) but no error. Verify io.ErrUnexpectedEOF
187+ // is returned.
188+ {r : badReader {data : []byte ("MY=====" ), errs : []error {nil }},
189+ res : "" , err : io .ErrUnexpectedEOF },
190+ // Reader returns invalid input data and an error. Verify the reader and not the
191+ // decoder error is returned.
192+ {r : badReader {data : []byte ("Ma======" ), errs : []error {badErr }},
193+ res : "" , err : badErr },
194+ // Reader returns valid data and io.EOF. Check data is decoded and io.EOF is propagated.
195+ {r : badReader {data : []byte ("MZXW6YTB" ), errs : []error {io .EOF }},
196+ res : "fooba" , err : io .EOF },
197+ // Check errors are properly reported when decoder.Read is called multiple times.
198+ // decoder.Read will be called 8 times, badReader.Read will be called twice, returning
199+ // valid data both times but an error on the second call.
200+ {r : badReader {data : []byte ("NRSWC43VOJSS4===" ), errs : []error {nil , badErr }},
201+ res : "leasure." , err : badErr , dbuflen : 1 },
202+ // Check io.EOF is properly reported when decoder.Read is called multiple times.
203+ // decoder.Read will be called 8 times, badReader.Read will be called twice, returning
204+ // valid data both times but io.EOF on the second call.
205+ {r : badReader {data : []byte ("NRSWC43VOJSS4===" ), errs : []error {nil , io .EOF }},
206+ res : "leasure." , err : io .EOF , dbuflen : 1 },
207+ // The following two test cases check that errors are propagated correctly when more than
208+ // 8 bytes are read at a time.
209+ {r : badReader {data : []byte ("NRSWC43VOJSS4===" ), errs : []error {io .EOF }},
210+ res : "leasure." , err : io .EOF , dbuflen : 11 },
211+ {r : badReader {data : []byte ("NRSWC43VOJSS4===" ), errs : []error {badErr }},
212+ res : "leasure." , err : badErr , dbuflen : 11 },
213+ // Check that errors are correctly propagated when the reader returns valid bytes in
214+ // groups that are not divisible by 8. The first read will return 11 bytes and no
215+ // error. The second will return 7 and an error. The data should be decoded correctly
216+ // and the error should be propagated.
217+ {r : badReader {data : []byte ("NRSWC43VOJSS4===" ), errs : []error {nil , badErr }, limit : 11 },
218+ res : "leasure." , err : badErr },
219+ }
220+
221+ for _ , tc := range testCases {
222+ input := tc .r .data
223+ decoder := NewDecoder (StdEncoding , & tc .r )
224+ var dbuflen int
225+ if tc .dbuflen > 0 {
226+ dbuflen = tc .dbuflen
227+ } else {
228+ dbuflen = StdEncoding .DecodedLen (len (input ))
229+ }
230+ dbuf := make ([]byte , dbuflen )
231+ var err error
232+ var res []byte
233+ for err == nil {
234+ var n int
235+ n , err = decoder .Read (dbuf )
236+ if n > 0 {
237+ res = append (res , dbuf [:n ]... )
238+ }
239+ }
240+
241+ testEqual (t , "Decoding of %q = %q, want %q" , string (input ), string (res ), tc .res )
242+ testEqual (t , "Decoding of %q err = %v, expected %v" , string (input ), err , tc .err )
243+ }
244+ }
245+
246+ // TestDecoderError verifies decode errors are propagated when there are no read
247+ // errors.
248+ func TestDecoderError (t * testing.T ) {
249+ for _ , readErr := range []error {io .EOF , nil } {
250+ input := "MZXW6YTb"
251+ dbuf := make ([]byte , StdEncoding .DecodedLen (len (input )))
252+ br := badReader {data : []byte (input ), errs : []error {readErr }}
253+ decoder := NewDecoder (StdEncoding , & br )
254+ n , err := decoder .Read (dbuf )
255+ testEqual (t , "Read after EOF, n = %d, expected %d" , n , 0 )
256+ if _ , ok := err .(CorruptInputError ); ! ok {
257+ t .Errorf ("Corrupt input error expected. Found %T" , err )
258+ }
259+ }
260+ }
261+
262+ // TestReaderEOF ensures decoder.Read behaves correctly when input data is
263+ // exhausted.
264+ func TestReaderEOF (t * testing.T ) {
265+ for _ , readErr := range []error {io .EOF , nil } {
266+ input := "MZXW6YTB"
267+ br := badReader {data : []byte (input ), errs : []error {nil , readErr }}
268+ decoder := NewDecoder (StdEncoding , & br )
269+ dbuf := make ([]byte , StdEncoding .DecodedLen (len (input )))
270+ n , err := decoder .Read (dbuf )
271+ testEqual (t , "Decoding of %q err = %v, expected %v" , string (input ), err , error (nil ))
272+ n , err = decoder .Read (dbuf )
273+ testEqual (t , "Read after EOF, n = %d, expected %d" , n , 0 )
274+ testEqual (t , "Read after EOF, err = %v, expected %v" , err , io .EOF )
275+ n , err = decoder .Read (dbuf )
276+ testEqual (t , "Read after EOF, n = %d, expected %d" , n , 0 )
277+ testEqual (t , "Read after EOF, err = %v, expected %v" , err , io .EOF )
278+ }
279+ }
280+
126281func TestDecoderBuffering (t * testing.T ) {
127282 for bs := 1 ; bs <= 12 ; bs ++ {
128283 decoder := NewDecoder (StdEncoding , strings .NewReader (bigtest .encoded ))
0 commit comments