ParseOptions: Add allocation_limit()

This commit is contained in:
Serial 2023-10-22 12:54:17 -04:00 committed by Alex
parent f08da59e24
commit ab828fbe15
3 changed files with 29 additions and 4 deletions

View file

@ -6,8 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Added
- **ParseOptions**: `ParseOptions::allocation_limit` to change the default allocation limit.
### Changed ### Changed
- **VorbisComments**: When converting from `Tag` to `VorbisComments`, `ItemKey::Unknown`s will be checked for spec compliance. ([PR](https://github.com/Serial-ATA/lofty-rs/pull/272)) - **VorbisComments**: When converting from `Tag` to `VorbisComments`, `ItemKey::Unknown`s will be checked for spec compliance. ([PR](https://github.com/Serial-ATA/lofty-rs/pull/272))
- **Alloc**: The default allocation limit for any single tag item is now **16MB**.
### Fixed ### Fixed
- **MP4**: Verify atom identifiers fall within a subset of characters ([PR](https://github.com/Serial-ATA/lofty-rs/pull/267)) - **MP4**: Verify atom identifiers fall within a subset of characters ([PR](https://github.com/Serial-ATA/lofty-rs/pull/267))

View file

@ -28,6 +28,7 @@ pub struct ParseOptions {
pub(crate) use_custom_resolvers: bool, pub(crate) use_custom_resolvers: bool,
pub(crate) parsing_mode: ParsingMode, pub(crate) parsing_mode: ParsingMode,
pub(crate) max_junk_bytes: usize, pub(crate) max_junk_bytes: usize,
pub(crate) allocation_limit: usize,
} }
impl Default for ParseOptions { impl Default for ParseOptions {
@ -55,6 +56,9 @@ impl ParseOptions {
/// Default number of junk bytes to read /// Default number of junk bytes to read
pub const DEFAULT_MAX_JUNK_BYTES: usize = 1024; pub const DEFAULT_MAX_JUNK_BYTES: usize = 1024;
/// Default allocation limit for any single tag item
pub const DEFAULT_ALLOCATION_LIMIT: usize = 16 * 1024 * 1024;
/// Creates a new `ParseOptions`, alias for `Default` implementation /// Creates a new `ParseOptions`, alias for `Default` implementation
/// ///
/// See also: [`ParseOptions::default`] /// See also: [`ParseOptions::default`]
@ -73,6 +77,7 @@ impl ParseOptions {
use_custom_resolvers: true, use_custom_resolvers: true,
parsing_mode: Self::DEFAULT_PARSING_MODE, parsing_mode: Self::DEFAULT_PARSING_MODE,
max_junk_bytes: Self::DEFAULT_MAX_JUNK_BYTES, max_junk_bytes: Self::DEFAULT_MAX_JUNK_BYTES,
allocation_limit: Self::DEFAULT_ALLOCATION_LIMIT,
} }
} }
@ -140,6 +145,24 @@ impl ParseOptions {
self.max_junk_bytes = max_junk_bytes; self.max_junk_bytes = max_junk_bytes;
*self *self
} }
/// The maximum number of bytes to allocate for any single tag item
///
/// This is a safety measure to prevent allocating too much memory for a single tag item. If a tag item
/// exceeds this limit, the allocator will return [`ErrorKind::TooMuchData`].
///
/// # Examples
///
/// ```rust
/// use lofty::ParseOptions;
///
/// // I have files with gigantic images, I'll double the allocation limit!
/// let parsing_options = ParseOptions::new().allocation_limit(32 * 1024 * 1024);
/// ```
pub fn allocation_limit(&mut self, allocation_limit: usize) -> Self {
self.allocation_limit = allocation_limit;
*self
}
} }
/// The parsing strictness mode /// The parsing strictness mode

View file

@ -1,8 +1,6 @@
use crate::error::Result; use crate::error::Result;
use crate::macros::err; use crate::macros::err;
use crate::probe::ParseOptions;
// We have an allocation limit of 16MB for any one item
const ALLOCATION_LIMIT: usize = 16 * 1024 * 1024;
/// Provides the `fallible_repeat` method on `Vec` /// Provides the `fallible_repeat` method on `Vec`
/// ///
@ -22,7 +20,7 @@ impl<T> VecFallibleRepeat<T> for Vec<T> {
return Ok(self); return Ok(self);
} }
if expected_size > ALLOCATION_LIMIT { if expected_size > ParseOptions::DEFAULT_ALLOCATION_LIMIT {
err!(TooMuchData); err!(TooMuchData);
} }