Bug 1235605 - Use CheckedInt in Deinterlacer and make its buffer allocation fallible - r=tn a=abillings
authorEdwin Flores <eflores@mozilla.com>
Tue, 05 Jan 2016 12:43:53 -0800
changeset 305964 5622177b1e95f677efa8786d228981e71648b1a7
parent 305963 aaa41a664b4187efcef4c28b8b7e95f6ce119cfc
child 305965 557dc9dd4dbd4f4de0d0666b830b03c3a235d621
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn, abillings
bugs1235605
milestone44.0
Bug 1235605 - Use CheckedInt in Deinterlacer and make its buffer allocation fallible - r=tn a=abillings
image/Deinterlacer.cpp
image/Deinterlacer.h
image/decoders/nsGIFDecoder2.cpp
image/test/crashtests/1235605.gif
image/test/crashtests/crashtests.list
--- a/image/Deinterlacer.cpp
+++ b/image/Deinterlacer.cpp
@@ -1,45 +1,55 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * 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 http://mozilla.org/MPL/2.0/. */
 
 
 #include "Downscaler.h"
+#include "mozilla/UniquePtrExtensions.h"
 
 namespace mozilla {
 namespace image {
 
 Deinterlacer::Deinterlacer(const nsIntSize& aImageSize)
   : mImageSize(aImageSize)
-  , mBuffer(MakeUnique<uint8_t[]>(mImageSize.width *
-                                  mImageSize.height *
-                                  sizeof(uint32_t)))
-{ }
+{
+  CheckedInt<size_t> bufferSize = mImageSize.width;
+  bufferSize *= mImageSize.height;
+  bufferSize *= sizeof(uint32_t);
+
+  if (!bufferSize.isValid()) {
+    return;
+  }
+
+  mBuffer = MakeUniqueFallible<uint8_t[]>(bufferSize.value());
+}
 
 uint32_t
 Deinterlacer::RowSize() const
 {
   return mImageSize.width * sizeof(uint32_t);
 }
 
 uint8_t*
 Deinterlacer::RowBuffer(uint32_t aRow)
 {
   uint32_t offset = aRow * RowSize();
+  MOZ_ASSERT(IsValid(), "Deinterlacer in invalid state");
   MOZ_ASSERT(offset < mImageSize.width * mImageSize.height * sizeof(uint32_t),
              "Row is outside of image");
   return mBuffer.get() + offset;
 }
 
 void
 Deinterlacer::PropagatePassToDownscaler(Downscaler& aDownscaler)
 {
+  MOZ_ASSERT(IsValid(), "Deinterlacer in invalid state");
   for (int32_t row = 0 ; row < mImageSize.height ; ++row) {
     memcpy(aDownscaler.RowBuffer(), RowBuffer(row), RowSize());
     aDownscaler.CommitRow();
   }
 }
 
 } // namespace image
 } // namespace mozilla
--- a/image/Deinterlacer.h
+++ b/image/Deinterlacer.h
@@ -27,16 +27,17 @@
 
 namespace mozilla {
 namespace image {
 
 class Deinterlacer
 {
 public:
   explicit Deinterlacer(const nsIntSize& aImageSize);
+  bool IsValid() { return !!mBuffer; }
 
   uint8_t* RowBuffer(uint32_t aRow);
   void PropagatePassToDownscaler(Downscaler& aDownscaler);
 
 private:
   uint32_t RowSize() const;
 
   nsIntSize mImageSize;
--- a/image/decoders/nsGIFDecoder2.cpp
+++ b/image/decoders/nsGIFDecoder2.cpp
@@ -1173,16 +1173,22 @@ nsGIFDecoder2::WriteInternal(const char*
         }
       }
 
       if (q[8] & 0x40) {
         mGIFStruct.interlaced = true;
         mGIFStruct.ipass = 1;
         if (mDownscaler) {
           mDeinterlacer.emplace(mDownscaler->FrameSize());
+
+          if (!mDeinterlacer->IsValid()) {
+            mDeinterlacer.reset();
+            mGIFStruct.state = gif_error;
+            break;
+          }
         }
       } else {
         mGIFStruct.interlaced = false;
         mGIFStruct.ipass = 0;
       }
 
       // Only apply the Haeberli display hack on the first frame
       mGIFStruct.progressive_display = (mGIFStruct.images_decoded == 0);
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e7c3ea0b876b0cbbd42b49c65b54878f32f1e7d8
GIT binary patch
literal 2360
zc${<hbhEHb{P+L&|K|-1{qq)_dtSBeJ=@l&M=vBDVOVIxKnf5bNi`0@M7AX5fQ5=?
zH4sw3NRn~5!j=gS56wRuV6p*>sOVEXaiV}<ClwvhKu7@xoTd1m+s`%Rva@4=tC5}o
zGbkDqf3h%$0cjnOJSZ<Xuy6;Q^jy8y;`Q0x|0}@qum3~k*%^NRZ}B~<eA_PSksM2x
zzFx+k`)BGvGT362m3M(wUrOe@j8*G$Uhm5Q8}$-q)a(De49$%Q#o(YswmJf={u4|+
zD=--}|2+HZaGDld#(@XB3%|rgt`O01$-t`ZCrsO`|H2H7tKP8x{CFbIsCI$L%iIHB
znCBht^X2%4W;aE^fq{W@O8?5!Z}}I`*#mX~KP*i7fPQG69eCtu@{x&n9Qx(I07FZI
zbun{icJ%}sL)YqEGZp4Ignbu6wFO5Q--CrQ*sKr#-~DgY7qvMm^Latj(kb;7`OBK;
zaW(Q0<rPM-JsbqpF)+b>yaw!*KQOPn`G5O=a|`R;iiqQeOJ{PgESG1rMA3;63e2Fu
zQUG~};rIW>>CZUwS{7}aRD^0Dt}KJ@RCIT-F+kn*>%S;Nqs$zm>i+HKUpOQ`7k>Qa
zvO37A;$ZVSeEQ$O{KX7pHZJ8UReW;YA$_~Ur$ZHArC&Xpr|gnVIIys|6AM7M`Uk{n
zMqp~<W@vFhD8wid5qa$$Jg<F&IsE1S&;Of_8n1fu_Y6;$^VvAd*B&C%Um096{3XcD
zwPM$ue+8$2@nHbg!~zQ~ZlHr3tERIqVRqTu1F?h=$&r8Ij{F6)MiiKu8@I%Ly1jS0
z<VVMVGRv3tix=+O`|RWM{q?e7tt@Z?r$>;23a$`2SfDlmW0Hh$gnR1u|1bX=f88;=
z0xX{!u<B$)7ss&t<9}v`mf7sxpMAKsZhhxNc!veO)JH1-nNZ5w-~U+|8jFOAB@Hg`
zyR}I~U<D`320UIu09@$^DO}P0{}CEROuP)hlEKtGVwU}cMwTT@pHyQS<ABX<WCN`M
DT7QSO
--- a/image/test/crashtests/crashtests.list
+++ b/image/test/crashtests/crashtests.list
@@ -40,16 +40,17 @@ load truncated-second-frame.png # bug 86
 # Bug 863958
 # This icon's size is such that it leads to multiple writes to the PNG decoder
 # after we've gotten our size.
 load multiple-png-hassize.ico
 
 # Bug 856615
 # Asserts in the debug build
 load 856616.gif
+load 1235605.gif
 
 skip-if(AddressSanitizer) skip-if(B2G) load 944353.jpg
 
 # Bug 1160801: Ensure that we handle invalid disposal types.
 load invalid-disposal-method-1.gif
 load invalid-disposal-method-2.gif
 load invalid-disposal-method-3.gif