@@ -358,11 +358,9 @@ where
358358// of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every
359359// time is 4,500 times (!) slower than a default reservation size of 32 if the
360360// reader has a very small amount of data to return.
361- //
362- // Because we're extending the buffer with uninitialized data for trusted
363- // readers, we need to make sure to truncate that if any of this panics.
364361pub ( crate ) fn default_read_to_end < R : Read + ?Sized > ( r : & mut R , buf : & mut Vec < u8 > ) -> Result < usize > {
365- let initial_len = buf. len ( ) ; // need to know so we can return how many bytes we read
362+ let start_len = buf. len ( ) ;
363+ let start_cap = buf. capacity ( ) ;
366364
367365 let mut initialized = 0 ; // Extra initalized bytes from previous loop iteration
368366 loop {
@@ -384,7 +382,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>
384382 }
385383
386384 if read_buf. filled_len ( ) == 0 {
387- break ;
385+ return Ok ( buf . len ( ) - start_len )
388386 }
389387
390388 // store how much was initialized but not filled
@@ -395,9 +393,27 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>
395393 unsafe {
396394 buf. set_len ( new_len) ;
397395 }
398- }
399396
400- Ok ( buf. len ( ) - initial_len)
397+ if buf. len ( ) == buf. capacity ( ) && buf. capacity ( ) == start_cap {
398+ // The buffer might be an exact fit. Let's read into a probe buffer
399+ // and see if it returns `Ok(0)`. If so, we've avoided an
400+ // unnecessary doubling of the capacity. But if not, append the
401+ // probe buffer to the primary buffer and let its capacity grow.
402+ let mut probe = [ 0u8 ; 32 ] ;
403+
404+ loop {
405+ match r. read ( & mut probe) {
406+ Ok ( 0 ) => return Ok ( buf. len ( ) - start_len) ,
407+ Ok ( n) => {
408+ buf. extend_from_slice ( & probe[ ..n] ) ;
409+ break ;
410+ }
411+ Err ( ref e) if e. kind ( ) == ErrorKind :: Interrupted => continue ,
412+ Err ( e) => return Err ( e) ,
413+ }
414+ }
415+ }
416+ }
401417}
402418
403419pub ( crate ) fn default_read_to_string < R : Read + ?Sized > (
0 commit comments