# HG changeset patch # User SamuXarick <43006711+SamuXarick@users.noreply.github.com> # Date 2024-01-27 21:11:02 # Node ID 2880086cc07177c1b0385ddf1d787b62e992aaa6 # Parent d5de6992fa2addc8bc632415010b9fe44cad5d3d Fix #10438: [GS] Validate story page element type for ScriptStoryPage::NewElement (#11888) Fixes a crash that happens if an invalid StoryPageElementType is passed to ScriptStoryPage::NewElement. Adds an enforced precondition that tests the validity of StoryPageElementType. Adds GSStoryPage::IsValidStoryPageElementType to the API. diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -81,6 +81,7 @@ * \li GSGoal::SetDestination * \li GSIndustry::GetProductionLevel * \li GSIndustry::SetProductionLevel + * \li GSStoryPage::IsValidStoryPageElementType * * API removals: * \li GSError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore. diff --git a/src/script/api/script_story_page.cpp b/src/script/api/script_story_page.cpp --- a/src/script/api/script_story_page.cpp +++ b/src/script/api/script_story_page.cpp @@ -38,6 +38,11 @@ static inline bool StoryPageElementTypeR return ::StoryPageElement::IsValidID(story_page_element_id); } +/* static */ bool ScriptStoryPage::IsValidStoryPageElementType(StoryPageElementType type) +{ + return type == SPET_TEXT || type == SPET_LOCATION || type == SPET_GOAL || type == SPET_BUTTON_PUSH || type == SPET_BUTTON_TILE || type == SPET_BUTTON_VEHICLE; +} + /* static */ ScriptStoryPage::StoryPageID ScriptStoryPage::New(ScriptCompany::CompanyID company, Text *title) { CCountedPtr counter(title); @@ -63,6 +68,7 @@ static inline bool StoryPageElementTypeR EnforceDeityMode(STORY_PAGE_ELEMENT_INVALID); EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, IsValidStoryPage(story_page_id)); + EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, IsValidStoryPageElementType(type)); std::string encoded_text; if (StoryPageElementTypeRequiresText(btype)) { EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, text != nullptr); diff --git a/src/script/api/script_story_page.hpp b/src/script/api/script_story_page.hpp --- a/src/script/api/script_story_page.hpp +++ b/src/script/api/script_story_page.hpp @@ -180,6 +180,13 @@ public: static bool IsValidStoryPageElement(StoryPageElementID story_page_element_id); /** + * Check whether this is a valid story page element type. + * @param type The StoryPageElementType to check. + * @return True if and only if this story page element type is valid. + */ + static bool IsValidStoryPageElementType(StoryPageElementType type); + + /** * Create a new story page. * @param company The company to create the story page for, or ScriptCompany::COMPANY_INVALID for all. * @param title Page title (can be either a raw string, a ScriptText object, or null). @@ -202,6 +209,7 @@ public: * @return The new StoryPageElementID, or STORY_PAGE_ELEMENT_INVALID if it failed. * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidStoryPage(story_page). + * @pre IsValidStoryPageElementType(type). * @pre (type != SPET_TEXT && type != SPET_LOCATION) || (text != null && len(text) != 0). * @pre type != SPET_LOCATION || ScriptMap::IsValidTile(reference). * @pre type != SPET_GOAL || ScriptGoal::IsValidGoal(reference).