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<()>> {
|
) -> Poll<io::Result<()>> {
|
||||||
let this = &mut self.state;
|
let this = &mut self.state;
|
||||||
|
|
||||||
|
// reading nothing always succeeds
|
||||||
|
if buf.remaining() == 0 {
|
||||||
|
return Ok(()).into();
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match this {
|
match this {
|
||||||
State::Body {
|
State::Body {
|
||||||
|
|
@ -147,11 +152,8 @@ impl<R: AsyncRead + Unpin, T: Tag> AsyncRead for BytesReader<R, T> {
|
||||||
Pin::new(reader.as_mut().unwrap())
|
Pin::new(reader.as_mut().unwrap())
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut bytes_read = 0;
|
let bytes_read = ready!(with_limited(buf, remaining, |buf| {
|
||||||
ready!(with_limited(buf, remaining, |buf| {
|
reader.poll_read(cx, buf).map_ok(|()| buf.filled().len())
|
||||||
let ret = reader.poll_read(cx, buf);
|
|
||||||
bytes_read = buf.filled().len();
|
|
||||||
ret
|
|
||||||
}))?;
|
}))?;
|
||||||
|
|
||||||
*consumed += bytes_read as u64;
|
*consumed += bytes_read as u64;
|
||||||
|
|
@ -262,7 +264,11 @@ impl<R: AsyncBufRead + Unpin, T: Tag> AsyncBufRead for BytesReader<R, T> {
|
||||||
|
|
||||||
reader.consume(amt);
|
reader.consume(amt);
|
||||||
}
|
}
|
||||||
State::ReadTrailer(_) => unreachable!(),
|
State::ReadTrailer(_) => {
|
||||||
|
if amt != 0 {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
State::ReleaseTrailer { consumed, data } => {
|
State::ReleaseTrailer { consumed, data } => {
|
||||||
*consumed = amt
|
*consumed = amt
|
||||||
.checked_add(*consumed as usize)
|
.checked_add(*consumed as usize)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue