From 6a1580e84f492b5671d23be98192267bb73de250 Mon Sep 17 00:00:00 2001 From: Marek Kasik 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