From 9ac9798d7f98ec1d0f1faf7fe3028e27ca592153 Mon Sep 17 00:00:00 2001 From: frosch Date: Sat, 3 May 2025 17:46:30 +0200 Subject: [PATCH] Codechange: Remove usages of stoi and stol. (#14196) --- src/console_cmds.cpp | 10 ++--- src/intro_gui.cpp | 76 +++++++++++++++++----------------- src/safeguards.h | 7 ++++ src/saveload/saveload.cpp | 9 ++-- src/script/api/script_text.cpp | 5 ++- 5 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 3797c3c2b1..b5a5e0a989 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -2132,9 +2132,9 @@ static bool ConNetworkAuthorizedKey(std::span argv) authorized_key = argv[3]; if (StrStartsWithIgnoreCase(authorized_key, "client:")) { - std::string id_string(authorized_key.substr(7)); - authorized_key = NetworkGetPublicKeyOfClient(static_cast(std::stoi(id_string))); - if (authorized_key.empty()) { + auto value = ParseInteger(authorized_key.substr(7)); + if (value.has_value()) authorized_key = NetworkGetPublicKeyOfClient(static_cast(*value)); + if (!value.has_value() || authorized_key.empty()) { IConsolePrint(CC_ERROR, "You must enter a valid client id; see 'clients'."); return false; } @@ -2154,8 +2154,8 @@ static bool ConNetworkAuthorizedKey(std::span argv) } if (StrStartsWithIgnoreCase(type, "company:")) { - std::string id_string(type.substr(8)); - Company *c = Company::GetIfValid(std::stoi(id_string) - 1); + auto value = ParseInteger(type.substr(8)); + Company *c = value.has_value() ? Company::GetIfValid(*value - 1) : nullptr; if (c == nullptr) { IConsolePrint(CC_ERROR, "You must enter a valid company id; see 'companies'."); return false; diff --git a/src/intro_gui.cpp b/src/intro_gui.cpp index 5dac9a182d..612e8ce4a2 100644 --- a/src/intro_gui.cpp +++ b/src/intro_gui.cpp @@ -27,6 +27,7 @@ #include "game/game_gui.hpp" #include "gfx_func.h" #include "core/geometry_func.hpp" +#include "core/string_consumer.hpp" #include "language.h" #include "rev.h" #include "highscore.h" @@ -125,45 +126,46 @@ struct SelectGameWindow : public Window { for (const Sign *sign : Sign::Iterate()) { std::smatch match; - if (std::regex_search(sign->name, match, re)) { - IntroGameViewportCommand vc; - /* Sequence index from the first matching group. */ - vc.command_index = std::stoi(match[1].str()); - /* Sign coordinates for positioning. */ - vc.position = RemapCoords(sign->x, sign->y, sign->z); - /* Delay from the third matching group. */ - vc.delay = std::stoi(match[3].str()) * 1000; // milliseconds + if (!std::regex_search(sign->name, match, re)) continue; - /* Parse flags from second matching group. */ - enum IdType : uint8_t { - ID_NONE, ID_VEHICLE - } id_type = ID_NONE; - for (char c : match[2].str()) { - if (isdigit(c)) { - if (id_type == ID_VEHICLE) { - vc.vehicle = static_cast(vc.vehicle.base() * 10 + (c - '0')); - } - } else { - id_type = ID_NONE; - switch (toupper(c)) { - case '-': vc.zoom_adjust = +1; break; - case '+': vc.zoom_adjust = -1; break; - case 'T': vc.align_v = IntroGameViewportCommand::TOP; break; - case 'M': vc.align_v = IntroGameViewportCommand::MIDDLE; break; - case 'B': vc.align_v = IntroGameViewportCommand::BOTTOM; break; - case 'L': vc.align_h = IntroGameViewportCommand::LEFT; break; - case 'C': vc.align_h = IntroGameViewportCommand::CENTRE; break; - case 'R': vc.align_h = IntroGameViewportCommand::RIGHT; break; - case 'P': vc.pan_to_next = true; break; - case 'V': id_type = ID_VEHICLE; vc.vehicle = VehicleID::Begin(); break; - } - } - } - - /* Successfully parsed, store. */ - intro_viewport_commands.push_back(vc); - signs_to_delete.push_back(sign->index); + IntroGameViewportCommand vc; + /* Sequence index from the first matching group. */ + if (auto value = ParseInteger(match[1].str()); value.has_value()) { + vc.command_index = *value; + } else { + continue; } + /* Sign coordinates for positioning. */ + vc.position = RemapCoords(sign->x, sign->y, sign->z); + /* Delay from the third matching group. */ + if (auto value = ParseInteger(match[3].str()); value.has_value()) { + vc.delay = *value * 1000; // milliseconds + } else { + continue; + } + + /* Parse flags from second matching group. */ + auto flags = match[2].str(); + StringConsumer consumer{flags}; + while (consumer.AnyBytesLeft()) { + auto c = consumer.ReadUtf8(); + switch (toupper(c)) { + case '-': vc.zoom_adjust = +1; break; + case '+': vc.zoom_adjust = -1; break; + case 'T': vc.align_v = IntroGameViewportCommand::TOP; break; + case 'M': vc.align_v = IntroGameViewportCommand::MIDDLE; break; + case 'B': vc.align_v = IntroGameViewportCommand::BOTTOM; break; + case 'L': vc.align_h = IntroGameViewportCommand::LEFT; break; + case 'C': vc.align_h = IntroGameViewportCommand::CENTRE; break; + case 'R': vc.align_h = IntroGameViewportCommand::RIGHT; break; + case 'P': vc.pan_to_next = true; break; + case 'V': vc.vehicle = static_cast(consumer.ReadIntegerBase(10, VehicleID::Invalid().base())); break; + } + } + + /* Successfully parsed, store. */ + intro_viewport_commands.push_back(vc); + signs_to_delete.push_back(sign->index); } /* Sort the commands by sequence index. */ diff --git a/src/safeguards.h b/src/safeguards.h index 70a272cbf9..34d6de3126 100644 --- a/src/safeguards.h +++ b/src/safeguards.h @@ -59,6 +59,13 @@ #define strtoll SAFEGUARD_DO_NOT_USE_THIS_METHOD #define strtoul SAFEGUARD_DO_NOT_USE_THIS_METHOD #define strtoull SAFEGUARD_DO_NOT_USE_THIS_METHOD +#define stoi SAFEGUARD_DO_NOT_USE_THIS_METHOD +#define stol SAFEGUARD_DO_NOT_USE_THIS_METHOD +#define stoll SAFEGUARD_DO_NOT_USE_THIS_METHOD +#define stoul SAFEGUARD_DO_NOT_USE_THIS_METHOD +#define stoull SAFEGUARD_DO_NOT_USE_THIS_METHOD +#define stoimax SAFEGUARD_DO_NOT_USE_THIS_METHOD +#define stoumax SAFEGUARD_DO_NOT_USE_THIS_METHOD /* Use fmt::print instead. */ #define printf SAFEGUARD_DO_NOT_USE_THIS_METHOD diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 84e65c58b2..0fc8d60b27 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -2863,18 +2863,17 @@ static std::pair GetSavegameFormat(const std::s for (const auto &slf : _saveload_formats) { if (slf.init_write != nullptr && name.compare(slf.name) == 0) { if (has_comp_level) { - const std::string complevel(full_name, separator + 1); + auto complevel = std::string_view(full_name).substr(separator + 1); /* Get the level and determine whether all went fine. */ - size_t processed; - long level = std::stol(complevel, &processed, 10); - if (processed == 0 || level != Clamp(level, slf.min_compression, slf.max_compression)) { + auto level = ParseInteger(complevel); + if (!level.has_value() || *level != Clamp(*level, slf.min_compression, slf.max_compression)) { ShowErrorMessage( GetEncodedString(STR_CONFIG_ERROR), GetEncodedString(STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL, complevel), WL_CRITICAL); } else { - return {slf, ClampTo(level)}; + return {slf, *level}; } } return {slf, slf.default_compression}; diff --git a/src/script/api/script_text.cpp b/src/script/api/script_text.cpp index 8948c1c7f3..4e1c02ea3e 100644 --- a/src/script/api/script_text.cpp +++ b/src/script/api/script_text.cpp @@ -14,6 +14,7 @@ #include "script_text.hpp" #include "script_log.hpp" #include "../script_fatalerror.hpp" +#include "../../core/string_consumer.hpp" #include "../../table/control_codes.h" #include "table/strings.h" @@ -141,7 +142,9 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm) std::string str = StrMakeValid(view); if (!str.starts_with("param_") || str.size() > 8) return SQ_ERROR; - k = stoi(str.substr(6)); + auto key = ParseInteger(str.substr(6)); + if (!key.has_value()) return SQ_ERROR; + k = *key; } else if (sq_gettype(vm, 2) == OT_INTEGER) { SQInteger key; sq_getinteger(vm, 2, &key);