From 6a1580e84f492b5671d23be98192267bb73de250 Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Mon, 13 May 2019 15:08:38 +0200
Subject: [PATCH] Splash: Restrict filling of overlapping boxes

Check whether area to fill in Splash::blitTransparent()
does not run out of allocated memory for source and for destination
and shrink it if needed.

Fixes #750
---
 splash/Splash.cc | 48 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/splash/Splash.cc b/splash/Splash.cc
index 0a06f9c8..4ac163e4 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -5853,7 +5853,7 @@ SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
 				    int xDest, int yDest, int w, int h) {
   SplashColorPtr p, sp;
   Guchar *q;
-  int x, y, mask, srcMask;
+  int x, y, mask, srcMask, width = w, height = h;
 
   if (src->mode != bitmap->mode) {
     return splashErrModeMismatch;
@@ -5863,14 +5863,32 @@ SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
     return splashErrZeroImage;
   }
 
+  if (src->getWidth() - xSrc < width)
+    width = src->getWidth() - xSrc;
+
+  if (src->getHeight() - ySrc < height)
+    height = src->getHeight() - ySrc;
+
+  if (bitmap->getWidth() - xDest < width)
+    width = bitmap->getWidth() - xDest;
+
+  if (bitmap->getHeight() - yDest < height)
+    height = bitmap->getHeight() - yDest;
+
+  if (width < 0)
+    width = 0;
+
+  if (height < 0)
+    height = 0;
+
   switch (bitmap->mode) {
   case splashModeMono1:
-    for (y = 0; y < h; ++y) {
+    for (y = 0; y < height; ++y) {
       p = &bitmap->data[(yDest + y) * bitmap->rowSize + (xDest >> 3)];
       mask = 0x80 >> (xDest & 7);
       sp = &src->data[(ySrc + y) * src->rowSize + (xSrc >> 3)];
       srcMask = 0x80 >> (xSrc & 7);
-      for (x = 0; x < w; ++x) {
+      for (x = 0; x < width; ++x) {
 	if (*sp & srcMask) {
 	  *p |= mask;
 	} else {
@@ -5888,20 +5906,20 @@ SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
     }
     break;
   case splashModeMono8:
-    for (y = 0; y < h; ++y) {
+    for (y = 0; y < height; ++y) {
       p = &bitmap->data[(yDest + y) * bitmap->rowSize + xDest];
       sp = &src->data[(ySrc + y) * bitmap->rowSize + xSrc];
-      for (x = 0; x < w; ++x) {
+      for (x = 0; x < width; ++x) {
 	*p++ = *sp++;
       }
     }
     break;
   case splashModeRGB8:
   case splashModeBGR8:
-    for (y = 0; y < h; ++y) {
+    for (y = 0; y < height; ++y) {
       p = &bitmap->data[(yDest + y) * bitmap->rowSize + 3 * xDest];
       sp = &src->data[(ySrc + y) * src->rowSize + 3 * xSrc];
-      for (x = 0; x < w; ++x) {
+      for (x = 0; x < width; ++x) {
 	*p++ = *sp++;
 	*p++ = *sp++;
 	*p++ = *sp++;
@@ -5909,10 +5927,10 @@ SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
     }
     break;
   case splashModeXBGR8:
-    for (y = 0; y < h; ++y) {
+    for (y = 0; y < height; ++y) {
       p = &bitmap->data[(yDest + y) * bitmap->rowSize + 4 * xDest];
       sp = &src->data[(ySrc + y) * src->rowSize + 4 * xSrc];
-      for (x = 0; x < w; ++x) {
+      for (x = 0; x < width; ++x) {
 	*p++ = *sp++;
 	*p++ = *sp++;
 	*p++ = *sp++;
@@ -5923,10 +5941,10 @@ SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
     break;
 #ifdef SPLASH_CMYK
   case splashModeCMYK8:
-    for (y = 0; y < h; ++y) {
+    for (y = 0; y < height; ++y) {
       p = &bitmap->data[(yDest + y) * bitmap->rowSize + 4 * xDest];
       sp = &src->data[(ySrc + y) * src->rowSize + 4 * xSrc];
-      for (x = 0; x < w; ++x) {
+      for (x = 0; x < width; ++x) {
 	*p++ = *sp++;
 	*p++ = *sp++;
 	*p++ = *sp++;
@@ -5935,10 +5953,10 @@ SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
     }
     break;
   case splashModeDeviceN8:
-    for (y = 0; y < h; ++y) {
+    for (y = 0; y < height; ++y) {
       p = &bitmap->data[(yDest + y) * bitmap->rowSize + (SPOT_NCOMPS+4) * xDest];
       sp = &src->data[(ySrc + y) * src->rowSize + (SPOT_NCOMPS+4) * xSrc];
-      for (x = 0; x < w; ++x) {
+      for (x = 0; x < width; ++x) {
         for (int cp=0; cp < SPOT_NCOMPS+4; cp++)
           *p++ = *sp++;
       }
@@ -5948,9 +5966,9 @@ SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
   }
 
   if (bitmap->alpha) {
-    for (y = 0; y < h; ++y) {
+    for (y = 0; y < height; ++y) {
       q = &bitmap->alpha[(yDest + y) * bitmap->width + xDest];
-      memset(q, 0x00, w);
+      memset(q, 0x00, width);
     }
   }
 
-- 
GitLab

