Bug 1487416 - Read pattern information in Sinf parser. r=jya
authorBryce Van Dyk <bvandyk@mozilla.com>
Fri, 11 Jan 2019 15:11:05 +0000
changeset 453493 9edd4ab366410d8a6b4a3a9c5c47b630bac08e73
parent 453492 e4cbf560928e09c1d7003e5375a5601eabb79c61
child 453494 9922ca87970ee8a50151780cc96d9403e30bce2c
push id35357
push usernerli@mozilla.com
push dateFri, 11 Jan 2019 21:54:07 +0000
treeherdermozilla-central@0ce024c91511 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1487416
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1487416 - Read pattern information in Sinf parser. r=jya Differential Revision: https://phabricator.services.mozilla.com/D15873
dom/media/mp4/SinfParser.cpp
dom/media/mp4/SinfParser.h
--- a/dom/media/mp4/SinfParser.cpp
+++ b/dom/media/mp4/SinfParser.cpp
@@ -50,18 +50,46 @@ Result<Ok, nsresult> SinfParser::ParseSc
 
 Result<Ok, nsresult> SinfParser::ParseTenc(Box& aBox) {
   BoxReader reader(aBox);
 
   if (reader->Remaining() < 24) {
     return Err(NS_ERROR_FAILURE);
   }
 
-  MOZ_TRY(reader->ReadU32());  // flags -- ignore
+  uint32_t flags;
+  MOZ_TRY_VAR(flags, reader->ReadU32());
+  uint8_t version = flags >> 24;
 
-  uint32_t isEncrypted;
-  MOZ_TRY_VAR(isEncrypted, reader->ReadU24());
+  // Skip reserved byte
+  MOZ_TRY(reader->ReadU8());
+  if (version >= 1) {
+    uint8_t pattern;
+    MOZ_TRY_VAR(pattern, reader->ReadU8());
+    mSinf.mDefaultCryptByteBlock = pattern >> 4;
+    mSinf.mDefaultSkipByteBlock = pattern & 0x0f;
+  } else {
+    // Reserved if version is less than 1
+    MOZ_TRY(reader->ReadU8());
+    mSinf.mDefaultCryptByteBlock = 0;
+    mSinf.mDefaultSkipByteBlock = 0;
+  }
+
+  uint8_t isEncrypted;
+  MOZ_TRY_VAR(isEncrypted, reader->ReadU8());
   MOZ_TRY_VAR(mSinf.mDefaultIVSize, reader->ReadU8());
   memcpy(mSinf.mDefaultKeyID, reader->Read(16), 16);
+
+  if (isEncrypted && mSinf.mDefaultIVSize == 0) {
+    uint8_t defaultConstantIVSize;
+    MOZ_TRY_VAR(defaultConstantIVSize, reader->ReadU8());
+    if (!mSinf.mDefaultConstantIV.SetLength(defaultConstantIVSize,
+                                            mozilla::fallible)) {
+      return Err(NS_ERROR_FAILURE);
+    }
+    for (uint8_t i = 0; i < defaultConstantIVSize; i++) {
+      MOZ_TRY_VAR(mSinf.mDefaultConstantIV.ElementAt(i), reader->ReadU8());
+    }
+  }
   return Ok();
 }
 
 }  // namespace mozilla
--- a/dom/media/mp4/SinfParser.h
+++ b/dom/media/mp4/SinfParser.h
@@ -10,26 +10,35 @@
 #include "AtomType.h"
 
 namespace mozilla {
 
 class Box;
 
 class Sinf : public Atom {
  public:
-  Sinf() : mDefaultIVSize(0), mDefaultEncryptionType() {}
+  Sinf()
+      : mDefaultIVSize(0),
+        mDefaultEncryptionType(),
+        mDefaultCryptByteBlock(0),
+        mDefaultSkipByteBlock(0) {}
   explicit Sinf(Box& aBox);
 
-  virtual bool IsValid() override {
-    return !!mDefaultIVSize && !!mDefaultEncryptionType;
+  bool IsValid() override {
+    return !!mDefaultEncryptionType &&  // Should have an encryption scheme
+           (mDefaultIVSize > 0 ||       // and either a default IV size
+            mDefaultConstantIV.Length() > 0);  // or a constant IV.
   }
 
   uint8_t mDefaultIVSize;
   AtomType mDefaultEncryptionType;
   uint8_t mDefaultKeyID[16];
+  uint8_t mDefaultCryptByteBlock;
+  uint8_t mDefaultSkipByteBlock;
+  nsTArray<uint8_t> mDefaultConstantIV;
 };
 
 class SinfParser {
  public:
   explicit SinfParser(Box& aBox);
 
   Sinf& GetSinf() { return mSinf; }