From 042f60fd3b633965733a9cdcb02217277b1cec1b Mon Sep 17 00:00:00 2001 From: Pascal Seitz Date: Mon, 6 Feb 2023 23:22:18 +0800 Subject: [PATCH] allow to pass buffer larger than size, warn on missing docs --- src/block/decompress.rs | 33 +++++++++++++++++---------------- src/block/decompress_safe.rs | 36 ++++++++++++++++++------------------ src/block/mod.rs | 16 +++++----------- src/frame/decompress.rs | 4 ---- src/frame/header.rs | 10 +++++++++- src/frame/mod.rs | 8 +++++++- src/lib.rs | 1 + 7 files changed, 57 insertions(+), 51 deletions(-) diff --git a/src/block/decompress.rs b/src/block/decompress.rs index 1dacf37..c345140 100644 --- a/src/block/decompress.rs +++ b/src/block/decompress.rs @@ -462,21 +462,22 @@ pub fn decompress_into_with_dict( } /// Decompress all bytes of `input` into a new vec. +/// The passed parameter `min_uncompressed_size` needs to be equal or larger than the uncompressed size. +/// +/// # Panics +/// May panic if the parameter `min_uncompressed_size` is smaller than the +/// uncompressed data. + #[inline] pub fn decompress_with_dict( input: &[u8], - uncompressed_size: usize, + min_uncompressed_size: usize, ext_dict: &[u8], ) -> Result, DecompressError> { // Allocate a vector to contain the decompressed stream. - let mut vec = get_vec_with_size(uncompressed_size); + let mut vec = get_vec_with_size(min_uncompressed_size); let decomp_len = decompress_into_with_dict(input, &mut vec[..], ext_dict)?; - if decomp_len != uncompressed_size { - return Err(DecompressError::UncompressedSizeDiffers { - expected: uncompressed_size, - actual: decomp_len, - }); - } + vec.truncate(decomp_len); Ok(vec) } @@ -489,17 +490,17 @@ pub fn decompress_size_prepended(input: &[u8]) -> Result, DecompressErro } /// Decompress all bytes of `input` into a new vec. +/// The passed parameter `min_uncompressed_size` needs to be equal or larger than the uncompressed size. +/// +/// # Panics +/// May panic if the parameter `min_uncompressed_size` is smaller than the +/// uncompressed data. #[inline] -pub fn decompress(input: &[u8], uncompressed_size: usize) -> Result, DecompressError> { +pub fn decompress(input: &[u8], min_uncompressed_size: usize) -> Result, DecompressError> { // Allocate a vector to contain the decompressed stream. - let mut vec = get_vec_with_size(uncompressed_size); + let mut vec = get_vec_with_size(min_uncompressed_size); let decomp_len = decompress_into(input, &mut vec[..])?; - if decomp_len != uncompressed_size { - return Err(DecompressError::UncompressedSizeDiffers { - expected: uncompressed_size, - actual: decomp_len, - }); - } + vec.truncate(decomp_len); Ok(vec) } diff --git a/src/block/decompress_safe.rs b/src/block/decompress_safe.rs index e62088b..56a40a3 100644 --- a/src/block/decompress_safe.rs +++ b/src/block/decompress_safe.rs @@ -5,6 +5,7 @@ use core::convert::TryInto; use crate::block::DecompressError; use crate::block::MINMATCH; use crate::sink::SliceSink; +use alloc::vec; use alloc::vec::Vec; /// Read an integer. @@ -323,18 +324,18 @@ pub fn decompress_size_prepended(input: &[u8]) -> Result, DecompressErro } /// Decompress all bytes of `input` into a new vec. +/// The passed parameter `min_uncompressed_size` needs to be equal or larger than the uncompressed size. +/// +/// # Panics +/// May panic if the parameter `min_uncompressed_size` is smaller than the +/// uncompressed data. #[inline] -pub fn decompress(input: &[u8], uncompressed_size: usize) -> Result, DecompressError> { - let mut decompressed: Vec = Vec::with_capacity(uncompressed_size); - decompressed.resize(uncompressed_size, 0); +pub fn decompress(input: &[u8], min_uncompressed_size: usize) -> Result, DecompressError> { + let mut decompressed: Vec = Vec::with_capacity(min_uncompressed_size); + decompressed.resize(min_uncompressed_size, 0); let decomp_len = decompress_internal::(input, &mut SliceSink::new(&mut decompressed, 0), b"")?; - if decomp_len != uncompressed_size { - return Err(DecompressError::UncompressedSizeDiffers { - expected: uncompressed_size, - actual: decomp_len, - }); - } + decompressed.truncate(decomp_len); Ok(decompressed) } @@ -350,22 +351,21 @@ pub fn decompress_size_prepended_with_dict( } /// Decompress all bytes of `input` into a new vec. +/// The passed parameter `min_uncompressed_size` needs to be equal or larger than the uncompressed size. +/// +/// # Panics +/// May panic if the parameter `min_uncompressed_size` is smaller than the +/// uncompressed data. #[inline] pub fn decompress_with_dict( input: &[u8], - uncompressed_size: usize, + min_uncompressed_size: usize, ext_dict: &[u8], ) -> Result, DecompressError> { - let mut decompressed: Vec = Vec::with_capacity(uncompressed_size); - decompressed.resize(uncompressed_size, 0); + let mut decompressed: Vec = vec![0; min_uncompressed_size]; let decomp_len = decompress_internal::(input, &mut SliceSink::new(&mut decompressed, 0), ext_dict)?; - if decomp_len != uncompressed_size { - return Err(DecompressError::UncompressedSizeDiffers { - expected: uncompressed_size, - actual: decomp_len, - }); - } + decompressed.truncate(decomp_len); Ok(decompressed) } diff --git a/src/block/mod.rs b/src/block/mod.rs index 75674ce..bb38677 100644 --- a/src/block/mod.rs +++ b/src/block/mod.rs @@ -81,12 +81,11 @@ static LZ4_64KLIMIT: usize = (64 * 1024) + (MFLIMIT - 1); #[derive(Debug)] #[non_exhaustive] pub enum DecompressError { + /// The provided output is too small OutputTooSmall { + /// Minimum expected output size expected: usize, - actual: usize, - }, - UncompressedSizeDiffers { - expected: usize, + /// Actual size of output actual: usize, }, /// Literal is out of bounds of the input @@ -99,7 +98,9 @@ pub enum DecompressError { #[derive(Debug)] #[non_exhaustive] +/// Errors that can happen during compression. pub enum CompressError { + /// The provided output is too small. OutputTooSmall, } @@ -123,13 +124,6 @@ impl fmt::Display for DecompressError { DecompressError::OffsetOutOfBounds => { f.write_str("the offset to copy is not contained in the decompressed buffer") } - DecompressError::UncompressedSizeDiffers { actual, expected } => { - write!( - f, - "the expected decompressed size differs, actual {}, expected {}", - actual, expected - ) - } } } } diff --git a/src/frame/decompress.rs b/src/frame/decompress.rs index 5d6f332..c1ec74f 100644 --- a/src/frame/decompress.rs +++ b/src/frame/decompress.rs @@ -89,10 +89,6 @@ impl FrameDecoder { } } - pub fn frame_info(&mut self) -> Option<&FrameInfo> { - self.current_frame_info.as_ref() - } - /// Gets a reference to the underlying reader in this decoder. pub fn get_ref(&self) -> &R { &self.r diff --git a/src/frame/header.rs b/src/frame/header.rs index 308ea7b..d3e81cc 100644 --- a/src/frame/header.rs +++ b/src/frame/header.rs @@ -35,12 +35,17 @@ pub(crate) const MAX_FRAME_INFO_SIZE: usize = 19; pub(crate) const BLOCK_INFO_SIZE: usize = 4; #[derive(Clone, Copy, PartialEq, Debug)] +/// Different predefines blocksizes to choose when compressing data. pub enum BlockSize { /// The default block size. Max64KB = 4, + /// 256KB block size. Max256KB = 5, + /// 1MB block size. Max1MB = 6, + /// 4MB block size. Max4MB = 7, + /// 8MB block size. Max8MB = 8, } @@ -51,7 +56,7 @@ impl Default for BlockSize { } impl BlockSize { - pub fn get_size(&self) -> usize { + pub(crate) fn get_size(&self) -> usize { match self { BlockSize::Max64KB => 64 * 1024, BlockSize::Max256KB => 256 * 1024, @@ -63,6 +68,7 @@ impl BlockSize { } #[derive(Clone, Copy, PartialEq, Debug)] +/// The two `BlockMode` operations that can be set on (`FrameInfo`)[FrameInfo] pub enum BlockMode { /// Every block is compressed independently. The default. Independent, @@ -114,6 +120,7 @@ impl Default for BlockMode { // | 4 bytes | | 0 - 4 bytes | // #[derive(Debug, Clone)] +/// The metadata for de/compressing with lz4 frame format. pub struct FrameInfo { /// If set, includes the total uncompressed size of data in the frame. pub content_size: Option, @@ -142,6 +149,7 @@ impl Default for FrameInfo { } impl FrameInfo { + /// Create a new `FrameInfo`. pub fn new() -> Self { Self { content_size: None, diff --git a/src/frame/mod.rs b/src/frame/mod.rs index 8a8d266..9cb484f 100644 --- a/src/frame/mod.rs +++ b/src/frame/mod.rs @@ -31,6 +31,7 @@ pub use header::{BlockMode, BlockSize, FrameInfo}; #[derive(Debug)] #[non_exhaustive] +/// Errors that can occur when de/compressing lz4. pub enum Error { /// Compression error. CompressionError(crate::block::CompressError), @@ -62,7 +63,12 @@ pub enum Error { /// External dictionaries are not supported. DictionaryNotSupported, /// Content length differs. - ContentLengthError { expected: u64, actual: u64 }, + ContentLengthError { + /// Expected content length. + expected: u64, + /// Actual content lenght. + actual: u64, + }, } impl From for io::Error { diff --git a/src/lib.rs b/src/lib.rs index f693dff..24b6659 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,7 @@ //! //! #![deny(warnings)] +#![deny(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] #[cfg_attr(test, macro_use)]