Bug 1967030 - Update mp4parse-rust to d3e4d255. r=media-playback-reviewers,supply-chain-reviewers,padenot

Differential Revision: https://phabricator.services.mozilla.com/D249858
This commit is contained in:
Matthew Gregan
2025-05-20 20:40:33 +00:00
committed by mgregan@mozilla.com
parent 251a73199e
commit 0888571e1e
23 changed files with 312 additions and 337 deletions

View File

@@ -95,9 +95,9 @@ git = "https://github.com/mozilla/midir.git"
rev = "85156e360a37d851734118104619f86bd18e94c6"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/mp4parse-rust?rev=e64650a686e5c5732395cd059e17cfd3b1e5b63b"]
[source."git+https://github.com/mozilla/mp4parse-rust?rev=d3e4d255bd149d341c7e90f5e9fc84e743a8e179"]
git = "https://github.com/mozilla/mp4parse-rust"
rev = "e64650a686e5c5732395cd059e17cfd3b1e5b63b"
rev = "d3e4d255bd149d341c7e90f5e9fc84e743a8e179"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/neqo?tag=v0.13.2"]

11
Cargo.lock generated
View File

@@ -1984,11 +1984,11 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
[[package]]
name = "fallible_collections"
version = "0.4.9"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a88c69768c0a15262df21899142bc6df9b9b823546d4b4b9a7bc2d6c448ec6fd"
checksum = "8b3e85d14d419ba3e1db925519461c0d17a49bdd2d67ea6316fa965ca7acdf74"
dependencies = [
"hashbrown 0.13.999",
"hashbrown 0.14.999",
]
[[package]]
@@ -2573,7 +2573,6 @@ dependencies = [
"dom_fragmentdirectives",
"encoding_glue",
"etagere",
"fallible_collections",
"fluent",
"fluent-fallback",
"fluent-ffi",
@@ -4604,7 +4603,7 @@ dependencies = [
[[package]]
name = "mp4parse"
version = "0.17.0"
source = "git+https://github.com/mozilla/mp4parse-rust?rev=e64650a686e5c5732395cd059e17cfd3b1e5b63b#e64650a686e5c5732395cd059e17cfd3b1e5b63b"
source = "git+https://github.com/mozilla/mp4parse-rust?rev=d3e4d255bd149d341c7e90f5e9fc84e743a8e179#d3e4d255bd149d341c7e90f5e9fc84e743a8e179"
dependencies = [
"bitreader",
"byteorder",
@@ -4621,7 +4620,7 @@ version = "0.1.0"
[[package]]
name = "mp4parse_capi"
version = "0.17.0"
source = "git+https://github.com/mozilla/mp4parse-rust?rev=e64650a686e5c5732395cd059e17cfd3b1e5b63b#e64650a686e5c5732395cd059e17cfd3b1e5b63b"
source = "git+https://github.com/mozilla/mp4parse-rust?rev=d3e4d255bd149d341c7e90f5e9fc84e743a8e179#d3e4d255bd149d341c7e90f5e9fc84e743a8e179"
dependencies = [
"byteorder",
"fallible_collections",

View File

@@ -2178,6 +2178,12 @@ criteria = "safe-to-deploy"
delta = "0.4.6 -> 0.4.9"
notes = "Mostly soundness fixes."
[[audits.fallible_collections]]
who = "Matthew Gregan <kinetik@flim.org>"
criteria = "safe-to-deploy"
delta = "0.4.9 -> 0.5.1"
notes = "Changes are largely removal of Rust < 1.57 support and dependency updates."
[[audits.fastrand]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"

View File

@@ -1 +1 @@
{"files":{"Cargo.toml":"050bb460a70e6ddd572fdf118e5d52ae8dc1c7801af6475ef2ab9dfd34d963ab","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","README.md":"63b0c7dac05e6dfba32dcd4cb8e671bb8b72525f67a6b17fa5b8f10fd2cab047","src/arc.rs":"fda02f28d359193cbc0ec988b7c8149e9212c1951dff9cba6041a9ebd7fa3f17","src/boxed.rs":"8d7b3afc19e27ca51a843490d346319807cfdcc268355272c3164756fd63c242","src/btree.rs":"b83820fc2a00e2e34127b3037abde8b945f0ca2785f3def725787e6813c3d3e0","src/btree/map.rs":"557ce3ff2d02c425adcb2b4ac53b6b6607c25c535aee8ffa4f12bf773fbcd763","src/btree/node.rs":"49feca8742513b1c29d2f949c1eb1b178b538097ae94ba9dc31b8323a6423ea6","src/btree/search.rs":"ae78f73f3e56ea277b0a02cc39454447b75e12a6c817ecfee00065b3ddbfff67","src/btree/set.rs":"607f0db0b189c39b41824fbbf6fd8d9c5fdf85cc40f4437b13152e7b86d2979f","src/format.rs":"5142970f6ac1fe66f667ee2565af786802e93e6728ec3a1b82ffaa9f6a6b5bce","src/hashmap.rs":"1b9bf03fd2f2d9412ea2dad6963e1d37d51662e7091424bfcdc44a502f4e64bc","src/lib.rs":"71c5dc986ad58a4515604a73a4b7f4d8b6f43d2831993ee8612c99978ff2bb42","src/rc.rs":"f327a0adcfd2b1e225913ae716deb96777ca562985ac64e3b83550111f809864","src/try_clone.rs":"725130e0ddacde1ff7c976de62fbe45d01c67412af395aa41cac4bcfb85f6a5f","src/try_reserve_error.rs":"5e8db6a538225e66fec5d9d3a4314939b5b0428180676eb55ab928875e4feefd","src/vec.rs":"4268ae1de90750c21503fc84bdbf46cd6ccf76e33ae7f7daf8050fb29b839db1"},"package":"a88c69768c0a15262df21899142bc6df9b9b823546d4b4b9a7bc2d6c448ec6fd"}
{"files":{"Cargo.toml":"70a708a66e4364764d00147d8e4f7189b3b95e1ff712f59fbe17a74f28409c46","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","README.md":"edbf4f0c8ab2b2eeec5f167205a3b70261a3f19f3426c21aead9011cc217ecdb","rustfmt.toml":"b52c3059df95b63e647dd5f7730ca032786486041775017e96f083b3ae464372","src/arc.rs":"d9a2a788166da905df2efba1106055fd35001c34f2d1baa460f81440a077c669","src/boxed.rs":"0e521e1c62d16cdcbf8ce955ab94667613b7ba508920ec89ed7f1048abe63f65","src/btree.rs":"b83820fc2a00e2e34127b3037abde8b945f0ca2785f3def725787e6813c3d3e0","src/btree/map.rs":"557ce3ff2d02c425adcb2b4ac53b6b6607c25c535aee8ffa4f12bf773fbcd763","src/btree/node.rs":"49feca8742513b1c29d2f949c1eb1b178b538097ae94ba9dc31b8323a6423ea6","src/btree/search.rs":"ae78f73f3e56ea277b0a02cc39454447b75e12a6c817ecfee00065b3ddbfff67","src/btree/set.rs":"607f0db0b189c39b41824fbbf6fd8d9c5fdf85cc40f4437b13152e7b86d2979f","src/format.rs":"5142970f6ac1fe66f667ee2565af786802e93e6728ec3a1b82ffaa9f6a6b5bce","src/hashmap.rs":"3c8eb3aa44fe588bc81f1726add4e35332822878203cd8c48b407bf87bef59d6","src/lib.rs":"e9f574c61012d379fda211e66da25a871186095fba94fb4b1765945d79380495","src/rc.rs":"a4c53d6e5a2b8230c79aed456cb574e839ce2d6c42ee08491bc0a824c8437fe4","src/try_clone.rs":"725130e0ddacde1ff7c976de62fbe45d01c67412af395aa41cac4bcfb85f6a5f","src/vec.rs":"0a09c7350681d9ff41d03c8ff8c26c437c311312ce9effc3eb6eb47c835c93d3"},"package":"8b3e85d14d419ba3e1db925519461c0d17a49bdd2d67ea6316fa965ca7acdf74"}

View File

@@ -10,26 +10,43 @@
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
edition = "2021"
rust-version = "1.64"
name = "fallible_collections"
version = "0.4.9"
version = "0.5.1"
authors = ["vcombey <vcombey@student.42.fr>"]
build = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "a crate which adds fallible allocation api to std collections"
readme = "README.md"
keywords = [
"fallible",
"allocation",
"collections",
"oom",
"try-reserve",
]
license = "MIT/Apache-2.0"
categories = [
"rust-patterns",
"memory-management",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/vcombey/fallible_collections.git"
[lib]
name = "fallible_collections"
path = "src/lib.rs"
[dependencies.hashbrown]
version = "0.13"
version = "0.14"
optional = true
[features]
default = ["hashmap"]
hashmap = ["hashbrown"]
hashmap = ["dep:hashbrown"]
rust_1_57 = []
std = []
std_io = ["std"]

View File

@@ -1,38 +1,34 @@
Fallible Collections.rs
==============
Implement api on rust collection wich returns a result when an allocation error occurs.
Implements APIs on Rust collections wich gracefully return a `Result` when an allocation error occurs.
This is inspired a lot by [RFC 2116](https://github.com/rust-lang/rfcs/blob/master/text/2116-alloc-me-maybe.md).
The api currently propose a fallible interface for Vec, Box, Arc, Btree and Rc,
a TryClone trait wich is implemented for primitive rust traits and a fallible format macro.
You can use this with try_clone_derive crate wich derive TryClone for your own types.
There are APIs for a fallible interface for `Vec`, `Box`, `BTree`, `HashMap`,
and a `TryClone` trait wich is implemented for primitive Rust traits and a fallible format macro.
You can use this with `try_clone_derive` crate wich derive `TryClone` for your own types.
# Getting Started
[fallible collections is available on crates.io](https://crates.io/crates/fallible_collections).
[`fallible_collections` is available on crates.io](https://crates.io/crates/fallible_collections).
It is recommended to look there for the newest released version, as well as links to the newest builds of the docs.
At the point of the last update of this README, the latest published version could be used like this:
Add the following dependency to your Cargo manifest...
Add feature std and rust_1_57 to use the stabilized try_reserve api and the std HashMap type. Obviously, you cannot combine it with the 'unstable' feature.
Add integration tests that can be run with the tiny_integration_tester command.
Add the following dependency to your Cargo manifest:
```toml
[dependencies]
fallible_collections = "0.4"
fallible_collections = "0.5"
# or
fallible_collections = { version = "0.4", features = ["std", "rust_1_57"] }
fallible_collections = { version = "0.5", features = ["std"] }
```
...and see the [docs](https://docs.rs/fallible_collections) for how to use it.
# Example
Exemple of using the FallibleBox interface.
Exemple of using the `FallibleBox` interface.
```rust
use fallible_collections::FallibleBox;
@@ -47,7 +43,8 @@ fn main() {
}
```
Exemple of using the FallibleVec interface.
Exemple of using the `FallibleVec` interface.
```rust
use fallible_collections::FallibleVec;

View File

@@ -0,0 +1,3 @@
# Basic formatting options
edition = "2018"

View File

@@ -1,16 +1,16 @@
//! Implement a Fallible Arc
#[cfg(any(not(feature = "unstable"), feature = "rust_1_57"))]
#[cfg(not(feature = "unstable"))]
use super::FallibleBox;
use super::TryClone;
use crate::TryReserveError;
#[cfg(any(not(feature = "unstable"), feature = "rust_1_57"))]
#[cfg(not(feature = "unstable"))]
use alloc::boxed::Box;
use alloc::sync::Arc;
/// trait to implement Fallible Arc
#[cfg_attr(
any(not(feature = "unstable"), feature = "rust_1_57"),
not(feature = "unstable"),
deprecated(
since = "0.3.1",
note = "this function is not completely fallible, it can panic !, see [issue](https://github.com/vcombey/fallible_collections/issues/13). help wanted"
@@ -27,13 +27,13 @@ pub trait FallibleArc<T> {
#[allow(deprecated)]
impl<T> FallibleArc<T> for Arc<T> {
fn try_new(t: T) -> Result<Self, TryReserveError> {
#[cfg(any(not(feature = "unstable"), feature = "rust_1_57"))]
#[cfg(not(feature = "unstable"))]
{
// doesn't work as the inner variable of arc are also stocked in the box
let b = <Box<T> as FallibleBox<T>>::try_new(t)?;
Ok(Arc::from(b))
}
#[cfg(all(feature = "unstable", not(feature = "rust_1_57")))]
#[cfg(feature = "unstable")]
{
use alloc::alloc::Layout;
use alloc::collections::TryReserveErrorKind;

View File

@@ -1,11 +1,10 @@
//! Implement Fallible Box
use super::TryClone;
use crate::TryReserveError;
use alloc::alloc::Layout;
use alloc::boxed::Box;
use core::borrow::Borrow;
use core::mem::ManuallyDrop;
use core::ops::Deref;
use core::ptr::NonNull;
/// trait to implement Fallible Box
pub trait FallibleBox<T> {
@@ -63,47 +62,15 @@ impl<T> Deref for TryBox<T> {
}
}
fn alloc(layout: Layout) -> Result<NonNull<u8>, TryReserveError> {
#[cfg(all(feature = "unstable", not(feature = "rust_1_57")))] // requires allocator_api
{
use alloc::collections::TryReserveErrorKind;
use core::alloc::Allocator;
alloc::alloc::Global
.allocate(layout)
.map_err(|_e| {
TryReserveErrorKind::AllocError {
layout,
non_exhaustive: (),
}
.into()
})
.map(|v| v.cast())
}
#[cfg(any(not(feature = "unstable"), feature = "rust_1_57"))]
{
match layout.size() {
0 => {
// Required for alloc safety
// See https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#safety-1
Ok(NonNull::dangling())
}
1..=core::usize::MAX => {
let ptr = unsafe { alloc::alloc::alloc(layout) };
core::ptr::NonNull::new(ptr).ok_or(TryReserveError::AllocError { layout })
}
_ => unreachable!("size must be non-negative"),
}
}
}
impl<T> FallibleBox<T> for Box<T> {
fn try_new(t: T) -> Result<Self, TryReserveError> {
let layout = Layout::for_value(&t);
let ptr = alloc(layout)?.as_ptr() as *mut T;
unsafe {
core::ptr::write(ptr, t);
Ok(Box::from_raw(ptr))
}
let mut vec = alloc::vec::Vec::new();
vec.try_reserve_exact(1)?;
vec.push(t);
// try_reserve_exact doesn't promise the exact size, but into_boxed_slice does.
// in practice the size is going to be okay anyway, so it won't realloc.
let ptr: *mut T = ManuallyDrop::new(vec.into_boxed_slice()).as_mut_ptr();
Ok(unsafe { Box::from_raw(ptr) })
}
}

View File

@@ -6,17 +6,17 @@ use core::default::Default;
use core::fmt::Debug;
use core::hash::Hash;
#[cfg(not(all(feature = "std", feature = "rust_1_57")))]
#[cfg(not(feature = "std"))]
type HashMap<K, V> = hashbrown::hash_map::HashMap<K, V>;
#[cfg(all(feature = "std", feature = "rust_1_57"))]
#[cfg(feature = "std")]
type HashMap<K, V> = std::collections::HashMap<K, V>;
#[cfg(not(all(feature = "std", feature = "rust_1_57")))]
use hashbrown::hash_map::{Iter, IntoIter};
#[cfg(not(feature = "std"))]
use hashbrown::hash_map::{IntoIter, Iter};
#[cfg(all(feature = "std", feature = "rust_1_57"))]
use std::collections::hash_map::{Iter, IntoIter};
#[cfg(feature = "std")]
use std::collections::hash_map::{IntoIter, Iter};
pub struct TryHashMap<K, V> {
inner: HashMap<K, V>,
@@ -87,20 +87,9 @@ where
#[inline(always)]
fn reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
#[cfg(not(all(feature = "std", feature = "rust_1_57")))]
{
self.inner.try_reserve(additional)
}
#[cfg(all(feature = "std", feature = "rust_1_57"))]
{
self.inner.try_reserve(additional).map_err(|_| {
crate::make_try_reserve_error(self.len(), additional,
core::mem::size_of::<K>() + core::mem::size_of::<V>(),
core::mem::align_of::<K>().max(core::mem::align_of::<V>()),
)
})
}
self.inner
.try_reserve(additional)
.map_err(|_| make_try_reserve_error())
}
}
@@ -137,3 +126,10 @@ fn tryhashmap_oom() {
_ => (),
}
}
#[cold]
fn make_try_reserve_error() -> TryReserveError {
let mut v: alloc::vec::Vec<[u8; 1024]> = alloc::vec::Vec::new();
// this will always overflow capacity
v.try_reserve(!0).unwrap_err()
}

View File

@@ -31,13 +31,6 @@
#![cfg_attr(feature = "unstable", feature(maybe_uninit_slice))]
#![cfg_attr(feature = "unstable", feature(maybe_uninit_uninit_array))]
#[cfg(all(feature = "unstable", feature = "rust_1_57"))]
compile_error!(
"The use of the 'unstable' feature combined with the \
'rust_1_57' feature, which is related to the partial stabilization \
of the allocator API since rustc version 1.57, does not make sense!"
);
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
@@ -49,7 +42,9 @@ pub mod vec;
pub use vec::*;
pub mod rc;
pub use rc::*;
#[cfg(target_has_atomic = "ptr")]
pub mod arc;
#[cfg(target_has_atomic = "ptr")]
pub use arc::*;
#[cfg(feature = "unstable")]
pub mod btree;
@@ -61,8 +56,7 @@ pub use hashmap::*;
pub mod format;
pub mod try_clone;
pub mod try_reserve_error;
pub use try_reserve_error::TryReserveError;
pub use alloc::collections::TryReserveError;
#[cfg(feature = "std_io")]
pub use vec::std_io::*;
@@ -83,13 +77,3 @@ pub trait TryClone {
where
Self: core::marker::Sized;
}
#[cfg(feature = "rust_1_57")]
fn make_try_reserve_error(len: usize, additional: usize, elem_size: usize, align: usize) -> TryReserveError {
if let Some(size) = len.checked_add(additional).and_then(|l| l.checked_mul(elem_size)) {
if let Ok(layout) = alloc::alloc::Layout::from_size_align(size, align) {
return TryReserveError::AllocError { layout }
}
}
TryReserveError::CapacityOverflow
}

View File

@@ -3,7 +3,15 @@ use super::FallibleBox;
use crate::TryReserveError;
use alloc::boxed::Box;
use alloc::rc::Rc;
/// trait to implement Fallible Rc
#[cfg_attr(
any(not(feature = "unstable"), feature = "rust_1_57"),
deprecated(
since = "0.4.9",
note = "this function is not completely fallible, it can panic!, see [issue](https://github.com/vcombey/fallible_collections/issues/13). help wanted"
)
)]
pub trait FallibleRc<T> {
/// try creating a new Rc, returning a Result<Box<T>,
/// TryReserveError> if allocation failed
@@ -12,6 +20,7 @@ pub trait FallibleRc<T> {
Self: Sized;
}
#[allow(deprecated)]
impl<T> FallibleRc<T> for Rc<T> {
fn try_new(t: T) -> Result<Self, TryReserveError> {
let b = <Box<T> as FallibleBox<T>>::try_new(t)?;

View File

@@ -1,19 +0,0 @@
#[cfg(all(feature = "unstable", not(feature = "rust_1_57")))]
pub use alloc::collections::TryReserveError;
#[cfg(all(feature = "hashmap", not(all(feature = "unstable", not(feature = "rust_1_57")))))]
pub use hashbrown::TryReserveError;
/// The error type for `try_reserve` methods.
#[cfg(all(not(feature = "hashmap"), not(all(feature = "unstable", not(feature = "rust_1_57")))))]
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum TryReserveError {
/// Error due to the computed capacity exceeding the collection's maximum
/// (usually `isize::MAX` bytes).
CapacityOverflow,
/// The memory allocator returned an error
AllocError {
/// The layout of the allocation request that failed.
layout: alloc::alloc::Layout,
},
}

View File

@@ -431,108 +431,22 @@ impl<'a, T> Iterator for IterMut<'a, T> {
}
}
/// Grow capacity exponentially
#[cold]
fn vec_try_reserve_for_growth<T>(v: &mut Vec<T>, additional: usize) -> Result<(), TryReserveError> {
// saturating, because can't use CapacityOverflow here if rust_1_57 flag is enabled
FallibleVec::try_reserve(v, additional.max(v.capacity().saturating_mul(2) - v.len()))
}
fn needs_to_grow<T>(v: &Vec<T>, len: usize) -> bool {
v.len().checked_add(len).map_or(true, |needed| needed > v.capacity())
}
#[cfg(not(any(feature = "unstable", feature = "rust_1_57")))]
fn vec_try_reserve<T>(v: &mut Vec<T>, additional: usize) -> Result<(), TryReserveError> {
let available = v.capacity().checked_sub(v.len()).expect("capacity >= len");
if additional > available {
let increase = additional
.checked_sub(available)
.expect("additional > available");
let new_cap = v
.capacity()
.checked_add(increase)
.ok_or(TryReserveError::CapacityOverflow)?;
vec_try_extend(v, new_cap)?;
debug_assert!(v.capacity() == new_cap);
}
Ok(())
}
#[cfg(not(any(feature = "unstable", feature = "rust_1_57")))]
fn vec_try_extend<T>(v: &mut Vec<T>, new_cap: usize) -> Result<(), TryReserveError> {
let old_len = v.len();
let old_cap: usize = v.capacity();
if old_cap >= new_cap {
return Ok(());
}
let elem_size = core::mem::size_of::<T>();
let new_alloc_size = new_cap
.checked_mul(elem_size)
.filter(|size| *size <= isize::MAX as usize)
.ok_or(TryReserveError::CapacityOverflow)?;
// required for alloc safety
// See https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#safety-1
// Should be unreachable given prior `old_cap >= new_cap` check.
assert!(new_alloc_size > 0);
let align = core::mem::align_of::<T>();
let (new_ptr, layout) = {
if old_cap == 0 {
let layout = Layout::from_size_align(new_alloc_size, align).expect("Invalid layout");
let new_ptr = unsafe { alloc(layout) };
(new_ptr, layout)
} else {
let old_alloc_size = old_cap
.checked_mul(elem_size)
.ok_or(TryReserveError::CapacityOverflow)?;
let layout = Layout::from_size_align(old_alloc_size, align).expect("Invalid layout");
let new_ptr = unsafe { realloc(v.as_mut_ptr() as *mut u8, layout, new_alloc_size) };
(new_ptr, layout)
}
};
if new_ptr.is_null() {
return Err(TryReserveError::AllocError { layout });
}
let new_vec = unsafe { Vec::from_raw_parts(new_ptr.cast(), old_len, new_cap) };
core::mem::forget(core::mem::replace(v, new_vec));
Ok(())
v.len()
.checked_add(len)
.map_or(true, |needed| needed > v.capacity())
}
impl<T> FallibleVec<T> for Vec<T> {
#[inline(always)]
fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
#[cfg(all(feature = "unstable", not(feature = "rust_1_57")))]
{
self.try_reserve(additional)
}
#[cfg(all(not(feature = "unstable"), not(feature = "rust_1_57")))]
{
vec_try_reserve(self, additional)
}
#[cfg(feature = "rust_1_57")]
{
// TryReserveError is an opaque type in 1.57
self.try_reserve(additional).map_err(|_| {
crate::make_try_reserve_error(self.len(), additional, core::mem::size_of::<T>(), core::mem::align_of::<T>())
})
}
}
#[inline]
fn try_push(&mut self, elem: T) -> Result<(), TryReserveError> {
if self.len() == self.capacity() {
vec_try_reserve_for_growth(self, 1)?;
self.try_reserve(1)?;
}
Ok(self.push(elem))
}
@@ -540,7 +454,7 @@ impl<T> FallibleVec<T> for Vec<T> {
#[inline]
fn try_push_give_back(&mut self, elem: T) -> Result<(), (T, TryReserveError)> {
if self.len() == self.capacity() {
if let Err(e) = vec_try_reserve_for_growth(self, 1) {
if let Err(e) = self.try_reserve(1) {
return Err((elem, e));
}
}
@@ -560,17 +474,19 @@ impl<T> FallibleVec<T> for Vec<T> {
#[inline]
fn try_insert(&mut self, index: usize, element: T) -> Result<(), (T, TryReserveError)> {
if self.len() == self.capacity() {
if let Err(e) = vec_try_reserve_for_growth(self, 1) {
if let Err(e) = self.try_reserve(1) {
return Err((element, e));
}
}
Ok(self.insert(index, element))
}
#[inline]
fn try_append(&mut self, other: &mut Self) -> Result<(), TryReserveError> {
FallibleVec::try_reserve(self, other.len())?;
Ok(self.append(other))
}
fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
where
T: Copy + Clone,
@@ -581,6 +497,7 @@ impl<T> FallibleVec<T> for Vec<T> {
}
Ok(self.resize(new_len, value))
}
fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), TryReserveError>
where
F: FnMut() -> T,
@@ -591,6 +508,7 @@ impl<T> FallibleVec<T> for Vec<T> {
}
Ok(self.resize_with(new_len, f))
}
fn try_resize_no_copy(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
where
T: TryClone,
@@ -600,25 +518,27 @@ impl<T> FallibleVec<T> for Vec<T> {
if new_len > len {
self.try_extend_with(new_len - len, TryExtendElement(value))
} else {
Ok(self.truncate(new_len))
Ok(Truncate::truncate(self, new_len))
}
}
#[inline]
fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError>
where
T: Clone,
{
if needs_to_grow(self, other.len()) {
vec_try_reserve_for_growth(self, other.len())?;
self.try_reserve(other.len())?;
}
Ok(self.extend_from_slice(other))
}
fn try_extend_from_slice_no_copy(&mut self, other: &[T]) -> Result<(), TryReserveError>
where
T: TryClone,
{
if needs_to_grow(self, other.len()) {
vec_try_reserve_for_growth(self, other.len())?;
self.try_reserve(other.len())?;
}
let mut len = self.len();
let mut iterator = other.iter();
@@ -667,7 +587,7 @@ impl<T> TryExtend<T> for Vec<T> {
mut value: E,
) -> Result<(), TryReserveError> {
if needs_to_grow(self, n) {
vec_try_reserve_for_growth(self, n)?;
self.try_reserve(n)?;
}
unsafe {
@@ -824,16 +744,26 @@ mod tests {
#[test]
fn try_clone_oom() {
let layout = Layout::new::<u8>();
let v =
unsafe { Vec::<u8>::from_raw_parts(alloc(layout), core::isize::MAX as usize, core::isize::MAX as usize) };
let v = unsafe {
Vec::<u8>::from_raw_parts(
alloc(layout),
core::isize::MAX as usize,
core::isize::MAX as usize,
)
};
assert!(v.try_clone().is_err());
}
#[test]
fn tryvec_try_clone_oom() {
let layout = Layout::new::<u8>();
let inner =
unsafe { Vec::<u8>::from_raw_parts(alloc(layout), core::isize::MAX as usize, core::isize::MAX as usize) };
let inner = unsafe {
Vec::<u8>::from_raw_parts(
alloc(layout),
core::isize::MAX as usize,
core::isize::MAX as usize,
)
};
let tv = TryVec { inner };
assert!(tv.try_clone().is_err());
}
@@ -951,15 +881,6 @@ mod tests {
assert_eq!(vec, b"foobar".as_ref());
}
#[test]
#[cfg(not(any(feature = "unstable", feature = "rust_1_57")))]
fn try_extend_zst() {
let mut vec: Vec<()> = Vec::new();
assert_eq!(vec.capacity(), core::usize::MAX);
assert!(vec_try_extend(&mut vec, 10).is_ok());
assert!(vec_try_extend(&mut vec, core::usize::MAX).is_ok());
}
#[test]
fn try_reserve_zst() {
let mut vec: Vec<()> = Vec::new();

File diff suppressed because one or more lines are too long

View File

@@ -76,7 +76,7 @@ static_assertions = "1.1.0"
version = "0.3.2"
[dependencies.fallible_collections]
version = "0.4.9"
version = "0.5"
features = ["std_io"]
[dev-dependencies]

View File

@@ -200,7 +200,7 @@ pub enum Status {
ElstBadVersion,
EsdsBadAudioSampleEntry,
EsdsBadDescriptor,
EsdsDecSpecificIntoTagQuantity,
EsdsDecSpecificInfoTagQuantity,
FtypBadSize,
FtypNotFirst,
HdlrNameNoNul,
@@ -514,7 +514,7 @@ impl From<Status> for &str {
Status::EsdsBadDescriptor => {
"Invalid descriptor."
}
Status::EsdsDecSpecificIntoTagQuantity => {
Status::EsdsDecSpecificInfoTagQuantity => {
"There can be only one DecSpecificInfoTag descriptor"
}
Status::FtypBadSize => {
@@ -2417,7 +2417,7 @@ pub fn read_avif<T: Read>(f: &mut T, strictness: ParseStrictness) -> Result<Avif
if image_sequence.is_some() {
return Status::MoovBadQuantity.into();
}
image_sequence = Some(read_moov(&mut b, None)?);
image_sequence = Some(read_moov(&mut b, None, strictness)?);
}
BoxType::MediaDataBox => {
let file_offset = b.offset();
@@ -4058,7 +4058,7 @@ fn read_iloc<T: Read>(src: &mut BMFFBox<T>) -> Result<TryHashMap<ItemId, ItemLoc
}
/// Read the contents of a box, including sub boxes.
pub fn read_mp4<T: Read>(f: &mut T) -> Result<MediaContext> {
pub fn read_mp4<T: Read>(f: &mut T, strictness: ParseStrictness) -> Result<MediaContext> {
let mut context = None;
let mut found_ftyp = false;
// TODO(kinetik): Top-level parsing should handle zero-sized boxes
@@ -4087,7 +4087,7 @@ pub fn read_mp4<T: Read>(f: &mut T) -> Result<MediaContext> {
debug!("{:?}", ftyp);
}
BoxType::MovieBox => {
context = Some(read_moov(&mut b, context)?);
context = Some(read_moov(&mut b, context, strictness)?);
}
#[cfg(feature = "meta-xml")]
BoxType::MetadataBox => {
@@ -4133,7 +4133,11 @@ fn parse_mvhd<T: Read>(f: &mut BMFFBox<T>) -> Result<Option<MediaTimeScale>> {
/// Note that despite the spec indicating "exactly one" moov box should exist at
/// the file container level, we support reading and merging multiple moov boxes
/// such as with tests/test_case_1185230.mp4.
fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: Option<MediaContext>) -> Result<MediaContext> {
fn read_moov<T: Read>(
f: &mut BMFFBox<T>,
context: Option<MediaContext>,
strictness: ParseStrictness,
) -> Result<MediaContext> {
let MediaContext {
mut timescale,
mut tracks,
@@ -4152,7 +4156,7 @@ fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: Option<MediaContext>) -> Resu
}
BoxType::TrackBox => {
let mut track = Track::new(tracks.len());
read_trak(&mut b, &mut track)?;
read_trak(&mut b, &mut track, strictness)?;
tracks.push(track)?;
}
BoxType::MovieExtendsBox => {
@@ -4262,7 +4266,11 @@ fn read_mehd<T: Read>(src: &mut BMFFBox<T>) -> Result<MediaScaledTime> {
/// Parse a Track Box
/// See ISOBMFF (ISO 14496-12:2020) § 8.3.1.
fn read_trak<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
fn read_trak<T: Read>(
f: &mut BMFFBox<T>,
track: &mut Track,
strictness: ParseStrictness,
) -> Result<()> {
let mut iter = f.box_iter();
while let Some(mut b) = iter.next_box()? {
match b.head.name {
@@ -4273,7 +4281,7 @@ fn read_trak<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
debug!("{:?}", tkhd);
}
BoxType::EditBox => read_edts(&mut b, track)?,
BoxType::MediaBox => read_mdia(&mut b, track)?,
BoxType::MediaBox => read_mdia(&mut b, track, strictness)?,
BoxType::TrackReferenceBox => track.tref = Some(read_tref(&mut b)?),
_ => skip_box_content(&mut b)?,
};
@@ -4346,7 +4354,11 @@ fn parse_mdhd<T: Read>(
Ok((mdhd, duration, timescale))
}
fn read_mdia<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
fn read_mdia<T: Read>(
f: &mut BMFFBox<T>,
track: &mut Track,
strictness: ParseStrictness,
) -> Result<()> {
let mut iter = f.box_iter();
while let Some(mut b) = iter.next_box()? {
match b.head.name {
@@ -4369,7 +4381,7 @@ fn read_mdia<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
}
debug!("{:?}", hdlr);
}
BoxType::MediaInformationBox => read_minf(&mut b, track)?,
BoxType::MediaInformationBox => read_minf(&mut b, track, strictness)?,
_ => skip_box_content(&mut b)?,
};
check_parser_state!(b.content);
@@ -4403,11 +4415,15 @@ fn read_tref_auxl<T: Read>(f: &mut BMFFBox<T>) -> Result<TrackReference> {
Ok(TrackReference { track_ids })
}
fn read_minf<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
fn read_minf<T: Read>(
f: &mut BMFFBox<T>,
track: &mut Track,
strictness: ParseStrictness,
) -> Result<()> {
let mut iter = f.box_iter();
while let Some(mut b) = iter.next_box()? {
match b.head.name {
BoxType::SampleTableBox => read_stbl(&mut b, track)?,
BoxType::SampleTableBox => read_stbl(&mut b, track, strictness)?,
_ => skip_box_content(&mut b)?,
};
check_parser_state!(b.content);
@@ -4415,12 +4431,16 @@ fn read_minf<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
Ok(())
}
fn read_stbl<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
fn read_stbl<T: Read>(
f: &mut BMFFBox<T>,
track: &mut Track,
strictness: ParseStrictness,
) -> Result<()> {
let mut iter = f.box_iter();
while let Some(mut b) = iter.next_box()? {
match b.head.name {
BoxType::SampleDescriptionBox => {
let stsd = read_stsd(&mut b, track)?;
let stsd = read_stsd(&mut b, track, strictness)?;
debug!("{:?}", stsd);
track.stsd = Some(stsd);
}
@@ -4455,7 +4475,7 @@ fn read_stbl<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
track.stss = Some(stss);
}
BoxType::CompositionOffsetBox => {
let ctts = read_ctts(&mut b)?;
let ctts = read_ctts(&mut b, strictness)?;
debug!("{:?}", ctts);
track.ctts = Some(ctts);
}
@@ -4727,14 +4747,17 @@ fn read_stsc<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleToChunkBox> {
/// Parse a Composition Time to Sample Box
/// See ISOBMFF (ISO 14496-12:2020) § 8.6.1.3
fn read_ctts<T: Read>(src: &mut BMFFBox<T>) -> Result<CompositionOffsetBox> {
fn read_ctts<T: Read>(
src: &mut BMFFBox<T>,
strictness: ParseStrictness,
) -> Result<CompositionOffsetBox> {
let (version, _) = read_fullbox_extra(src)?;
let counts = be_u32(src)?;
if counts
.checked_mul(8)
.map_or(true, |bytes| u64::from(bytes) > src.bytes_left())
.is_none_or(|bytes| u64::from(bytes) > src.bytes_left())
{
return Status::CttsBadSize.into();
}
@@ -4760,7 +4783,12 @@ fn read_ctts<T: Read>(src: &mut BMFFBox<T>) -> Result<CompositionOffsetBox> {
})?;
}
if strictness == ParseStrictness::Strict {
check_parser_state!(src.content);
} else {
// Padding may be present in some content.
skip_box_remain(src)?;
}
Ok(CompositionOffsetBox { samples: offsets })
}
@@ -4942,7 +4970,11 @@ fn read_flac_metadata<T: Read>(src: &mut BMFFBox<T>) -> Result<FLACMetadataBlock
}
/// See MPEG-4 Systems (ISO 14496-1:2010) § 7.2.6.5
fn find_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
fn find_descriptor(
data: &[u8],
esds: &mut ES_Descriptor,
strictness: ParseStrictness,
) -> Result<()> {
// Tags for elementary stream description
const ESDESCR_TAG: u8 = 0x03;
const DECODER_CONFIG_TAG: u8 = 0x04;
@@ -4982,14 +5014,22 @@ fn find_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
match tag {
ESDESCR_TAG => {
read_es_descriptor(descriptor, esds)?;
read_es_descriptor(descriptor, esds, strictness)?;
}
DECODER_CONFIG_TAG => {
read_dc_descriptor(descriptor, esds)?;
read_dc_descriptor(descriptor, esds, strictness)?;
}
DECODER_SPECIFIC_TAG => {
read_ds_descriptor(descriptor, esds)?;
DECODER_SPECIFIC_TAG => match read_ds_descriptor(descriptor, esds, strictness) {
Ok(()) => {}
Err(Error::InvalidData(Status::BitReaderError))
if strictness != ParseStrictness::Strict =>
{
debug!("Unexpected EOS parsing ds descriptor in non-strict mode");
}
Err(e) => {
return Err(e);
}
},
_ => {
debug!("Unsupported descriptor, tag {}", tag);
}
@@ -5014,7 +5054,11 @@ fn get_audio_object_type(bit_reader: &mut BitReader) -> Result<u16> {
}
/// See MPEG-4 Systems (ISO 14496-1:2010) § 7.2.6.7 and probably 14496-3 somewhere?
fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
fn read_ds_descriptor(
data: &[u8],
esds: &mut ES_Descriptor,
strictness: ParseStrictness,
) -> Result<()> {
#[cfg(feature = "mp4v")]
// Check if we are in a Visual esda Box.
if esds.video_codec != CodecType::Unknown {
@@ -5170,7 +5214,10 @@ fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
esds.audio_sample_rate = Some(sample_frequency_value);
esds.audio_channel_count = Some(channel_counts);
if !esds.decoder_specific_data.is_empty() {
return Status::EsdsDecSpecificIntoTagQuantity.into();
fail_with_status_if(
strictness == ParseStrictness::Strict,
Status::EsdsDecSpecificInfoTagQuantity,
)?;
}
esds.decoder_specific_data.extend_from_slice(data)?;
@@ -5191,7 +5238,11 @@ fn read_surround_channel_count(bit_reader: &mut BitReader, channels: u8) -> Resu
}
/// See MPEG-4 Systems (ISO 14496-1:2010) § 7.2.6.6
fn read_dc_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
fn read_dc_descriptor(
data: &[u8],
esds: &mut ES_Descriptor,
strictness: ParseStrictness,
) -> Result<()> {
let des = &mut Cursor::new(data);
let object_profile = des.read_u8()?;
@@ -5207,7 +5258,11 @@ fn read_dc_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
skip(des, 12)?;
if data.len().to_u64() > des.position() {
find_descriptor(&data[des.position().try_into()?..data.len()], esds)?;
find_descriptor(
&data[des.position().try_into()?..data.len()],
esds,
strictness,
)?;
}
esds.audio_codec = match object_profile {
@@ -5225,7 +5280,11 @@ fn read_dc_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
}
/// See MPEG-4 Systems (ISO 14496-1:2010) § 7.2.6.5
fn read_es_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
fn read_es_descriptor(
data: &[u8],
esds: &mut ES_Descriptor,
strictness: ParseStrictness,
) -> Result<()> {
let des = &mut Cursor::new(data);
skip(des, 2)?;
@@ -5246,20 +5305,24 @@ fn read_es_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
}
if data.len().to_u64() > des.position() {
find_descriptor(&data[des.position().try_into()?..data.len()], esds)?;
find_descriptor(
&data[des.position().try_into()?..data.len()],
esds,
strictness,
)?;
}
Ok(())
}
/// See MP4 (ISO 14496-14:2020) § 6.7.2
fn read_esds<T: Read>(src: &mut BMFFBox<T>) -> Result<ES_Descriptor> {
fn read_esds<T: Read>(src: &mut BMFFBox<T>, strictness: ParseStrictness) -> Result<ES_Descriptor> {
let (_, _) = read_fullbox_extra(src)?;
let esds_array = read_buf(src, src.bytes_left())?;
let mut es_data = ES_Descriptor::default();
find_descriptor(&esds_array, &mut es_data)?;
find_descriptor(&esds_array, &mut es_data, strictness)?;
es_data.codec_esds = esds_array;
@@ -5558,7 +5621,7 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
{
// Read ES_Descriptor inside an esds box.
// See ISOBMFF (ISO 14496-1:2010) § 7.2.6.5
let esds = read_esds(&mut b)?;
let esds = read_esds(&mut b, ParseStrictness::Normal)?;
codec_specific =
Some(VideoCodecSpecific::ESDSConfig(esds.decoder_specific_data));
}
@@ -5621,13 +5684,16 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
)
}
fn read_qt_wave_atom<T: Read>(src: &mut BMFFBox<T>) -> Result<ES_Descriptor> {
fn read_qt_wave_atom<T: Read>(
src: &mut BMFFBox<T>,
strictness: ParseStrictness,
) -> Result<ES_Descriptor> {
let mut codec_specific = None;
let mut iter = src.box_iter();
while let Some(mut b) = iter.next_box()? {
match b.head.name {
BoxType::ESDBox => {
let esds = read_esds(&mut b)?;
let esds = read_esds(&mut b, strictness)?;
codec_specific = Some(esds);
}
_ => skip_box_content(&mut b)?,
@@ -5639,7 +5705,10 @@ fn read_qt_wave_atom<T: Read>(src: &mut BMFFBox<T>) -> Result<ES_Descriptor> {
/// Parse an audio description inside an stsd box.
/// See ISOBMFF (ISO 14496-12:2020) § 12.2.3
fn read_audio_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry> {
fn read_audio_sample_entry<T: Read>(
src: &mut BMFFBox<T>,
strictness: ParseStrictness,
) -> Result<SampleEntry> {
let name = src.get_header().name;
// Skip uninteresting fields.
@@ -5713,7 +5782,7 @@ fn read_audio_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
{
return Status::StsdBadAudioSampleEntry.into();
}
let esds = read_esds(&mut b)?;
let esds = read_esds(&mut b, strictness)?;
codec_type = esds.audio_codec;
codec_specific = Some(AudioCodecSpecific::ES_Descriptor(esds));
}
@@ -5746,7 +5815,7 @@ fn read_audio_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
codec_specific = Some(AudioCodecSpecific::ALACSpecificBox(alac));
}
BoxType::QTWaveAtom => {
let qt_esds = read_qt_wave_atom(&mut b)?;
let qt_esds = read_qt_wave_atom(&mut b, strictness)?;
codec_type = qt_esds.audio_codec;
codec_specific = Some(AudioCodecSpecific::ES_Descriptor(qt_esds));
}
@@ -5799,7 +5868,11 @@ fn read_audio_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
/// Parse a stsd box.
/// See ISOBMFF (ISO 14496-12:2020) § 8.5.2
/// See MP4 (ISO 14496-14:2020) § 6.7.2
fn read_stsd<T: Read>(src: &mut BMFFBox<T>, track: &Track) -> Result<SampleDescriptionBox> {
fn read_stsd<T: Read>(
src: &mut BMFFBox<T>,
track: &Track,
strictness: ParseStrictness,
) -> Result<SampleDescriptionBox> {
let (_, flags) = read_fullbox_extra(src)?;
if flags != 0 {
@@ -5819,7 +5892,7 @@ fn read_stsd<T: Read>(src: &mut BMFFBox<T>, track: &Track) -> Result<SampleDescr
TrackType::Video => read_video_sample_entry(&mut b),
TrackType::Picture => read_video_sample_entry(&mut b),
TrackType::AuxiliaryVideo => read_video_sample_entry(&mut b),
TrackType::Audio => read_audio_sample_entry(&mut b),
TrackType::Audio => read_audio_sample_entry(&mut b, strictness),
TrackType::Metadata => Err(Error::Unsupported("metadata track")),
TrackType::Unknown => Err(Error::Unsupported("unknown track type")),
};

View File

@@ -211,7 +211,7 @@ fn read_truncated_ftyp() {
.B32(0) // minor version
.append_bytes(b"isom")
});
match read_mp4(&mut stream) {
match read_mp4(&mut stream, ParseStrictness::Normal) {
Err(Error::UnexpectedEOF) => (),
Ok(_) => panic!("expected an error result"),
_ => panic!("expected a different error result"),
@@ -649,7 +649,7 @@ fn read_flac() {
});
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let r = super::read_audio_sample_entry(&mut stream);
let r = super::read_audio_sample_entry(&mut stream, ParseStrictness::Normal);
assert!(r.is_ok());
}
@@ -740,7 +740,7 @@ fn read_opus() {
});
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let r = super::read_audio_sample_entry(&mut stream);
let r = super::read_audio_sample_entry(&mut stream, ParseStrictness::Normal);
assert!(r.is_ok());
}
@@ -830,7 +830,7 @@ fn read_alac() {
});
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let r = super::read_audio_sample_entry(&mut stream);
let r = super::read_audio_sample_entry(&mut stream, ParseStrictness::Normal);
assert!(r.is_ok());
}
@@ -852,7 +852,7 @@ fn esds_limit() {
});
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
match super::read_audio_sample_entry(&mut stream) {
match super::read_audio_sample_entry(&mut stream, ParseStrictness::Normal) {
Err(Error::UnexpectedEOF) => (),
Ok(_) => panic!("expected an error result"),
_ => panic!("expected a different error result"),
@@ -963,7 +963,8 @@ fn skip_padding_in_stsd() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
super::read_stsd(&mut stream, &super::Track::new(0)).expect("fail to skip padding: stsd");
super::read_stsd(&mut stream, &super::Track::new(0), ParseStrictness::Normal)
.expect("fail to skip padding: stsd");
}
#[test]
@@ -1000,8 +1001,8 @@ fn read_qt_wave_atom() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let sample_entry =
super::read_audio_sample_entry(&mut stream).expect("fail to read qt wave atom");
let sample_entry = super::read_audio_sample_entry(&mut stream, ParseStrictness::Normal)
.expect("fail to read qt wave atom");
match sample_entry {
super::SampleEntry::Audio(sample_entry) => {
assert_eq!(sample_entry.codec_type, super::CodecType::MP3)
@@ -1025,7 +1026,7 @@ fn read_descriptor_80() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let es = super::read_esds(&mut stream).unwrap();
let es = super::read_esds(&mut stream, ParseStrictness::Normal).unwrap();
assert_eq!(es.audio_codec, super::CodecType::AAC);
assert_eq!(es.audio_object_type, Some(2));
@@ -1052,7 +1053,7 @@ fn read_esds() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let es = super::read_esds(&mut stream).unwrap();
let es = super::read_esds(&mut stream, ParseStrictness::Normal).unwrap();
assert_eq!(es.audio_codec, super::CodecType::AAC);
assert_eq!(es.audio_object_type, Some(2));
@@ -1081,7 +1082,7 @@ fn read_esds_aac_type5() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let es = super::read_esds(&mut stream).unwrap();
let es = super::read_esds(&mut stream, ParseStrictness::Normal).unwrap();
assert_eq!(es.audio_codec, super::CodecType::AAC);
assert_eq!(es.audio_object_type, Some(2));
@@ -1110,7 +1111,7 @@ fn read_esds_mpeg2_aac_lc() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let es = super::read_esds(&mut stream).unwrap();
let es = super::read_esds(&mut stream, ParseStrictness::Normal).unwrap();
assert_eq!(es.audio_codec, super::CodecType::AAC);
assert_eq!(es.audio_object_type, Some(2));
@@ -1179,7 +1180,7 @@ fn read_esds_one_byte_extension_descriptor() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let es = super::read_esds(&mut stream).unwrap();
let es = super::read_esds(&mut stream, ParseStrictness::Normal).unwrap();
assert_eq!(es.audio_codec, super::CodecType::AAC);
assert_eq!(es.audio_object_type, Some(2));
@@ -1199,7 +1200,7 @@ fn read_esds_byte_extension_descriptor() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
match super::read_esds(&mut stream) {
match super::read_esds(&mut stream, ParseStrictness::Normal) {
Ok(_) => (),
_ => panic!("fail to parse descriptor extension byte length"),
}
@@ -1220,8 +1221,8 @@ fn read_f4v_stsd() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let sample_entry =
super::read_audio_sample_entry(&mut stream).expect("failed to read f4v stsd atom");
let sample_entry = super::read_audio_sample_entry(&mut stream, ParseStrictness::Normal)
.expect("failed to read f4v stsd atom");
match sample_entry {
super::SampleEntry::Audio(sample_entry) => {
assert_eq!(sample_entry.codec_type, super::CodecType::MP3)
@@ -1269,7 +1270,7 @@ fn unknown_audio_sample_entry() {
});
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
match super::read_audio_sample_entry(&mut stream) {
match super::read_audio_sample_entry(&mut stream, ParseStrictness::Normal) {
Ok(super::SampleEntry::Unknown) => (),
_ => panic!("expected a different error result"),
}
@@ -1291,7 +1292,7 @@ fn read_esds_invalid_descriptor() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
match super::read_esds(&mut stream) {
match super::read_esds(&mut stream, ParseStrictness::Normal) {
Err(Error::InvalidData(s)) => assert_eq!(s, Status::EsdsBadDescriptor),
_ => panic!("unexpected result with invalid descriptor"),
}
@@ -1311,12 +1312,36 @@ fn read_esds_redundant_descriptor() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
match super::read_esds(&mut stream) {
match super::read_esds(&mut stream, ParseStrictness::Normal) {
Ok(esds) => assert_eq!(esds.audio_codec, super::CodecType::AAC),
_ => panic!("unexpected result with invalid descriptor"),
}
}
#[test]
fn read_esds_multiple_descriptors() {
// Permit multiple descriptors in non-strict mode.
// Extracted from BMO #1936124 using Bento4.
// "mp4extract --payload-only moov/trak[0]/mdia/minf/stbl/stsd/mp4a/esds bug1936124.mp4 /dev/stdout | xxd -i -c 15"
let esds = vec![
0x03, 0x1d, 0x00, 0x00, 0x00, 0x04, 0x15, 0x40, 0x15, 0x00, 0x06, 0x00, 0x00, 0x01, 0x77,
0x00, 0x00, 0x01, 0x77, 0x00, 0x05, 0x02, 0x11, 0x90, 0x05, 0x02, 0x11, 0x90, 0x06, 0x01,
0x02,
];
let mut stream = make_box(BoxSize::Auto, b"esds", |s| {
s.B32(0) // reserved
.append_bytes(esds.as_slice())
});
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
match super::read_esds(&mut stream, ParseStrictness::Normal) {
Ok(esds) => assert_eq!(esds.audio_codec, super::CodecType::AAC),
_ => panic!("unexpected result with multiple descriptors"),
}
}
#[test]
fn read_stsd_lpcm() {
// Extract from sample converted by ffmpeg.
@@ -1334,7 +1359,8 @@ fn read_stsd_lpcm() {
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();
let sample_entry = super::read_audio_sample_entry(&mut stream).unwrap();
let sample_entry =
super::read_audio_sample_entry(&mut stream, ParseStrictness::Normal).unwrap();
match sample_entry {
#[allow(clippy::float_cmp)] // The float comparison below is valid and intended.

View File

@@ -243,7 +243,7 @@ fn public_api() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
assert_eq!(context.timescale, Some(mp4::MediaTimeScale(1000)));
for track in context.tracks {
match track.track_type {
@@ -373,7 +373,7 @@ fn public_metadata() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
let udta = context
.userdata
.expect("didn't find udta")
@@ -439,7 +439,7 @@ fn public_metadata_gnre() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
let udta = context
.userdata
.expect("didn't find udta")
@@ -504,7 +504,7 @@ fn public_invalid_metadata() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
// Should have userdata.
assert!(context.userdata.is_some());
// But it should contain an error.
@@ -547,7 +547,7 @@ fn public_audio_tenc() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
let stsd = track.stsd.expect("expected an stsd");
let a = match stsd.descriptions.first().expect("expected a SampleEntry") {
@@ -605,7 +605,7 @@ fn public_video_cenc() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
let stsd = track.stsd.expect("expected an stsd");
let v = match stsd.descriptions.first().expect("expected a SampleEntry") {
@@ -677,7 +677,7 @@ fn public_audio_cbcs() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
let stsd = track.stsd.expect("expected an stsd");
assert_eq!(stsd.descriptions.len(), 2);
@@ -758,7 +758,7 @@ fn public_video_cbcs() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
let stsd = track.stsd.expect("expected an stsd");
assert_eq!(stsd.descriptions.len(), 2);
@@ -816,7 +816,7 @@ fn public_video_av1() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
// track part
assert_eq!(track.duration, Some(mp4::TrackScaledTime(512, 0)));
@@ -863,7 +863,7 @@ fn public_video_av1() {
#[test]
fn public_mp4_bug_1185230() {
let input = &mut File::open("tests/test_case_1185230.mp4").expect("Unknown file");
let context = mp4::read_mp4(input).expect("read_mp4 failed");
let context = mp4::read_mp4(input, ParseStrictness::Normal).expect("read_mp4 failed");
let number_video_tracks = context
.tracks
.iter()
@@ -882,7 +882,10 @@ fn public_mp4_bug_1185230() {
fn public_mp4_ctts_overflow() {
let input = &mut File::open("tests/clusterfuzz-testcase-minimized-mp4-6093954524250112")
.expect("Unknown file");
assert_eq!(Status::from(mp4::read_mp4(input)), Status::CttsBadSize);
assert_eq!(
Status::from(mp4::read_mp4(input, ParseStrictness::Normal)),
Status::CttsBadSize
);
}
#[test]
@@ -1427,7 +1430,7 @@ fn public_video_h263() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
let stsd = track.stsd.expect("expected an stsd");
let v = match stsd.descriptions.first().expect("expected a SampleEntry") {
@@ -1453,7 +1456,7 @@ fn public_video_hevc() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
let stsd = track.stsd.expect("expected an stsd");
let v = match stsd.descriptions.first().expect("expected a SampleEntry") {
@@ -1479,7 +1482,7 @@ fn public_parse_pasp_h264() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
let stsd = track.stsd.expect("expected an stsd");
let v = match stsd.descriptions.first().expect("expected a SampleEntry") {
@@ -1509,7 +1512,7 @@ fn public_audio_amrnb() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
let stsd = track.stsd.expect("expected an stsd");
let a = match stsd.descriptions.first().expect("expected a SampleEntry") {
@@ -1534,7 +1537,7 @@ fn public_audio_amrwb() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
let stsd = track.stsd.expect("expected an stsd");
let a = match stsd.descriptions.first().expect("expected a SampleEntry") {
@@ -1559,7 +1562,7 @@ fn public_video_mp4v() {
fd.read_to_end(&mut buf).expect("File error");
let mut c = Cursor::new(&buf);
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
let context = mp4::read_mp4(&mut c, ParseStrictness::Normal).expect("read_mp4 failed");
for track in context.tracks {
let stsd = track.stsd.expect("expected an stsd");
let v = match stsd.descriptions.first().expect("expected a SampleEntry") {

View File

@@ -1 +1 @@
{"files":{"Cargo.toml":"40db3f983f6b385791f7bb869290919b924f97af77860f81c09ed67c826b4b17","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"f776ed4bbb7b58a5684402a9c5c28dfe1fa02b6b184139b2c2c49384cc1e3723","cbindgen.toml":"62066cd34285ab9e7f1cc5db8950a51e9e080f5a85bd55ad43d7022e4eae2758","examples/dump.rs":"aef3a73e9f5e8dc125e449f7dc7eb8a8c6cfa0edf5f99114d4b90c52e0903613","src/lib.rs":"4f8048452328adeb23e6bfb656e2305b64ed3b3cef30c68509acf1635953212b","tests/test_avis.rs":"f01df914abcb18b562e74c39e15a0fa53159dbe93e9bd8698fab30d792e74645","tests/test_chunk_out_of_range.rs":"4039d0db0ee5973787e4ca14cea510fd958ae5d21856a79240a5e7b826caa18d","tests/test_encryption.rs":"f62131a36b0516caf9e2c48f8aea060d300b0f5c8a32bc54d31cbc97aa25b4e6","tests/test_fragment.rs":"d3f805cc2107481ee9a989818af3addbb3ea1faf7422ea7f4416591d03031318","tests/test_rotation.rs":"23fa4898eca2e17255bc1ba2f538707a6554fb4644bb75f80548ae56a7cd2d44","tests/test_sample_table.rs":"6a0095c155a3618b2338d7252101ff16adaa020f511abdac410548b417aee11b","tests/test_workaround_stsc.rs":"1d17a394f55e1524c30888bfe1e57e2b0457444b79c23eb91b02d2edf859c9ad"},"package":null}
{"files":{"Cargo.toml":"e8990ea5795527d3c8cbb46bdc63d36d48451601de3bd87a42dd49b28d7b96d8","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"f776ed4bbb7b58a5684402a9c5c28dfe1fa02b6b184139b2c2c49384cc1e3723","cbindgen.toml":"62066cd34285ab9e7f1cc5db8950a51e9e080f5a85bd55ad43d7022e4eae2758","examples/dump.rs":"aef3a73e9f5e8dc125e449f7dc7eb8a8c6cfa0edf5f99114d4b90c52e0903613","src/lib.rs":"be450bdfe41d259a3f8b48663173ab1d852c66836bdd63af9f3932c925a41a53","tests/test_avis.rs":"f01df914abcb18b562e74c39e15a0fa53159dbe93e9bd8698fab30d792e74645","tests/test_chunk_out_of_range.rs":"4039d0db0ee5973787e4ca14cea510fd958ae5d21856a79240a5e7b826caa18d","tests/test_encryption.rs":"f62131a36b0516caf9e2c48f8aea060d300b0f5c8a32bc54d31cbc97aa25b4e6","tests/test_fragment.rs":"d3f805cc2107481ee9a989818af3addbb3ea1faf7422ea7f4416591d03031318","tests/test_rotation.rs":"23fa4898eca2e17255bc1ba2f538707a6554fb4644bb75f80548ae56a7cd2d44","tests/test_sample_table.rs":"6a0095c155a3618b2338d7252101ff16adaa020f511abdac410548b417aee11b","tests/test_workaround_stsc.rs":"1d17a394f55e1524c30888bfe1e57e2b0457444b79c23eb91b02d2edf859c9ad"},"package":null}

View File

@@ -87,7 +87,7 @@ log = "0.4"
num-traits = "0.2.14"
[dependencies.fallible_collections]
version = "0.4.9"
version = "0.5"
features = ["std_io"]
[dependencies.mp4parse]

View File

@@ -391,8 +391,8 @@ impl ContextParser for Mp4parseParser {
}
}
fn read<T: Read>(io: &mut T, _strictness: ParseStrictness) -> mp4parse::Result<Self::Context> {
let r = mp4parse::read_mp4(io);
fn read<T: Read>(io: &mut T, strictness: ParseStrictness) -> mp4parse::Result<Self::Context> {
let r = mp4parse::read_mp4(io, strictness);
log::debug!("mp4parse::read_mp4 -> {:?}", r);
r
}
@@ -442,8 +442,7 @@ pub struct Mp4parseIo {
impl Read for Mp4parseIo {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if buf.len() > isize::MAX as usize {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
return Err(std::io::Error::other(
"buf length overflow in Mp4parseIo Read impl",
));
}
@@ -451,10 +450,7 @@ impl Read for Mp4parseIo {
if rv >= 0 {
Ok(rv as usize)
} else {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"I/O error in Mp4parseIo Read impl",
))
Err(std::io::Error::other("I/O error in Mp4parseIo Read impl"))
}
}
}

View File

@@ -13,7 +13,7 @@ mozglue-static = { path = "../../../../mozglue/static/rust" }
geckoservo = { path = "../../../../servo/ports/geckolib" }
kvstore = { path = "../../../components/kvstore" }
lmdb-rkv-sys = { version = "0.11", features = ["mdb_idl_logn_9"] }
mp4parse_capi = { git = "https://github.com/mozilla/mp4parse-rust", rev = "e64650a686e5c5732395cd059e17cfd3b1e5b63b", features = ["missing-pixi-permitted"] }
mp4parse_capi = { git = "https://github.com/mozilla/mp4parse-rust", rev = "d3e4d255bd149d341c7e90f5e9fc84e743a8e179", features = ["missing-pixi-permitted"] }
nserror = { path = "../../../../xpcom/rust/nserror" }
nsstring = { path = "../../../../xpcom/rust/nsstring" }
netwerk_helper = { path = "../../../../netwerk/base/rust-helper" }
@@ -107,9 +107,6 @@ etagere = { version = "0.2.13", features = ["ffi"] }
url = "2.5.0"
# Since we're building with at least rustc 1.63, enable rust 1.57 features (use of try_reserve methods).
fallible_collections = { version = "0.4", features = ["rust_1_57"] }
libz-rs-sys = { version = "0.4.1", features = ["custom-prefix"], optional = true }
[target.'cfg(any(target_os = "android", target_os = "macos", target_os = "ios", all(target_os = "windows", not(target_arch = "aarch64"))))'.dependencies]