Skip to content

Commit

Permalink
Fix: parsing from IntoAsyncRead with small chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
arnauorriols committed May 7, 2024
1 parent 6e682db commit 843d326
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
30 changes: 25 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ impl Eszip {
reader: R,
) -> Result<(Eszip, EszipParserFuture<R>), ParseError> {
let mut reader = futures::io::BufReader::new(reader);
reader.fill_buf().await?;
let buffer = reader.buffer();
if EszipV2::has_magic(buffer) {
let (eszip, fut) = EszipV2::parse(reader).await?;
let mut magic = [0; 8];
reader.read_exact(&mut magic).await?;
if EszipV2::has_magic(&magic) {
let (eszip, fut) = EszipV2::parse_with_magic(&magic, reader).await?;
Ok((Eszip::V2(eszip), Box::pin(fut)))
} else {
let mut buffer = Vec::new();
reader.read_to_end(&mut buffer).await?;
let mut reader_w_magic = magic.chain(&mut reader);
reader_w_magic.read_to_end(&mut buffer).await?;
let eszip = EszipV1::parse(&buffer)?;
let fut = async move { Ok::<_, ParseError>(reader) };
Ok((Eszip::V1(eszip), Box::pin(fut)))
Expand Down Expand Up @@ -215,6 +216,9 @@ pub enum ModuleKind {
mod tests {
use super::*;
use futures::io::AllowStdIo;
use futures::stream;
use futures::StreamExt;
use futures::TryStreamExt;

#[tokio::test]
async fn parse_v1() {
Expand Down Expand Up @@ -351,4 +355,20 @@ mod tests {
);
}
}

#[tokio::test]
async fn parse_small_chunks_reader() {
let bytes = std::fs::read("./src/testdata/redirect.eszip2")
.unwrap()
.chunks(2)
.map(|chunk| chunk.to_vec())
.collect::<Vec<_>>();
let reader = stream::iter(bytes)
.map(std::io::Result::Ok)
.into_async_read();

let (eszip, fut) = Eszip::parse(reader).await.unwrap();
fut.await.unwrap();
assert!(matches!(eszip, Eszip::V2(_)));
}
}
13 changes: 13 additions & 0 deletions src/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,19 @@ impl EszipV2 {
return Err(ParseError::InvalidV2);
}

Self::parse_with_magic(&magic, reader).await
}

pub(super) async fn parse_with_magic<R: futures::io::AsyncRead + Unpin>(
magic: &[u8],
mut reader: futures::io::BufReader<R>,
) -> Result<
(
EszipV2,
impl Future<Output = Result<futures::io::BufReader<R>, ParseError>>,
),
ParseError,
> {
let is_v3 = magic == *ESZIP_V2_1_MAGIC;
let header = HashedSection::read(&mut reader).await?;
if !header.hash_valid() {
Expand Down

0 comments on commit 843d326

Please sign in to comment.