From 45de20d789350910cdd1b54a7c9493f953f23fc7 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 21 Dec 2010 15:53:42 +0000 Subject: [PATCH] Add extra check for bad copy rects and try to handle it gracefully instead of just crashing. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4227 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- common/rfb/PixelBuffer.cxx | 39 ++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/common/rfb/PixelBuffer.cxx b/common/rfb/PixelBuffer.cxx index d093426f..a48e735a 100644 --- a/common/rfb/PixelBuffer.cxx +++ b/common/rfb/PixelBuffer.cxx @@ -225,25 +225,48 @@ void FullFramePixelBuffer::maskRect(const Rect& r, Pixel pixel, const void* mask void FullFramePixelBuffer::copyRect(const Rect &rect, const Point &move_by_delta) { int stride; - U8* data = getPixelsRW(getRect(), &stride); - // We assume that the specified rectangle is pre-clipped to the buffer + U8* data; unsigned int bytesPerPixel, bytesPerRow, bytesPerMemCpy; - Rect srect = rect.translate(move_by_delta.negate()); + Rect drect, srect = rect.translate(move_by_delta.negate()); + + drect = rect; + if (!drect.enclosed_by(getRect())) { + vlog.error("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d", + drect.width(), drect.height(), drect.tl.x, drect.tl.y, width_, height_); + drect = drect.intersect(getRect()); + } + + if (drect.is_empty()) + return; + + srect = drect.translate(move_by_delta.negate()); + if (!srect.enclosed_by(getRect())) { + vlog.error("Source rect %dx%d at %d,%d exceeds framebuffer %dx%d", + srect.width(), srect.height(), srect.tl.x, srect.tl.y, width_, height_); + srect = srect.intersect(getRect()); + // Need to readjust the destination now that the area has changed + drect = srect.translate(move_by_delta); + } + + if (srect.is_empty()) + return; + + data = getPixelsRW(getRect(), &stride); bytesPerPixel = getPF().bpp/8; bytesPerRow = stride * bytesPerPixel; - bytesPerMemCpy = rect.width() * bytesPerPixel; + bytesPerMemCpy = drect.width() * bytesPerPixel; if (move_by_delta.y <= 0) { - U8* dest = data + rect.tl.x*bytesPerPixel + rect.tl.y*bytesPerRow; + U8* dest = data + drect.tl.x*bytesPerPixel + drect.tl.y*bytesPerRow; U8* src = data + srect.tl.x*bytesPerPixel + srect.tl.y*bytesPerRow; - for (int i=rect.tl.y; i