[tor-commits] [tor-browser] 18/43: Bug 1767365 - Clip image data transfers. r=aosmond, a=RyanVM

gitolite role git at cupani.torproject.org
Tue May 31 07:07:01 UTC 2022


This is an automated email from the git hooks/post-receive script.

pierov pushed a commit to branch tor-browser-91.10.0esr-11.0-1
in repository tor-browser.

commit 7967e9aebf8532e5d149feba418fde16bf2dd5f6
Author: Lee Salzman <lsalzman at mozilla.com>
AuthorDate: Tue May 10 05:26:44 2022 +0000

    Bug 1767365 - Clip image data transfers. r=aosmond, a=RyanVM
    
    Differential Revision: https://phabricator.services.mozilla.com/D145674
---
 dom/canvas/CanvasRenderingContext2D.cpp | 28 +++++++++++++++++-----------
 gfx/2d/BaseRect.h                       | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
index b80b371d2867e..1098cb8d811e2 100644
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -5044,6 +5044,16 @@ already_AddRefed<ImageData> CanvasRenderingContext2D::GetImageData(
   return MakeAndAddRef<ImageData>(w, h, *array);
 }
 
+static IntRect ClipImageDataTransfer(IntRect& aSrc, const IntPoint& aDestOffset,
+                                     const IntSize& aDestBounds) {
+  IntRect dest = aSrc;
+  dest.SafeMoveBy(aDestOffset);
+  dest = IntRect(IntPoint(0, 0), aDestBounds).SafeIntersect(dest);
+
+  aSrc = aSrc.SafeIntersect(dest - aDestOffset);
+  return aSrc + aDestOffset;
+}
+
 nsresult CanvasRenderingContext2D::GetImageDataArray(
     JSContext* aCx, int32_t aX, int32_t aY, uint32_t aWidth, uint32_t aHeight,
     nsIPrincipal& aSubjectPrincipal, JSObject** aRetval) {
@@ -5073,9 +5083,9 @@ nsresult CanvasRenderingContext2D::GetImageDataArray(
     return NS_OK;
   }
 
-  IntRect srcRect(0, 0, mWidth, mHeight);
-  IntRect destRect(aX, aY, aWidth, aHeight);
-  IntRect srcReadRect = srcRect.Intersect(destRect);
+  IntRect dstWriteRect(0, 0, aWidth, aHeight);
+  IntRect srcReadRect = ClipImageDataTransfer(dstWriteRect, IntPoint(aX, aY),
+                                              IntSize(mWidth, mHeight));
   if (srcReadRect.IsEmpty()) {
     *aRetval = darray;
     return NS_OK;
@@ -5100,9 +5110,6 @@ nsresult CanvasRenderingContext2D::GetImageDataArray(
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  IntRect dstWriteRect = srcReadRect;
-  dstWriteRect.MoveBy(-aX, -aY);
-
   // Check for site-specific permission.  This check is not needed if the
   // canvas was created with a docshell (that is only done for special
   // internal uses).
@@ -5253,10 +5260,10 @@ void CanvasRenderingContext2D::PutImageData_explicit(
     dirtyRect = imageDataRect;
   }
 
-  dirtyRect.MoveBy(IntPoint(aX, aY));
-  dirtyRect = IntRect(0, 0, mWidth, mHeight).Intersect(dirtyRect);
-
-  if (dirtyRect.Width() <= 0 || dirtyRect.Height() <= 0) {
+  IntRect srcRect = dirtyRect;
+  dirtyRect = ClipImageDataTransfer(srcRect, IntPoint(aX, aY),
+                                    IntSize(mWidth, mHeight));
+  if (dirtyRect.IsEmpty()) {
     return;
   }
 
@@ -5311,7 +5318,6 @@ void CanvasRenderingContext2D::PutImageData_explicit(
     dstFormat = sourceSurface->GetFormat();
   }
 
-  IntRect srcRect = dirtyRect - IntPoint(aX, aY);
   uint8_t* srcData = arr.Data() + srcRect.y * (width * 4) + srcRect.x * 4;
 
   PremultiplyData(
diff --git a/gfx/2d/BaseRect.h b/gfx/2d/BaseRect.h
index 8d0a3f1db1c72..b72d6c1d5548b 100644
--- a/gfx/2d/BaseRect.h
+++ b/gfx/2d/BaseRect.h
@@ -313,6 +313,39 @@ struct BaseRect {
     height = aSize.height;
   }
 
+  // Variant of MoveBy that ensures that even after translation by a point that
+  // the rectangle coordinates will still fit within numeric limits. The origin
+  // and size will be clipped within numeric limits to ensure this.
+  void SafeMoveByX(T aDx) {
+    T x2 = XMost();
+    if (aDx >= T(0)) {
+      T limit = std::numeric_limits<T>::max();
+      x = limit - aDx < x ? limit : x + aDx;
+      width = (limit - aDx < x2 ? limit : x2 + aDx) - x;
+    } else {
+      T limit = std::numeric_limits<T>::min();
+      x = limit - aDx > x ? limit : x + aDx;
+      width = (limit - aDx > x2 ? limit : x2 + aDx) - x;
+    }
+  }
+  void SafeMoveByY(T aDy) {
+    T y2 = YMost();
+    if (aDy >= T(0)) {
+      T limit = std::numeric_limits<T>::max();
+      y = limit - aDy < y ? limit : y + aDy;
+      height = (limit - aDy < y2 ? limit : y2 + aDy) - y;
+    } else {
+      T limit = std::numeric_limits<T>::min();
+      y = limit - aDy > y ? limit : y + aDy;
+      height = (limit - aDy > y2 ? limit : y2 + aDy) - y;
+    }
+  }
+  void SafeMoveBy(T aDx, T aDy) {
+    SafeMoveByX(aDx);
+    SafeMoveByY(aDy);
+  }
+  void SafeMoveBy(const Point& aPoint) { SafeMoveBy(aPoint.x, aPoint.y); }
+
   void Inflate(T aD) { Inflate(aD, aD); }
   void Inflate(T aDx, T aDy) {
     x -= aDx;

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list