From 416dc22f35cb2c0a6179e51dd51bfc096ed3366b Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Fri, 6 Mar 2020 15:06:28 +0100 Subject: [PATCH 1/2] Guard access to appriopriate image items per row --- src/openrct2-ui/interface/Dropdown.h | 3 +-- src/openrct2-ui/interface/LandTool.cpp | 9 +++++---- src/openrct2-ui/windows/Dropdown.cpp | 11 ++++++++--- src/openrct2-ui/windows/Footpath.cpp | 7 ++++--- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/openrct2-ui/interface/Dropdown.h b/src/openrct2-ui/interface/Dropdown.h index c16cb20b5c..99f6fbcc0b 100644 --- a/src/openrct2-ui/interface/Dropdown.h +++ b/src/openrct2-ui/interface/Dropdown.h @@ -23,8 +23,6 @@ enum DROPDOWN_FLAG_STAY_OPEN = (1 << 7) }; -extern int32_t gAppropriateImageDropdownItemsPerRow[]; - extern int32_t gDropdownNumItems; extern rct_string_id gDropdownItemsFormat[DROPDOWN_ITEMS_MAX_SIZE]; extern int64_t gDropdownItemsArgs[DROPDOWN_ITEMS_MAX_SIZE]; @@ -50,3 +48,4 @@ int32_t dropdown_index_from_point(const ScreenCoordsXY& loc, rct_window* w); void window_dropdown_show_colour(rct_window* w, rct_widget* widget, uint8_t dropdownColour, uint8_t selectedColour); void window_dropdown_show_colour_available( rct_window* w, rct_widget* widget, uint8_t dropdownColour, uint8_t selectedColour, uint32_t availableColours); +uint32_t dropdown_get_appropriate_image_dropdown_items_per_row(uint32_t numItems); diff --git a/src/openrct2-ui/interface/LandTool.cpp b/src/openrct2-ui/interface/LandTool.cpp index 8f316c5e30..000ec739d5 100644 --- a/src/openrct2-ui/interface/LandTool.cpp +++ b/src/openrct2-ui/interface/LandTool.cpp @@ -80,11 +80,11 @@ void land_tool_show_surface_style_dropdown(rct_window* w, rct_widget* widget, ui itemIndex++; } } - auto surfaceCount = itemIndex; + uint32_t surfaceCount = itemIndex; window_dropdown_show_image( w->windowPos.x + widget->left, w->windowPos.y + widget->top, widget->bottom - widget->top, w->colours[2], 0, - surfaceCount, 47, 36, gAppropriateImageDropdownItemsPerRow[surfaceCount]); + surfaceCount, 47, 36, dropdown_get_appropriate_image_dropdown_items_per_row(surfaceCount)); gDropdownDefaultIndex = defaultIndex; } @@ -109,11 +109,12 @@ void land_tool_show_edge_style_dropdown(rct_window* w, rct_widget* widget, uint8 itemIndex++; } } - auto edgeCount = itemIndex; + uint32_t edgeCount = itemIndex; + auto itemsPerRow = dropdown_get_appropriate_image_dropdown_items_per_row(edgeCount); window_dropdown_show_image( w->windowPos.x + widget->left, w->windowPos.y + widget->top, widget->bottom - widget->top, w->colours[2], 0, edgeCount, - 47, 36, gAppropriateImageDropdownItemsPerRow[edgeCount]); + 47, 36, itemsPerRow); gDropdownDefaultIndex = defaultIndex; } diff --git a/src/openrct2-ui/windows/Dropdown.cpp b/src/openrct2-ui/windows/Dropdown.cpp index db4c76ac8b..892e45be8d 100644 --- a/src/openrct2-ui/windows/Dropdown.cpp +++ b/src/openrct2-ui/windows/Dropdown.cpp @@ -22,8 +22,8 @@ constexpr int32_t DROPDOWN_TEXT_MAX_ROWS = 32; constexpr int32_t DROPDOWN_ITEM_HEIGHT = 12; -int32_t gAppropriateImageDropdownItemsPerRow[] = { - 1, 1, 1, 1, 2, 2, 3, 3, 4, 3, 5, 4, 4, 5, 5, 5, 4, 5, 6, 5, 5, 7, 4, 5, 6, 5, 6, 6, 6, 6, 6, 8, 8, 0, +static int32_t _appropriateImageDropdownItemsPerRow[34] = { + 1, 1, 1, 1, 2, 2, 3, 3, 4, 3, 5, 4, 4, 5, 5, 5, 4, 5, 6, 5, 5, 7, 4, 5, 6, 5, 6, 6, 6, 6, 6, 8, 8, 8, }; enum @@ -457,9 +457,14 @@ void window_dropdown_show_colour(rct_window* w, rct_widget* widget, uint8_t drop // Show dropdown window_dropdown_show_image( w->windowPos.x + widget->left, w->windowPos.y + widget->top, widget->bottom - widget->top + 1, dropdownColour, - DROPDOWN_FLAG_STAY_OPEN, COLOUR_COUNT, 12, 12, gAppropriateImageDropdownItemsPerRow[COLOUR_COUNT]); + DROPDOWN_FLAG_STAY_OPEN, COLOUR_COUNT, 12, 12, _appropriateImageDropdownItemsPerRow[COLOUR_COUNT]); gDropdownIsColour = true; gDropdownLastColourHover = -1; gDropdownDefaultIndex = defaultIndex; } + +uint32_t dropdown_get_appropriate_image_dropdown_items_per_row(uint32_t numItems) +{ + return numItems < std::size(_appropriateImageDropdownItemsPerRow) ? _appropriateImageDropdownItemsPerRow[numItems] : 8; +} diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index 7dda655bc2..3ce28c81e9 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -646,10 +646,10 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi) */ static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget* widget, bool showQueues) { - int32_t i, numPathTypes, image; + int32_t i, image; PathSurfaceEntry* pathType; - numPathTypes = 0; + uint32_t numPathTypes = 0; // If the game is in sandbox mode, also show paths that are normally restricted to the scenario editor bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode); @@ -677,9 +677,10 @@ static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget numPathTypes++; } + auto itemsPerRow = dropdown_get_appropriate_image_dropdown_items_per_row(numPathTypes); window_dropdown_show_image( w->windowPos.x + widget->left, w->windowPos.y + widget->top, widget->bottom - widget->top + 1, w->colours[1], 0, - numPathTypes, 47, 36, gAppropriateImageDropdownItemsPerRow[numPathTypes]); + numPathTypes, 47, 36, itemsPerRow); } /** From ceec430ae136c98ac36dc3d24921b05e3615a5f1 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 9 Mar 2020 12:22:29 +0100 Subject: [PATCH 2/2] Raise max size of dropdowns to 512 items --- src/openrct2-ui/interface/Dropdown.h | 8 ++++---- src/openrct2-ui/windows/Dropdown.cpp | 12 ++++++------ src/openrct2-ui/windows/Ride.cpp | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/openrct2-ui/interface/Dropdown.h b/src/openrct2-ui/interface/Dropdown.h index 99f6fbcc0b..6982e4b91f 100644 --- a/src/openrct2-ui/interface/Dropdown.h +++ b/src/openrct2-ui/interface/Dropdown.h @@ -12,10 +12,10 @@ #include #include -#define DROPDOWN_SEPARATOR 0 -#define DROPDOWN_FORMAT_COLOUR_PICKER 0xFFFE -#define DROPDOWN_FORMAT_LAND_PICKER 0xFFFF -#define DROPDOWN_ITEMS_MAX_SIZE 128 +constexpr const rct_string_id DROPDOWN_SEPARATOR = 0; +constexpr const rct_string_id DROPDOWN_FORMAT_COLOUR_PICKER = 0xFFFE; +constexpr const rct_string_id DROPDOWN_FORMAT_LAND_PICKER = 0xFFFF; +constexpr const int32_t DROPDOWN_ITEMS_MAX_SIZE = 512; enum { diff --git a/src/openrct2-ui/windows/Dropdown.cpp b/src/openrct2-ui/windows/Dropdown.cpp index 892e45be8d..01aef379b3 100644 --- a/src/openrct2-ui/windows/Dropdown.cpp +++ b/src/openrct2-ui/windows/Dropdown.cpp @@ -45,8 +45,8 @@ static bool _dropdown_list_vertically; int32_t gDropdownNumItems; rct_string_id gDropdownItemsFormat[DROPDOWN_ITEMS_MAX_SIZE]; int64_t gDropdownItemsArgs[DROPDOWN_ITEMS_MAX_SIZE]; -static bool _dropdownItemsChecked[DROPDOWN_ITEMS_MAX_SIZE]; -static bool _dropdownItemsDisabled[DROPDOWN_ITEMS_MAX_SIZE]; +static std::bitset _dropdownItemsChecked = {}; +static std::bitset _dropdownItemsDisabled = {}; bool gDropdownIsColour; int32_t gDropdownLastColourHover; int32_t gDropdownHighlightedIndex; @@ -217,8 +217,8 @@ void window_dropdown_show_text_custom_width( // Input state gDropdownHighlightedIndex = -1; - std::fill_n(_dropdownItemsDisabled, sizeof(_dropdownItemsDisabled), false); - std::fill_n(_dropdownItemsChecked, sizeof(_dropdownItemsChecked), false); + _dropdownItemsDisabled.reset(); + _dropdownItemsChecked.reset(); gDropdownIsColour = false; gDropdownDefaultIndex = -1; input_set_state(INPUT_STATE_DROPDOWN_ACTIVE); @@ -297,8 +297,8 @@ void window_dropdown_show_image( // Input state gDropdownHighlightedIndex = -1; - std::fill_n(_dropdownItemsDisabled, sizeof(_dropdownItemsDisabled), false); - std::fill_n(_dropdownItemsChecked, sizeof(_dropdownItemsChecked), false); + _dropdownItemsDisabled.reset(); + _dropdownItemsChecked.reset(); gDropdownIsColour = false; gDropdownDefaultIndex = -1; input_set_state(INPUT_STATE_DROPDOWN_ACTIVE); diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index a76e83ee97..5faef14558 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -4590,7 +4590,7 @@ static void window_ride_colour_mousedown(rct_window* w, rct_widgetindex widgetIn stringId = (ride->colour_scheme_type & 3) == VEHICLE_COLOUR_SCHEME_PER_TRAIN ? STR_RIDE_COLOUR_TRAIN_OPTION : STR_RIDE_COLOUR_VEHICLE_OPTION; - for (i = 0; i < std::min(numItems, (int32_t)DROPDOWN_ITEMS_MAX_SIZE); i++) + for (i = 0; i < std::min(numItems, DROPDOWN_ITEMS_MAX_SIZE); i++) { gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL; gDropdownItemsArgs[i] = ((int64_t)(i + 1) << 32)