-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use
Pin<Box<S>>
in BodyStream
and SizedStream
Fixes #1321 A better fix would be to change `MessageBody` to take a `Pin<&mut Self>`, rather than a `Pin<&mut Self>`. This will avoid requiring the use of `Box` for all consumers by allowing the caller to determine how to pin the `MessageBody` implementation (e.g. via stack pinning). However, doing so is a breaking change that will affect every user of `MessageBody`. By pinning the inner stream ourselves, we can fix the undefined behavior without breaking the API. I've included @sebzim4500's reproduction case as a new test case. However, due to the nature of undefined behavior, this could pass (and not segfault) even if underlying issue were to regress. Unfortunately, until rust-lang/unsafe-code-guidelines#148 is resolved, it's not even possible to write a Miri test that will pass when the bug is fixed.
- Loading branch information
Showing
2 changed files
with
32 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Regression test for #/1321 | ||
|
||
use futures::task::{noop_waker, Context}; | ||
use futures::stream::once; | ||
use actix_http::body::{MessageBody, BodyStream}; | ||
use bytes::Bytes; | ||
|
||
#[test] | ||
fn weird_poll() { | ||
let (sender, receiver) = futures::channel::oneshot::channel(); | ||
let mut body_stream = Ok(BodyStream::new(once(async { | ||
let x = Box::new(0); | ||
let y = &x; | ||
receiver.await.unwrap(); | ||
let _z = **y; | ||
Ok::<_, ()>(Bytes::new()) | ||
}))); | ||
|
||
let waker = noop_waker(); | ||
let mut context = Context::from_waker(&waker); | ||
|
||
let _ = body_stream.as_mut().unwrap().poll_next(&mut context); | ||
sender.send(()).unwrap(); | ||
let _ = std::mem::replace(&mut body_stream, Err([0; 32])).unwrap().poll_next(&mut context); | ||
} | ||
|