From 1d0f6b3a95b52fd289d900d5578c980a1c3ae3cb Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Tue, 10 Jan 2023 19:40:13 -0800 Subject: [PATCH] more careful bounds checking for screen tiles --- library/modules/Screen.cpp | 45 ++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index 30e922708..ae0a15b5e 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -116,17 +116,22 @@ bool Screen::inGraphicsMode() } static bool doSetTile_map(const Pen &pen, int x, int y) { - size_t max_index = gps->main_viewport->dim_x * gps->main_viewport->dim_y - 1; - size_t index = (x * gps->main_viewport->dim_y) + y; + auto &vp = gps->main_viewport; - if (index < 0 || index > max_index) + if (x < 0 || x >= vp->dim_x || y < 0 || y >= vp->dim_y) + return false; + + size_t max_index = vp->dim_x * vp->dim_y - 1; + size_t index = (x * vp->dim_y) + y; + + if (index > max_index) return false; long texpos = pen.tile; if (texpos == 0) { texpos = init->font.large_font_texpos[(uint8_t)pen.ch]; } - gps->main_viewport->screentexpos_interface[index] = texpos; + vp->screentexpos_interface[index] = texpos; return true; } @@ -137,6 +142,9 @@ static bool doSetTile_default(const Pen &pen, int x, int y, bool map) if (map && use_graphics) return doSetTile_map(pen, x, y); + if (x < 0 || x >= gps->dimx || y < 0 || y >= gps->dimy) + return false; + size_t index = (x * gps->dimy) + y; uint8_t *screen = &gps->screen[index * 8]; @@ -208,28 +216,33 @@ static bool doSetTile(const Pen &pen, int x, int y, bool map) bool Screen::paintTile(const Pen &pen, int x, int y, bool map) { - if (!gps || !pen.valid() || x < 0 || y < 0) return false; + if (!gps || !pen.valid()) return false; doSetTile(pen, x, y, map); return true; } static Pen doGetTile_map(int x, int y) { - size_t max_index = gps->main_viewport->dim_x * gps->main_viewport->dim_y - 1; - size_t index = (x * gps->main_viewport->dim_y) + y; + auto &vp = gps->main_viewport; + + if (x < 0 || x >= vp->dim_x || y < 0 || y >= vp->dim_y) + return Pen(0, 0, 0, -1); + + size_t max_index = vp->dim_x * vp->dim_y - 1; + size_t index = (x * vp->dim_y) + y; if (index < 0 || index > max_index) return Pen(0, 0, 0, -1); - int tile = gps->main_viewport->screentexpos[index]; + int tile = vp->screentexpos[index]; if (tile == 0) - tile = gps->main_viewport->screentexpos_item[index]; + tile = vp->screentexpos_item[index]; if (tile == 0) - tile = gps->main_viewport->screentexpos_building_one[index]; + tile = vp->screentexpos_building_one[index]; if (tile == 0) - tile = gps->main_viewport->screentexpos_background_two[index]; + tile = vp->screentexpos_background_two[index]; if (tile == 0) - tile = gps->main_viewport->screentexpos_background[index]; + tile = vp->screentexpos_background[index]; char ch = 0; uint8_t fg = 0; @@ -249,14 +262,14 @@ static uint8_t to_16_bit_color(uint8_t *rgb) { } static Pen doGetTile_default(int x, int y, bool map) { - if (x < 0 || y < 0) - return Pen(0, 0, 0, -1); - bool use_graphics = Screen::inGraphicsMode(); if (map && use_graphics) return doGetTile_map(x, y); + if (x < 0 || x >= gps->dimx || y < 0 || y >= gps->dimy) + return Pen(0, 0, 0, -1); + size_t index = (x * gps->dimy) + y; uint8_t *screen = &gps->screen[index * 8]; @@ -301,7 +314,7 @@ static Pen doGetTile(int x, int y, bool map) Pen Screen::readTile(int x, int y, bool map) { - if (!gps || x < 0 || y < 0) return Pen(0,0,0,-1); + if (!gps) return Pen(0,0,0,-1); return doGetTile(x, y, map); }