aboutsummaryrefslogtreecommitdiff
path: root/tests/io_read_to_end.rs
blob: 892d463c2dd1bc7a25f609088762d3f4b77fdcf6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use futures::{
    io::{self, AsyncRead, AsyncReadExt},
    task::{Context, Poll},
};
use std::pin::Pin;

#[test]
#[should_panic(expected = "assertion failed: n <= buf.len()")]
fn issue2310() {
    struct MyRead {
        first: bool,
    }

    impl MyRead {
        pub fn new() -> Self {
            MyRead { first: false }
        }
    }

    impl AsyncRead for MyRead {
        fn poll_read(
            mut self: Pin<&mut Self>,
            _cx: &mut Context,
            _buf: &mut [u8],
        ) -> Poll<io::Result<usize>> {
            Poll::Ready(if !self.first {
                self.first = true;
                // First iteration: return more than the buffer size
                Ok(64)
            } else {
                // Second iteration: indicate that we are done
                Ok(0)
            })
        }
    }

    struct VecWrapper {
        inner: Vec<u8>,
    }

    impl VecWrapper {
        pub fn new() -> Self {
            VecWrapper { inner: Vec::new() }
        }
    }

    impl Drop for VecWrapper {
        fn drop(&mut self) {
            // Observe uninitialized bytes
            println!("{:?}", &self.inner);
            // Overwrite heap contents
            for b in &mut self.inner {
                *b = 0x90;
            }
        }
    }

    futures::executor::block_on(async {
        let mut vec = VecWrapper::new();
        let mut read = MyRead::new();

        read.read_to_end(&mut vec.inner).await.unwrap();
    })
}