From 0d1848dcdab736c5c927f391a5a25a0324d23fcb Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 6 Apr 2019 12:11:03 +0200 Subject: [PATCH] added surface boundary check --- src/emucore/FBSurface.cxx | 35 ++++++++++++++++++++++++++++++++++- src/emucore/FBSurface.hxx | 10 ++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/emucore/FBSurface.cxx b/src/emucore/FBSurface.cxx index 161fc2d53..344191798 100644 --- a/src/emucore/FBSurface.cxx +++ b/src/emucore/FBSurface.cxx @@ -62,6 +62,7 @@ void FBSurface::readPixels(uInt8* buffer, uInt32 pitch, const GUI::Rect& rect) c // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurface::pixel(uInt32 x, uInt32 y, ColorId color) { + // Note: checkbounds() must be done in calling method uInt32* buffer = myPixels + y * myPitch + x; *buffer = uInt32(myPalette[color]); @@ -70,6 +71,9 @@ void FBSurface::pixel(uInt32 x, uInt32 y, ColorId color) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurface::line(uInt32 x, uInt32 y, uInt32 x2, uInt32 y2, ColorId color) { + if(!checkBounds(x, y) || !checkBounds(x2, y2)) + return; + // draw line using Bresenham algorithm Int32 dx = (x2 - x); Int32 dy = (y2 - y); @@ -129,6 +133,9 @@ void FBSurface::line(uInt32 x, uInt32 y, uInt32 x2, uInt32 y2, ColorId color) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurface::hLine(uInt32 x, uInt32 y, uInt32 x2, ColorId color) { + if(!checkBounds(x, y) || !checkBounds(x2, 2)) + return; + uInt32* buffer = myPixels + y * myPitch + x; while(x++ <= x2) *buffer++ = uInt32(myPalette[color]); @@ -137,6 +144,9 @@ void FBSurface::hLine(uInt32 x, uInt32 y, uInt32 x2, ColorId color) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurface::vLine(uInt32 x, uInt32 y, uInt32 y2, ColorId color) { + if(!checkBounds(x, y) || !checkBounds(x, y2)) + return; + uInt32* buffer = static_cast(myPixels + y * myPitch + x); while(y++ <= y2) { @@ -190,8 +200,14 @@ void FBSurface::drawChar(const GUI::Font& font, uInt8 chr, bby = desc.bbx[chr].y; } + int cx = tx + bbx; + int cy = ty + desc.ascent - bby - bbh; + + if(!checkBounds(cx , cy) || !checkBounds(cx + bbw - 1, cy + bbh - 1)) + return; + const uInt16* tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.fbbh)); - uInt32* buffer = myPixels + (ty + desc.ascent - bby - bbh) * myPitch + tx + bbx; + uInt32* buffer = myPixels + cy * myPitch + cx; for(int y = 0; y < bbh; y++) { @@ -217,6 +233,9 @@ void FBSurface::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty, void FBSurface::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty, ColorId color, uInt32 w, uInt32 h) { + if(!checkBounds(tx, ty) || !checkBounds(tx + w - 1, ty + h - 1)) + return; + uInt32* buffer = myPixels + ty * myPitch + tx; for(uInt32 y = 0; y < h; ++y) @@ -233,6 +252,9 @@ void FBSurface::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurface::drawPixels(uInt32* data, uInt32 tx, uInt32 ty, uInt32 numpixels) { + if(!checkBounds(tx, ty) || !checkBounds(tx + numpixels - 1, ty)) + return; + uInt32* buffer = myPixels + ty * myPitch + tx; for(uInt32 i = 0; i < numpixels; ++i) @@ -338,5 +360,16 @@ void FBSurface::drawString(const GUI::Font& font, const string& s, } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool FBSurface::checkBounds(const int x, const int y) const +{ + if (x >= 0 && x <= (int)width() && y >= 0 && y <= (int)height()) + return true; + + cerr << "FBSurface::checkBounds() failed: " + << x << ", " << y << " vs " << width() << ", " << height() << endl; + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const uInt32* FBSurface::myPalette = nullptr; diff --git a/src/emucore/FBSurface.hxx b/src/emucore/FBSurface.hxx index 74031aecb..b893a5077 100644 --- a/src/emucore/FBSurface.hxx +++ b/src/emucore/FBSurface.hxx @@ -219,6 +219,16 @@ class FBSurface ColorId color, TextAlign align = TextAlign::Left, int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone); + /** + This method should be called to check if the given coordinates are in + bounds of the surface. + + @param x The x coordinate to check + @param y The y coordinate to check + @return True if coordinates are in bounds + */ + virtual bool checkBounds(const int x, const int y) const; + ////////////////////////////////////////////////////////////////////////// // Note: The following methods are FBSurface-specific, and must be // implemented in child classes.