Bug 1448762 - Update mp4parse-rust to 9e70cb4. r?padenot draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 09 Apr 2018 09:59:57 +0200
changeset 779125 f948b7a3d62508510df47ee2a7df5f17b07e5b2f
parent 779089 b4bc6b2401738b78fd47127a4c716bb9178e1a09
child 779134 1d0c2eba8d624b5b2cbed3167fe5812f63bc315b
push id105664
push userbmo:jyavenard@mozilla.com
push dateMon, 09 Apr 2018 08:00:25 +0000
reviewerspadenot
bugs1448762
milestone61.0a1
Bug 1448762 - Update mp4parse-rust to 9e70cb4. r?padenot MozReview-Commit-ID: 2RuByCeEEe5
Cargo.lock
media/mp4parse-rust/mp4parse-cargo.patch
media/mp4parse-rust/mp4parse/Cargo.toml
media/mp4parse-rust/mp4parse/src/lib.rs
media/mp4parse-rust/mp4parse/src/tests.rs
media/mp4parse-rust/mp4parse/tests/overflow.rs
media/mp4parse-rust/mp4parse_capi/Cargo.toml
media/mp4parse-rust/mp4parse_capi/src/lib.rs
media/mp4parse-rust/update-rust.sh
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -825,17 +825,17 @@ dependencies = [
  "audioipc-server 0.2.2",
  "cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "cubeb-pulse 0.2.0",
  "cubeb-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding_glue 0.1.0",
  "geckoservo 0.0.1",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "mp4parse_capi 0.10.0",
+ "mp4parse_capi 0.10.1",
  "netwerk_helper 0.0.1",
  "nserror 0.1.0",
  "nsstring 0.1.0",
  "prefs_parser 0.0.1",
  "rsdparsa_capi 0.1.0",
  "rust_url_capi 0.0.1",
  "u2fhid 0.1.0",
  "webrender_bindings 0.1.0",
@@ -1269,36 +1269,36 @@ version = "0.1.3"
 dependencies = [
  "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rust-ini 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mp4parse"
-version = "0.10.0"
+version = "0.10.1"
 dependencies = [
  "bitreader 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "mp4parse_fallible 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mp4parse-gtest"
 version = "0.1.0"
 
 [[package]]
 name = "mp4parse_capi"
-version = "0.10.0"
+version = "0.10.1"
 dependencies = [
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "mp4parse 0.10.0",
+ "mp4parse 0.10.1",
  "num-traits 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mp4parse_fallible"
 version = "0.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
--- a/media/mp4parse-rust/mp4parse-cargo.patch
+++ b/media/mp4parse-rust/mp4parse-cargo.patch
@@ -37,18 +37,18 @@ index a30e045..a965f06 100644
 +build = false
  
  [dependencies]
  byteorder = "1.2.1"
  log = "0.4"
  
  # To enable fallible memory allocation, add 'features = ["mp4parse_fallible"]'
  # in mp4parse brace.
--mp4parse = {version = "0.10.0", path = "../mp4parse"}
-+mp4parse = {version = "0.10.0", path = "../mp4parse", features = ["mp4parse_fallible"]}
+-mp4parse = {version = "0.10.1", path = "../mp4parse"}
++mp4parse = {version = "0.10.1", path = "../mp4parse", features = ["mp4parse_fallible"]}
  num-traits = "0.2.0"
  
  [dev-dependencies]
  env_logger = "0.5.3"
 -
 -[build-dependencies]
 -cbindgen = "0.5.2"
 -
--- a/media/mp4parse-rust/mp4parse/Cargo.toml
+++ b/media/mp4parse-rust/mp4parse/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "mp4parse"
-version = "0.10.0"
+version = "0.10.1"
 authors = [
   "Ralph Giles <giles@mozilla.com>",
   "Matthew Gregan <kinetik@flim.org>",
   "Alfredo Yang <ayang@mozilla.com>",
 ]
 
 description = "Parser for ISO base media file format (mp4)"
 documentation = "https://docs.rs/mp4parse/"
--- a/media/mp4parse-rust/mp4parse/src/lib.rs
+++ b/media/mp4parse-rust/mp4parse/src/lib.rs
@@ -1372,16 +1372,22 @@ fn find_descriptor(data: &[u8], esds: &m
     // Descriptor length should be more than 2 bytes.
     while remains.len() > 2 {
         let des = &mut Cursor::new(remains);
         let tag = des.read_u8()?;
 
         let mut end: u32 = 0;   // It's u8 without declaration type that is incorrect.
         // MSB of extend_or_len indicates more bytes, up to 4 bytes.
         for _ in 0..4 {
+            if (des.position() as usize) == remains.len() {
+                // There's nothing more to read, the 0x80 was actually part of
+                // the content, and not an extension size.
+                end = des.position() as u32;
+                break;
+            }
             let extend_or_len = des.read_u8()?;
             end = (end << 7) + (extend_or_len & 0x7F) as u32;
             if (extend_or_len & 0x80) == 0 {
                 end += des.position() as u32;
                 break;
             }
         };
 
--- a/media/mp4parse-rust/mp4parse/src/tests.rs
+++ b/media/mp4parse-rust/mp4parse/src/tests.rs
@@ -893,16 +893,44 @@ fn read_qt_wave_atom() {
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     let (codec_type, _) = super::read_audio_sample_entry(&mut stream)
           .expect("fail to read qt wave atom");
     assert_eq!(codec_type, super::CodecType::MP3);
 }
 
 #[test]
+fn read_descriptor_80() {
+    let aac_esds =
+        vec![
+            0x03, 0x80, 0x80, 0x80, 0x22, 0x00, 0x02, 0x00,
+            0x04, 0x80, 0x80, 0x80, 0x17, 0x40, 0x15, 0x00,
+            0x00, 0x00, 0x00, 0x03, 0x22, 0xBC, 0x00, 0x01,
+            0xF5, 0x83, 0x05, 0x80, 0x80, 0x80, 0x02, 0x11,
+            0x90, 0x06, 0x80, 0x80, 0x80, 0x01, 0x02
+        ];
+    let aac_dc_descriptor = &aac_esds[31 .. 33];
+    let mut stream = make_box(BoxSize::Auto, b"esds", |s| {
+        s.B32(0) // reserved
+         .append_bytes(aac_esds.as_slice())
+    });
+    let mut iter = super::BoxIter::new(&mut stream);
+    let mut stream = iter.next_box().unwrap().unwrap();
+
+    let es = super::read_esds(&mut stream).unwrap();
+
+    assert_eq!(es.audio_codec, super::CodecType::AAC);
+    assert_eq!(es.audio_object_type, Some(2));
+    assert_eq!(es.audio_sample_rate, Some(48000));
+    assert_eq!(es.audio_channel_count, Some(2));
+    assert_eq!(es.codec_esds, aac_esds);
+    assert_eq!(es.decoder_specific_data, aac_dc_descriptor);
+}
+
+#[test]
 fn read_esds() {
     let aac_esds =
         vec![
             0x03, 0x24, 0x00, 0x00, 0x00, 0x04, 0x1c, 0x40,
             0x15, 0x00, 0x12, 0x00, 0x00, 0x01, 0xf4, 0x00,
             0x00, 0x01, 0xf4, 0x00, 0x05, 0x0d, 0x13, 0x00,
             0x05, 0x88, 0x05, 0x00, 0x48, 0x21, 0x10, 0x00,
             0x56, 0xe5, 0x98, 0x06, 0x01, 0x02,
new file mode 100644
--- /dev/null
+++ b/media/mp4parse-rust/mp4parse/tests/overflow.rs
@@ -0,0 +1,15 @@
+/// Verify we're built with run-time integer overflow detection.
+
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#[test]
+#[should_panic(expected = "attempt to add with overflow")]
+fn overflow_protection() {
+    let edge = u32::max_value();
+    assert_eq!(0u32, edge + 1);
+
+    let edge = u64::max_value();
+    assert_eq!(0u64, edge + 1);
+}
--- a/media/mp4parse-rust/mp4parse_capi/Cargo.toml
+++ b/media/mp4parse-rust/mp4parse_capi/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "mp4parse_capi"
-version = "0.10.0"
+version = "0.10.1"
 authors = [
   "Ralph Giles <giles@mozilla.com>",
   "Matthew Gregan <kinetik@flim.org>",
   "Alfredo Yang <ayang@mozilla.com>",
 ]
 
 description = "Parser for ISO base media file format (mp4)"
 documentation = "https://docs.rs/mp4parse_capi/"
@@ -21,13 +21,13 @@ exclude = [
 build = false
 
 [dependencies]
 byteorder = "1.2.1"
 log = "0.4"
 
 # To enable fallible memory allocation, add 'features = ["mp4parse_fallible"]'
 # in mp4parse brace.
-mp4parse = {version = "0.10.0", path = "../mp4parse", features = ["mp4parse_fallible"]}
+mp4parse = {version = "0.10.1", path = "../mp4parse", features = ["mp4parse_fallible"]}
 num-traits = "0.2.0"
 
 [dev-dependencies]
 env_logger = "0.5.3"
--- a/media/mp4parse-rust/mp4parse_capi/src/lib.rs
+++ b/media/mp4parse-rust/mp4parse_capi/src/lib.rs
@@ -821,43 +821,55 @@ struct SampleToChunkIterator<'a> {
 }
 
 impl<'a> Iterator for SampleToChunkIterator<'a> {
     type Item = (u32, u32);
 
     fn next(&mut self) -> Option<(u32, u32)> {
         let has_chunk = self.chunks.next()
             .or_else(|| {
-                self.chunks = match (self.stsc_peek_iter.next(), self.stsc_peek_iter.peek()) {
-                    (Some(next), Some(peek)) if next.first_chunk > 0 && peek.first_chunk > 0 => {
-                        self.sample_count = next.samples_per_chunk;
-                        ((next.first_chunk - 1) .. (peek.first_chunk - 1))
-                    },
-                    (Some(next), None) if next.first_chunk > 0 => {
-                        self.sample_count = next.samples_per_chunk;
-                        // Total chunk number in 'stsc' could be different to 'stco',
-                        // there could be more chunks at the last 'stsc' record.
-                        match next.first_chunk.checked_add(self.remain_chunk_count) {
-                            Some(r) => ((next.first_chunk - 1) .. r - 1),
-                            _ => (0 .. 0),
-                        }
-                    },
-                    _ => (0 .. 0),
-                };
-
+                self.chunks = self.locate();
                 self.remain_chunk_count.checked_sub(self.chunks.len() as u32).and_then(|res| {
                     self.remain_chunk_count = res;
                     self.chunks.next()
                 })
             });
 
         has_chunk.map_or(None, |id| { Some((id, self.sample_count)) })
     }
 }
 
+impl<'a> SampleToChunkIterator<'a> {
+    fn locate(&mut self) -> std::ops::Range<u32> {
+        loop {
+            return match (self.stsc_peek_iter.next(), self.stsc_peek_iter.peek()) {
+                (Some(next), Some(peek)) if next.first_chunk == peek.first_chunk => {
+                    // Invalid entry, skip it and will continue searching at
+                    // next loop iteration.
+                    continue
+                },
+                (Some(next), Some(peek)) if next.first_chunk > 0 && peek.first_chunk > 0 => {
+                    self.sample_count = next.samples_per_chunk;
+                    (next.first_chunk - 1) .. (peek.first_chunk - 1)
+                },
+                (Some(next), None) if next.first_chunk > 0 => {
+                    self.sample_count = next.samples_per_chunk;
+                    // Total chunk number in 'stsc' could be different to 'stco',
+                    // there could be more chunks at the last 'stsc' record.
+                    match next.first_chunk.checked_add(self.remain_chunk_count) {
+                        Some(r) => (next.first_chunk - 1) .. r - 1,
+                        _ => 0 .. 0,
+                    }
+                },
+                _ => 0 .. 0
+            };
+        };
+    }
+}
+
 fn create_sample_table(track: &Track, track_offset_time: i64) -> Option<Vec<Mp4parseIndice>> {
     let timescale = match track.timescale {
         Some(ref t) => TrackTimeScale::<i64>(t.0 as i64, t.1),
         _ => TrackTimeScale::<i64>(0, 0),
     };
 
     let (stsc, stco, stsz, stts) =
         match (&track.stsc, &track.stco, &track.stsz, &track.stts) {
--- a/media/mp4parse-rust/update-rust.sh
+++ b/media/mp4parse-rust/update-rust.sh
@@ -1,13 +1,13 @@
 #!/bin/sh -e
 # Script to update mp4parse-rust sources to latest upstream
 
 # Default version.
-VER="ded91a1661daaf55515e572aadd8e92e6d71cbaf"
+VER="9e70cb418401c152cd3183aab06b084c0ce3f3e6"
 
 # Accept version or commit from the command line.
 if test -n "$1"; then
   VER=$1
 fi
 
 echo "Fetching sources..."
 rm -rf _upstream