From 6186a0d916dfbb9e62b94bf291d6fb266a079ca5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 30 Jan 2023 00:45:05 +0100 Subject: [PATCH] io/region: accept incomplete block for final chunk --- src/io/region.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/io/region.rs b/src/io/region.rs index ac9784b..b75fcef 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -42,14 +42,6 @@ fn decode_chunk(buf: &[u8]) -> Result where T: DeserializeOwned, { - let (len_bytes, buf) = buf.split_at(4); - let len = u32::from_be_bytes(len_bytes.try_into().unwrap()) as usize; - - if len < 1 || len > buf.len() { - bail!("Invalid chunk size"); - } - let buf = &buf[..len]; - let (format, buf) = buf.split_at(1); if format[0] != 2 { bail!("Unknown chunk format"); @@ -92,7 +84,6 @@ impl Region { while !chunk_map.is_empty() { let Some(ChunkDesc { coords, len }) = chunk_map.remove(&index) else { - reader.seek(SeekFrom::Current(BLOCKSIZE as i64)).context("Failed to seek chunk data")?; index += 1; continue; }; @@ -102,7 +93,20 @@ impl Region { } seen[coords] = true; - let mut buffer = vec![0; (len as usize) * BLOCKSIZE]; + reader + .seek(SeekFrom::Start(index as u64 * BLOCKSIZE as u64)) + .context("Failed to seek chunk data")?; + + let mut len_buf = [0u8; 4]; + reader + .read_exact(&mut len_buf) + .with_context(|| format!("Failed to read length for chunk {:?}", coords))?; + let byte_len = u32::from_be_bytes(len_buf) as usize; + if byte_len < 1 || byte_len > (len as usize) * BLOCKSIZE - 4 { + bail!("Invalid length for chunk {:?}", coords); + } + + let mut buffer = vec![0; byte_len]; reader .read_exact(&mut buffer) .with_context(|| format!("Failed to read data for chunk {:?}", coords))?;