You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The design of Buf::chunks_vectored() does not account for an implementation that returns a partial slice in chunk() and doesn't override chunks_vectored() to be the full thing. It's assumed that if you have a composite buf, such as Chain, that you can just fill the IoSlices with both.
use bytes::Buf;use std::io::IoSlice;structTrickle<'a>(&'a [u8]);impl<'a>BufforTrickle<'a>{fnremaining(&self) -> usize{self.0.len()}fnadvance(&mutself,n:usize){self.0 = &self.0[n..];}fnchunk(&self) -> &[u8]{&self.0[0..1]}}let ab = Trickle(b"hello").chain(&b"world"[..]);letmut io = [IoSlice::new(&[]);16];let n = ab.chunks_vectored(&mut io);println!("{:?}", &io[..n]);// [[104], [119, 111, 114, 108, 100]]// eg [[h], [world]]
Interestingly, the documentation for chunks_vectored even declares a guarantee that likely cannot be upheld:
If chunk_vectored does not fill every entry in dst, then dst is guaranteed to contain all remaining slices in self.
Solutions
With the way the function signature is designed, I don't see a cheap way to check after a call if it really represents all of the buf.
An expensive solution would be to provide a helper function that compares remaining() with what was placed in the &mut [IoSlice], and only if true, pass the rest of the slices to the next buffer in the list.
Another option I can think of is to design a whole new function, chunks_vectored_done_right(), with arguments/return types that prevent making that mistake, deprecating the existing method, and probably changing the default to use the expensive solution anyways.
The text was updated successfully, but these errors were encountered:
How about removing the guarantee about chunks_vectored being complete, and adding a new method chunks_vectored_is_complete that returns a boolean describing whether this type provides the guarantee that chunks_vectored always provides all slices.
The design of
Buf::chunks_vectored()
does not account for an implementation that returns a partial slice inchunk()
and doesn't overridechunks_vectored()
to be the full thing. It's assumed that if you have a composite buf, such asChain
, that you can just fill theIoSlice
s with both.First reported in hyperium/hyper#3650
Example
Interestingly, the documentation for
chunks_vectored
even declares a guarantee that likely cannot be upheld:Solutions
With the way the function signature is designed, I don't see a cheap way to check after a call if it really represents all of the
buf
.An expensive solution would be to provide a helper function that compares
remaining()
with what was placed in the&mut [IoSlice]
, and only if true, pass the rest of the slices to the next buffer in the list.Another option I can think of is to design a whole new function,
chunks_vectored_done_right()
, with arguments/return types that prevent making that mistake, deprecating the existing method, and probably changing the default to use the expensive solution anyways.The text was updated successfully, but these errors were encountered: