@@ -142,25 +142,42 @@ fn read_in_short_increments() {
142
142
let mut wrapped_reader = io:: Cursor :: new ( & b64[ ..] ) ;
143
143
let mut decoder = DecoderReader :: new ( & mut wrapped_reader, config) ;
144
144
145
- let mut total_read = 0_usize ;
146
- loop {
147
- assert ! ( total_read <= size, "tr {} size {}" , total_read, size) ;
148
- if total_read == size {
149
- assert_eq ! ( bytes, & decoded[ ..total_read] ) ;
150
- // should be done
151
- assert_eq ! ( 0 , decoder. read( & mut decoded[ ..] ) . unwrap( ) ) ;
152
- // didn't write anything
153
- assert_eq ! ( bytes, & decoded[ ..total_read] ) ;
154
-
155
- break ;
156
- }
157
- let decode_len = rng. gen_range ( 1 , cmp:: max ( 2 , size * 2 ) ) ;
145
+ consume_with_short_reads_and_validate ( & mut rng, & bytes[ ..] , & mut decoded, & mut decoder) ;
146
+ }
147
+ }
158
148
159
- let read = decoder
160
- . read ( & mut decoded[ total_read..total_read + decode_len] )
161
- . unwrap ( ) ;
162
- total_read += read;
163
- }
149
+ #[ test]
150
+ fn read_in_short_increments_with_short_delegate_reads ( ) {
151
+ let mut rng = rand:: thread_rng ( ) ;
152
+ let mut bytes = Vec :: new ( ) ;
153
+ let mut b64 = String :: new ( ) ;
154
+ let mut decoded = Vec :: new ( ) ;
155
+
156
+ for _ in 0 ..10_000 {
157
+ bytes. clear ( ) ;
158
+ b64. clear ( ) ;
159
+ decoded. clear ( ) ;
160
+
161
+ let size = rng. gen_range ( 0 , 10 * BUF_SIZE ) ;
162
+ bytes. extend ( iter:: repeat ( 0 ) . take ( size) ) ;
163
+ // leave room to play around with larger buffers
164
+ decoded. extend ( iter:: repeat ( 0 ) . take ( size * 3 ) ) ;
165
+
166
+ rng. fill_bytes ( & mut bytes[ ..] ) ;
167
+ assert_eq ! ( size, bytes. len( ) ) ;
168
+
169
+ let config = random_config ( & mut rng) ;
170
+
171
+ encode_config_buf ( & bytes[ ..] , config, & mut b64) ;
172
+
173
+ let mut base_reader = io:: Cursor :: new ( & b64[ ..] ) ;
174
+ let mut decoder = DecoderReader :: new ( & mut base_reader, config) ;
175
+ let mut short_reader = RandomShortRead {
176
+ delegate : & mut decoder,
177
+ rng : & mut rand:: thread_rng ( ) ,
178
+ } ;
179
+
180
+ consume_with_short_reads_and_validate ( & mut rng, & bytes[ ..] , & mut decoded, & mut short_reader)
164
181
}
165
182
}
166
183
@@ -268,6 +285,38 @@ fn reports_invalid_byte_correctly() {
268
285
}
269
286
}
270
287
288
+ fn consume_with_short_reads_and_validate < R : Read > (
289
+ rng : & mut rand:: rngs:: ThreadRng ,
290
+ expected_bytes : & [ u8 ] ,
291
+ decoded : & mut Vec < u8 > ,
292
+ short_reader : & mut R ,
293
+ ) -> ( ) {
294
+ let mut total_read = 0_usize ;
295
+ loop {
296
+ assert ! (
297
+ total_read <= expected_bytes. len( ) ,
298
+ "tr {} size {}" ,
299
+ total_read,
300
+ expected_bytes. len( )
301
+ ) ;
302
+ if total_read == expected_bytes. len ( ) {
303
+ assert_eq ! ( expected_bytes, & decoded[ ..total_read] ) ;
304
+ // should be done
305
+ assert_eq ! ( 0 , short_reader. read( & mut decoded[ ..] ) . unwrap( ) ) ;
306
+ // didn't write anything
307
+ assert_eq ! ( expected_bytes, & decoded[ ..total_read] ) ;
308
+
309
+ break ;
310
+ }
311
+ let decode_len = rng. gen_range ( 1 , cmp:: max ( 2 , expected_bytes. len ( ) * 2 ) ) ;
312
+
313
+ let read = short_reader
314
+ . read ( & mut decoded[ total_read..total_read + decode_len] )
315
+ . unwrap ( ) ;
316
+ total_read += read;
317
+ }
318
+ }
319
+
271
320
/// Limits how many bytes a reader will provide in each read call.
272
321
/// Useful for shaking out code that may work fine only with typical input sources that always fill
273
322
/// the buffer.
@@ -279,7 +328,7 @@ struct RandomShortRead<'a, 'b, R: io::Read, N: rand::Rng> {
279
328
impl < ' a , ' b , R : io:: Read , N : rand:: Rng > io:: Read for RandomShortRead < ' a , ' b , R , N > {
280
329
fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , io:: Error > {
281
330
// avoid 0 since it means EOF for non-empty buffers
282
- let effective_len = self . rng . gen_range ( 1 , 20 ) ;
331
+ let effective_len = cmp :: min ( self . rng . gen_range ( 1 , 20 ) , buf . len ( ) ) ;
283
332
284
333
self . delegate . read ( & mut buf[ ..effective_len] )
285
334
}
0 commit comments