Bug 1428947 - Check plane width & stride constraints. r=mattwoodrow
authorDan Glastonbury <dan.glastonbury@gmail.com>
Thu, 08 Feb 2018 10:09:32 +1000
changeset 404362 5c26e5d34680
parent 404361 07e8cd273ed6
child 404363 477829f02dd7
push id99994
push userdglastonbury@mozilla.com
push dateMon, 19 Feb 2018 01:44:37 +0000
treeherdermozilla-inbound@5c26e5d34680 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1428947
milestone60.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 1428947 - Check plane width & stride constraints. r=mattwoodrow MozReview-Commit-ID: HEcMG4JoEl3
dom/media/MediaData.cpp
gfx/layers/ImageContainer.cpp
--- a/dom/media/MediaData.cpp
+++ b/dom/media/MediaData.cpp
@@ -103,17 +103,17 @@ AudioData::TransferAndUpdateTimestampAnd
 }
 
 static bool
 ValidatePlane(const VideoData::YCbCrBuffer::Plane& aPlane)
 {
   return aPlane.mWidth <= PlanarYCbCrImage::MAX_DIMENSION &&
          aPlane.mHeight <= PlanarYCbCrImage::MAX_DIMENSION &&
          aPlane.mWidth * aPlane.mHeight < MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
-         aPlane.mStride > 0;
+         aPlane.mStride > 0 && aPlane.mWidth <= aPlane.mStride;
 }
 
 static bool ValidateBufferAndPicture(const VideoData::YCbCrBuffer& aBuffer,
                                      const IntRect& aPicture)
 {
   // The following situation should never happen unless there is a bug
   // in the decoder
   if (aBuffer.mPlanes[1].mWidth != aBuffer.mPlanes[2].mWidth ||
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -534,22 +534,25 @@ RecyclingPlanarYCbCrImage::AllocateBuffe
 {
   return mRecycleBin->GetBuffer(aSize);
 }
 
 static void
 CopyPlane(uint8_t *aDst, const uint8_t *aSrc,
           const gfx::IntSize &aSize, int32_t aStride, int32_t aSkip)
 {
+  int32_t height = aSize.height;
+  int32_t width = aSize.width;
+
+  MOZ_RELEASE_ASSERT(width <= aStride);
+
   if (!aSkip) {
     // Fast path: planar input.
-    memcpy(aDst, aSrc, aSize.height * aStride);
+    memcpy(aDst, aSrc, height * aStride);
   } else {
-    int32_t height = aSize.height;
-    int32_t width = aSize.width;
     for (int y = 0; y < height; ++y) {
       const uint8_t *src = aSrc;
       uint8_t *dst = aDst;
       // Slow path
       for (int x = 0; x < width; ++x) {
         *dst++ = *src++;
         src += aSkip;
       }
@@ -557,47 +560,47 @@ CopyPlane(uint8_t *aDst, const uint8_t *
       aDst += aStride;
     }
   }
 }
 
 bool
 RecyclingPlanarYCbCrImage::CopyData(const Data& aData)
 {
-  mData = aData;
-
   // update buffer size
   // Use uint32_t throughout to match AllocateBuffer's param and mBufferSize
   const auto checkedSize =
-    CheckedInt<uint32_t>(mData.mCbCrStride) * mData.mCbCrSize.height * 2 +
-    CheckedInt<uint32_t>(mData.mYStride) * mData.mYSize.height;
+    CheckedInt<uint32_t>(aData.mCbCrStride) * aData.mCbCrSize.height * 2 +
+    CheckedInt<uint32_t>(aData.mYStride) * aData.mYSize.height;
 
   if (!checkedSize.isValid())
     return false;
 
   const auto size = checkedSize.value();
 
   // get new buffer
   mBuffer = AllocateBuffer(size);
   if (!mBuffer)
     return false;
 
   // update buffer size
   mBufferSize = size;
 
+  mData = aData;
   mData.mYChannel = mBuffer.get();
   mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height;
   mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height;
+  mData.mYSkip = mData.mCbSkip = mData.mCrSkip = 0;
 
   CopyPlane(mData.mYChannel, aData.mYChannel,
-            mData.mYSize, mData.mYStride, mData.mYSkip);
+            aData.mYSize, aData.mYStride, aData.mYSkip);
   CopyPlane(mData.mCbChannel, aData.mCbChannel,
-            mData.mCbCrSize, mData.mCbCrStride, mData.mCbSkip);
+            aData.mCbCrSize, aData.mCbCrStride, aData.mCbSkip);
   CopyPlane(mData.mCrChannel, aData.mCrChannel,
-            mData.mCbCrSize, mData.mCbCrStride, mData.mCrSkip);
+            aData.mCbCrSize, aData.mCbCrStride, aData.mCrSkip);
 
   mSize = aData.mPicSize;
   mOrigin = gfx::IntPoint(aData.mPicX, aData.mPicY);
   return true;
 }
 
 gfxImageFormat
 PlanarYCbCrImage::GetOffscreenFormat() const