fix(nix-compat/wire/bytes/reader): handle zero cases
Legitimate zero-length reads could cause spurious unexpected EOF, since we implicitly assumed buffers always have remaining capacity. For the buffered case, `consume(0)` could cause panics after either `poll_fill_buf` or `poll_read` had returned `Poll::Pending`. The bytes_read/with_limited logic receives a stylistic cleanup to make it obvious that bytes_read is always written before being used. Change-Id: I46aa47113309552dcef9532b5d4009d2186db9cd Reviewed-on: https://cl.snix.dev/c/snix/+/30492 Tested-by: besadii Reviewed-by: Brian Olsen <brian@maven-group.org> Reviewed-by: Florian Klink <flokli@flokli.de>
This commit is contained in:
		
							parent
							
								
									9a8a9c6b67
								
							
						
					
					
						commit
						83c3305863
					
				
					 1 changed files with 12 additions and 6 deletions
				
			
		|  | @ -129,6 +129,11 @@ impl<R: AsyncRead + Unpin, T: Tag> AsyncRead for BytesReader<R, T> { | |||
|     ) -> Poll<io::Result<()>> { | ||||
|         let this = &mut self.state; | ||||
| 
 | ||||
|         // reading nothing always succeeds
 | ||||
|         if buf.remaining() == 0 { | ||||
|             return Ok(()).into(); | ||||
|         } | ||||
| 
 | ||||
|         loop { | ||||
|             match this { | ||||
|                 State::Body { | ||||
|  | @ -147,11 +152,8 @@ impl<R: AsyncRead + Unpin, T: Tag> AsyncRead for BytesReader<R, T> { | |||
|                         Pin::new(reader.as_mut().unwrap()) | ||||
|                     }; | ||||
| 
 | ||||
|                     let mut bytes_read = 0; | ||||
|                     ready!(with_limited(buf, remaining, |buf| { | ||||
|                         let ret = reader.poll_read(cx, buf); | ||||
|                         bytes_read = buf.filled().len(); | ||||
|                         ret | ||||
|                     let bytes_read = ready!(with_limited(buf, remaining, |buf| { | ||||
|                         reader.poll_read(cx, buf).map_ok(|()| buf.filled().len()) | ||||
|                     }))?; | ||||
| 
 | ||||
|                     *consumed += bytes_read as u64; | ||||
|  | @ -262,7 +264,11 @@ impl<R: AsyncBufRead + Unpin, T: Tag> AsyncBufRead for BytesReader<R, T> { | |||
| 
 | ||||
|                 reader.consume(amt); | ||||
|             } | ||||
|             State::ReadTrailer(_) => unreachable!(), | ||||
|             State::ReadTrailer(_) => { | ||||
|                 if amt != 0 { | ||||
|                     unreachable!(); | ||||
|                 } | ||||
|             } | ||||
|             State::ReleaseTrailer { consumed, data } => { | ||||
|                 *consumed = amt | ||||
|                     .checked_add(*consumed as usize) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue