Update h2-fuzz to std-future
This commit is contained in:
committed by
Sean McArthur
parent
97a4c8049c
commit
517077c698
@@ -1,15 +1,15 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "h2-fuzz"
|
name = "h2-fuzz"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
publish = false
|
publish = false
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
h2 = { path = "../.." }
|
h2 = { path = "../.." }
|
||||||
|
|
||||||
env_logger = { version = "0.5.3", default-features = false }
|
env_logger = { version = "0.5.3", default-features = false }
|
||||||
futures = "0.1.21"
|
futures-preview = "0.3.0-alpha.18"
|
||||||
honggfuzz = "0.5"
|
honggfuzz = "0.5"
|
||||||
http = "0.1.3"
|
http = "0.1.3"
|
||||||
tokio-io = "0.1.4"
|
tokio = { git = "https://github.com/tokio-rs/tokio" }
|
||||||
|
|||||||
@@ -1,154 +1,127 @@
|
|||||||
use futures::prelude::*;
|
#![feature(async_await)]
|
||||||
use futures::{executor, future, task};
|
use std::future::Future;
|
||||||
use http::{Method, Request};
|
use futures::Stream;
|
||||||
use std::cell::Cell;
|
use std::task::{Context, Poll};
|
||||||
use std::io::{self, Read, Write};
|
use std::pin::Pin;
|
||||||
use std::sync::Arc;
|
use futures::future;
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use http::{Method, Request};
|
||||||
use futures::stream::futures_unordered::FuturesUnordered;
|
use std::io;
|
||||||
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
struct MockIo<'a> {
|
use futures::stream::FuturesUnordered;
|
||||||
input: &'a [u8],
|
|
||||||
}
|
struct MockIo<'a> {
|
||||||
|
input: &'a [u8],
|
||||||
impl<'a> MockIo<'a> {
|
}
|
||||||
fn next_byte(&mut self) -> Option<u8> {
|
|
||||||
if let Some(&c) = self.input.first() {
|
impl<'a> MockIo<'a> {
|
||||||
self.input = &self.input[1..];
|
fn next_byte(&mut self) -> Option<u8> {
|
||||||
Some(c)
|
if let Some(&c) = self.input.first() {
|
||||||
} else {
|
self.input = &self.input[1..];
|
||||||
None
|
Some(c)
|
||||||
}
|
} else {
|
||||||
}
|
None
|
||||||
|
}
|
||||||
fn next_u32(&mut self) -> u32 {
|
}
|
||||||
(self.next_byte().unwrap_or(0) as u32) << 8 | self.next_byte().unwrap_or(0) as u32
|
|
||||||
}
|
fn next_u32(&mut self) -> u32 {
|
||||||
}
|
(self.next_byte().unwrap_or(0) as u32) << 8 | self.next_byte().unwrap_or(0) as u32
|
||||||
|
}
|
||||||
impl<'a> Read for MockIo<'a> {
|
}
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
|
|
||||||
let mut len = self.next_u32() as usize;
|
impl<'a> AsyncRead for MockIo<'a> {
|
||||||
if self.input.is_empty() {
|
unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool {
|
||||||
Ok(0)
|
false
|
||||||
} else if len == 0 {
|
}
|
||||||
task::current().notify();
|
|
||||||
Err(io::ErrorKind::WouldBlock.into())
|
fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<io::Result<usize>> {
|
||||||
} else {
|
let mut len = self.next_u32() as usize;
|
||||||
if len > self.input.len() {
|
if self.input.is_empty() {
|
||||||
len = self.input.len();
|
Poll::Ready(Ok(0))
|
||||||
}
|
} else if len == 0 {
|
||||||
|
cx.waker().clone().wake();
|
||||||
if len > buf.len() {
|
Poll::Pending
|
||||||
len = buf.len();
|
} else {
|
||||||
}
|
if len > self.input.len() {
|
||||||
buf[0..len].copy_from_slice(&self.input[0..len]);
|
len = self.input.len();
|
||||||
self.input = &self.input[len..];
|
}
|
||||||
Ok(len)
|
|
||||||
}
|
if len > buf.len() {
|
||||||
}
|
len = buf.len();
|
||||||
}
|
}
|
||||||
|
buf[0..len].copy_from_slice(&self.input[0..len]);
|
||||||
impl<'a> AsyncRead for MockIo<'a> {
|
self.input = &self.input[len..];
|
||||||
unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool {
|
Poll::Ready(Ok(len))
|
||||||
false
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Write for MockIo<'a> {
|
impl<'a> AsyncWrite for MockIo<'a> {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
|
fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {
|
||||||
let len = std::cmp::min(self.next_u32() as usize, buf.len());
|
let len = std::cmp::min(self.next_u32() as usize, buf.len());
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
if self.input.is_empty() {
|
if self.input.is_empty() {
|
||||||
Err(io::ErrorKind::BrokenPipe.into())
|
Poll::Ready(Err(io::ErrorKind::BrokenPipe.into()))
|
||||||
} else {
|
} else {
|
||||||
task::current().notify();
|
cx.waker().clone().wake();
|
||||||
Err(io::ErrorKind::WouldBlock.into())
|
Poll::Pending
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(len)
|
Poll::Ready(Ok(len))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> Result<(), io::Error> {
|
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||||
Ok(())
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||||
impl<'a> AsyncWrite for MockIo<'a> {
|
Poll::Ready(Ok(()))
|
||||||
fn shutdown(&mut self) -> Poll<(), io::Error> {
|
}
|
||||||
Ok(Async::Ready(()))
|
}
|
||||||
}
|
|
||||||
}
|
async fn run(script: &[u8]) -> Result<(), h2::Error> {
|
||||||
|
let io = MockIo { input: script };
|
||||||
struct MockNotify {
|
let (mut h2, mut connection) = h2::client::handshake(io).await?;
|
||||||
notified: Cell<bool>,
|
let mut futs = FuturesUnordered::new();
|
||||||
}
|
let future = future::poll_fn(|cx| {
|
||||||
|
if let Poll::Ready(()) = Pin::new(&mut connection).poll(cx)? {
|
||||||
unsafe impl Sync for MockNotify {}
|
return Poll::Ready(Ok::<_, h2::Error>(()));
|
||||||
|
}
|
||||||
impl executor::Notify for MockNotify {
|
while futs.len() < 128 {
|
||||||
fn notify(&self, _id: usize) {
|
if !h2.poll_ready(cx)?.is_ready() {
|
||||||
self.notified.set(true);
|
break;
|
||||||
}
|
}
|
||||||
}
|
let request = Request::builder()
|
||||||
|
.method(Method::POST)
|
||||||
impl MockNotify {
|
.uri("https://example.com/")
|
||||||
fn take_notify(&self) -> bool {
|
.body(())
|
||||||
self.notified.replace(false)
|
.unwrap();
|
||||||
}
|
let (resp, mut send) = h2.send_request(request, false)?;
|
||||||
}
|
send.send_data(vec![0u8; 32769].into(), true).unwrap();
|
||||||
|
drop(send);
|
||||||
fn run(script: &[u8]) -> Result<(), h2::Error> {
|
futs.push(resp);
|
||||||
let notify = Arc::new(MockNotify {
|
}
|
||||||
notified: Cell::new(false),
|
loop {
|
||||||
});
|
match Pin::new(&mut futs).poll_next(cx) {
|
||||||
let notify_handle: executor::NotifyHandle = notify.clone().into();
|
Poll::Pending | Poll::Ready(None) => break,
|
||||||
let io = MockIo { input: script };
|
r @ Poll::Ready(Some(Ok(_))) | r @ Poll::Ready(Some(Err(_))) => {
|
||||||
let (mut h2, mut connection) = h2::client::handshake(io).wait()?;
|
eprintln!("{:?}", r);
|
||||||
let mut futs = FuturesUnordered::new();
|
}
|
||||||
let future = future::poll_fn(|| {
|
}
|
||||||
if let Async::Ready(()) = connection.poll()? {
|
}
|
||||||
return Ok(Async::Ready(()));
|
Poll::Pending
|
||||||
}
|
});
|
||||||
while futs.len() < 128 {
|
|
||||||
if h2.poll_ready()?.is_not_ready() {
|
future.await?;
|
||||||
break;
|
Ok(())
|
||||||
}
|
}
|
||||||
let request = Request::builder()
|
|
||||||
.method(Method::POST)
|
fn main() {
|
||||||
.uri("https://example.com/")
|
env_logger::init();
|
||||||
.body(())
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
.unwrap();
|
loop {
|
||||||
let (resp, mut send) = h2.send_request(request, false)?;
|
honggfuzz::fuzz!(|data: &[u8]| {
|
||||||
send.send_data(vec![0u8; 32769].into(), true).unwrap();
|
eprintln!("{:?}", rt.block_on(run(data)));
|
||||||
drop(send);
|
});
|
||||||
futs.push(resp);
|
}
|
||||||
}
|
}
|
||||||
loop {
|
|
||||||
match futs.poll() {
|
|
||||||
Ok(Async::NotReady) | Ok(Async::Ready(None)) => break,
|
|
||||||
r @ Ok(Async::Ready(_)) | r @ Err(_) => {
|
|
||||||
eprintln!("{:?}", r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok::<_, h2::Error>(Async::NotReady)
|
|
||||||
});
|
|
||||||
let mut spawn = executor::spawn(future);
|
|
||||||
loop {
|
|
||||||
if let Async::Ready(()) = spawn.poll_future_notify(¬ify_handle, 0)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
assert!(notify.take_notify());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
env_logger::init();
|
|
||||||
loop {
|
|
||||||
honggfuzz::fuzz!(|data: &[u8]| {
|
|
||||||
eprintln!("{:?}", run(data));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user