Bug 1428947 - Check plane width & stride constraints. r=mattwoodrow, a=ritu
authorDan Glastonbury <dan.glastonbury@gmail.com>
Tue, 20 Feb 2018 16:16:10 -0500
changeset 356863 456913d7e8b5
parent 356862 ac743923f81d
child 356864 f95c5b881442
push id7552
push userryanvm@gmail.com
push dateTue, 20 Feb 2018 21:20:17 +0000
treeherdermozilla-esr52@8a4265c8fb41 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow, ritu
bugs1428947
milestone52.6.1
Bug 1428947 - Check plane width & stride constraints. r=mattwoodrow, a=ritu MozReview-Commit-ID: 328ETwMdVnq
dom/media/MediaData.cpp
gfx/layers/ImageContainer.cpp
--- a/dom/media/MediaData.cpp
+++ b/dom/media/MediaData.cpp
@@ -85,17 +85,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;
 }
 
 #ifdef MOZ_WIDGET_GONK
 static bool
 IsYV12Format(const VideoData::YCbCrBuffer::Plane& aYPlane,
              const VideoData::YCbCrBuffer::Plane& aCbPlane,
              const VideoData::YCbCrBuffer::Plane& aCrPlane)
 {
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -433,22 +433,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;
       }
@@ -456,47 +459,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()