From c4cc7023b14a64a8aa2b889063e4d19768301f35 Mon Sep 17 00:00:00 2001 From: Jessa Date: Sun, 8 Jan 2023 13:59:07 -0800 Subject: [PATCH 1/2] don't subtract overflow when 64-bit box size is less than 8 --- src/mp4box/mod.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/mp4box/mod.rs b/src/mp4box/mod.rs index 890b694..556eeea 100644 --- a/src/mp4box/mod.rs +++ b/src/mp4box/mod.rs @@ -245,7 +245,9 @@ impl BoxHeader { Ok(BoxHeader { name: BoxType::from(typ), - size: largesize - HEADER_SIZE, + size: largesize + .checked_sub(HEADER_SIZE) + .ok_or(Error::InvalidData("64-bit box size too small"))?, }) } else { Ok(BoxHeader { @@ -356,4 +358,22 @@ mod tests { let ftyp_fcc2: u32 = ftyp_value.into(); assert_eq!(ftyp_fcc, ftyp_fcc2); } + + #[test] + fn test_largesize_too_small() { + let error = BoxHeader::read(&mut &[0, 0, 0, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 7][..]); + assert!(matches!(error, Err(Error::InvalidData(_)))); + } + + #[test] + fn test_zero_largesize() { + let header = BoxHeader::read(&mut &[0, 0, 0, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 8][..]); + assert!(matches!(header, Ok(BoxHeader { size: 0, .. }))); + } + + #[test] + fn test_nonzero_largesize() { + let header = BoxHeader::read(&mut &[0, 0, 0, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 9][..]); + assert!(matches!(header, Ok(BoxHeader { size: 1, .. }))); + } } From 76987c978a61f79ac1e5c629ddd461b52e23856c Mon Sep 17 00:00:00 2001 From: Jessa Date: Sun, 8 Jan 2023 14:48:19 -0800 Subject: [PATCH 2/2] fix largesize of 8 being conflated with a size of 0 --- src/mp4box/mod.rs | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/mp4box/mod.rs b/src/mp4box/mod.rs index 556eeea..da4485d 100644 --- a/src/mp4box/mod.rs +++ b/src/mp4box/mod.rs @@ -245,9 +245,15 @@ impl BoxHeader { Ok(BoxHeader { name: BoxType::from(typ), - size: largesize - .checked_sub(HEADER_SIZE) - .ok_or(Error::InvalidData("64-bit box size too small"))?, + + // Subtract the length of the serialized largesize, as callers assume `size - HEADER_SIZE` is the length + // of the box data. Disallow `largesize < 16`, or else a largesize of 8 will result in a BoxHeader::size + // of 0, incorrectly indicating that the box data extends to the end of the stream. + size: match largesize { + 0 => 0, + 1..=15 => return Err(Error::InvalidData("64-bit box size too small")), + 16..=u64::MAX => largesize - 8, + }, }) } else { Ok(BoxHeader { @@ -367,13 +373,19 @@ mod tests { #[test] fn test_zero_largesize() { - let header = BoxHeader::read(&mut &[0, 0, 0, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 8][..]); - assert!(matches!(header, Ok(BoxHeader { size: 0, .. }))); + let error = BoxHeader::read(&mut &[0, 0, 0, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 8][..]); + assert!(matches!(error, Err(Error::InvalidData(_)))); + } + + #[test] + fn test_nonzero_largesize_too_small() { + let error = BoxHeader::read(&mut &[0, 0, 0, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 15][..]); + assert!(matches!(error, Err(Error::InvalidData(_)))); } #[test] - fn test_nonzero_largesize() { - let header = BoxHeader::read(&mut &[0, 0, 0, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 9][..]); - assert!(matches!(header, Ok(BoxHeader { size: 1, .. }))); + fn test_valid_largesize() { + let header = BoxHeader::read(&mut &[0, 0, 0, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 16][..]); + assert!(matches!(header, Ok(BoxHeader { size: 8, .. }))); } }