Skip to content

Commit

Permalink
Merge pull request #172 from rust-secure-code/upgrade-and-insulate-mi…
Browse files Browse the repository at this point in the history
…niz-oxide

Upgrade and insulate miniz oxide
  • Loading branch information
Shnatsel authored Nov 11, 2024
2 parents e89342f + bf9ab62 commit 88a2b2d
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 21 deletions.
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion auditable-info/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ edition = "2018"

[dependencies]
auditable-extract = {version = "0.3.4", path = "../auditable-extract", default-features = false }
miniz_oxide = { version = "0.6.2", features = ["std"] }
miniz_oxide = { version = "0.8.0", features = ["std"] }
auditable-serde = {version = "0.7.0", path = "../auditable-serde", optional = true}
serde_json = { version = "1.0.57", optional = true }

Expand Down
72 changes: 68 additions & 4 deletions auditable-info/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub enum Error {
OutputLimitExceeded,
Io(std::io::Error),
BinaryParsing(auditable_extract::Error),
Decompression(miniz_oxide::inflate::DecompressError),
Decompression(DecompressError),
#[cfg(feature = "serde")]
Json(serde_json::Error),
Utf8(std::str::Utf8Error),
Expand Down Expand Up @@ -58,10 +58,10 @@ impl From<auditable_extract::Error> for Error {
}
}

impl From<miniz_oxide::inflate::DecompressError> for Error {
fn from(e: miniz_oxide::inflate::DecompressError) -> Self {
impl From<DecompressError> for Error {
fn from(e: DecompressError) -> Self {
match e.status {
miniz_oxide::inflate::TINFLStatus::HasMoreOutput => Error::OutputLimitExceeded,
TINFLStatus::HasMoreOutput => Error::OutputLimitExceeded,
_ => Error::Decompression(e),
}
}
Expand All @@ -79,3 +79,67 @@ impl From<serde_json::Error> for Error {
Self::Json(e)
}
}

/// A copy of [miniz_oxide::inflate::DecompressError].
///
/// We use our copy instead of the miniz_oxide type directly
/// so that we don't have to bump semver every time `miniz_oxide` does.
#[derive(Debug)]
pub struct DecompressError {
/// Decompressor status on failure. See [TINFLStatus] for details.
pub status: TINFLStatus,
/// The currently decompressed data if any.
pub output: Vec<u8>,
}

impl std::fmt::Display for DecompressError {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_str(match self.status {
TINFLStatus::FailedCannotMakeProgress => "Truncated input stream",
TINFLStatus::BadParam => "Invalid output buffer size",
TINFLStatus::Adler32Mismatch => "Adler32 checksum mismatch",
TINFLStatus::Failed => "Invalid input data",
TINFLStatus::Done => unreachable!(),
TINFLStatus::NeedsMoreInput => "Truncated input stream",
TINFLStatus::HasMoreOutput => "Output size exceeded the specified limit",
})
}
}

impl std::error::Error for DecompressError {}

impl DecompressError {
pub(crate) fn from_miniz(err: miniz_oxide::inflate::DecompressError) -> Self {
Self {
status: TINFLStatus::from_miniz(err.status),
output: err.output,
}
}
}

#[repr(i8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum TINFLStatus {
FailedCannotMakeProgress,
BadParam,
Adler32Mismatch,
Failed,
Done,
NeedsMoreInput,
HasMoreOutput,
}

impl TINFLStatus {
pub(crate) fn from_miniz(status: miniz_oxide::inflate::TINFLStatus) -> Self {
use miniz_oxide::inflate;
match status {
inflate::TINFLStatus::FailedCannotMakeProgress => Self::FailedCannotMakeProgress,
inflate::TINFLStatus::BadParam => Self::BadParam,
inflate::TINFLStatus::Adler32Mismatch => Self::Adler32Mismatch,
inflate::TINFLStatus::Failed => Self::Failed,
inflate::TINFLStatus::Done => Self::Done,
inflate::TINFLStatus::NeedsMoreInput => Self::NeedsMoreInput,
inflate::TINFLStatus::HasMoreOutput => Self::HasMoreOutput,
}
}
}
8 changes: 5 additions & 3 deletions auditable-info/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use std::path::Path;

mod error;

pub use crate::error::Error;
pub use crate::error::*;

/// Loads audit info from the specified binary compiled with `cargo auditable`.
///
Expand Down Expand Up @@ -82,7 +82,8 @@ pub fn audit_info_from_reader<T: BufRead>(
pub fn json_from_reader<T: BufRead>(reader: &mut T, limits: Limits) -> Result<String, Error> {
let compressed_data = get_compressed_audit_data(reader, limits)?;
let decompressed_data =
decompress_to_vec_zlib_with_limit(&compressed_data, limits.decompressed_json_size)?;
decompress_to_vec_zlib_with_limit(&compressed_data, limits.decompressed_json_size)
.map_err(DecompressError::from_miniz)?;
Ok(String::from_utf8(decompressed_data)?)
}

Expand Down Expand Up @@ -144,7 +145,8 @@ pub fn json_from_slice(
Err(Error::OutputLimitExceeded)?;
}
let decompressed_data =
decompress_to_vec_zlib_with_limit(compressed_audit_data, decompressed_json_size_limit)?;
decompress_to_vec_zlib_with_limit(compressed_audit_data, decompressed_json_size_limit)
.map_err(DecompressError::from_miniz)?;
Ok(String::from_utf8(decompressed_data)?)
}

Expand Down
2 changes: 1 addition & 1 deletion cargo-auditable/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ readme = "../README.md"
[dependencies]
object = {version = "0.30", default-features = false, features = ["write"]}
auditable-serde = {version = "0.7.0", path = "../auditable-serde", features = ["from_metadata"]}
miniz_oxide = {version = "0.6.0"}
miniz_oxide = {version = "0.8.0"}
serde_json = "1.0.57"
cargo_metadata = "0.18"
pico-args = "0.5"
Expand Down
12 changes: 6 additions & 6 deletions rust-audit-info/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 88a2b2d

Please sign in to comment.