From 878803ccfa7e7495d09b14769ef212ccf4d9a37c Mon Sep 17 00:00:00 2001 From: Roushan Kumar Singh <158602016+github-roushan@users.noreply.github.com> Date: Tue, 25 Feb 2025 15:24:02 +0530 Subject: [PATCH 1/2] feat: implement input validation to allow only valid numeric selections --- engine/utils/cli_selection_utils.h | 35 ++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/engine/utils/cli_selection_utils.h b/engine/utils/cli_selection_utils.h index a923565f1..1ac241043 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(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; } From 90ed7c27f79e48881e75b74b251f37d5de0d81f0 Mon Sep 17 00:00:00 2001 From: Roushan Singh Date: Thu, 27 Feb 2025 18:36:12 +0530 Subject: [PATCH 2/2] chore:refactor function name to follow coding conventions --- engine/utils/cli_selection_utils.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engine/utils/cli_selection_utils.h b/engine/utils/cli_selection_utils.h index 1ac241043..20450ef7f 100644 --- a/engine/utils/cli_selection_utils.h +++ b/engine/utils/cli_selection_utils.h @@ -25,7 +25,7 @@ inline void PrintMenu( std::endl(std::cout); } -inline std::optional getNumericValue(std::string& sval) { +inline std::optional GetNumericValue(const std::string& sval) { try { return std::stoi(sval); } catch (const std::invalid_argument&) { @@ -78,7 +78,7 @@ inline std::optional PrintModelSelection( } // deal with out of range numeric values - std::optional numeric_value = getNumericValue(selection); + std::optional numeric_value = GetNumericValue(selection); if (!numeric_value.has_value() || numeric_value.value() > availables.size() || numeric_value.value() < 1) { return std::nullopt; @@ -106,7 +106,7 @@ inline std::optional PrintSelection( } // deal with out of range numeric values - std::optional numeric_value = getNumericValue(selection); + std::optional numeric_value = GetNumericValue(selection); if (!numeric_value.has_value() || numeric_value.value() > options.size() || numeric_value.value() < 1) { return std::nullopt; }