diff --git a/engine/utils/cli_selection_utils.h b/engine/utils/cli_selection_utils.h index a923565f1..20450ef7f 100644 --- a/engine/utils/cli_selection_utils.h +++ b/engine/utils/cli_selection_utils.h @@ -25,12 +25,24 @@ inline void PrintMenu( std::endl(std::cout); } +inline std::optional GetNumericValue(const std::string& sval) { + try { + return std::stoi(sval); + } catch (const std::invalid_argument&) { + // Not a valid number + return std::nullopt; + } catch (const std::out_of_range&) { + // Number out of range + return std::nullopt; + } +} + inline std::optional PrintModelSelection( const std::vector& downloaded, const std::vector& availables, const std::optional default_selection = std::nullopt) { - std::string selection{""}; + std::string selection; if (!downloaded.empty()) { std::cout << "Downloaded models:\n"; for (const auto& option : downloaded) { @@ -60,7 +72,15 @@ inline std::optional PrintModelSelection( return std::nullopt; } - if (std::stoi(selection) > availables.size() || std::stoi(selection) < 1) { + // Validate if the selection consists solely of numeric characters + if(!std::all_of(selection.begin(), selection.end(), ::isdigit)){ + return std::nullopt; + } + + // deal with out of range numeric values + std::optional numeric_value = GetNumericValue(selection); + + if (!numeric_value.has_value() || numeric_value.value() > availables.size() || numeric_value.value() < 1) { return std::nullopt; } @@ -71,7 +91,7 @@ inline std::optional PrintSelection( const std::vector& options, const std::string& title = "Select an option") { std::cout << title << "\n"; - std::string selection{""}; + std::string selection; PrintMenu(options); std::cout << "Select an option (" << 1 << "-" << options.size() << "): "; std::getline(std::cin, selection); @@ -80,7 +100,14 @@ inline std::optional PrintSelection( return std::nullopt; } - if (std::stoi(selection) > options.size() || std::stoi(selection) < 1) { + // Validate if the selection consists solely of numeric characters + if(!std::all_of(selection.begin(), selection.end(), ::isdigit)){ + return std::nullopt; + } + + // deal with out of range numeric values + std::optional numeric_value = GetNumericValue(selection); + if (!numeric_value.has_value() || numeric_value.value() > options.size() || numeric_value.value() < 1) { return std::nullopt; }