diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2020-02-27 18:51:09 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2020-02-27 19:52:06 (GMT) |
commit | a33b3949e5337da978828d611f3ca3f08bcda21b (patch) | |
tree | 8fcb374c3a5e20596f3c9135160a9698cf1777cc /Source/cmForEachCommand.cxx | |
parent | 813b28902320831c0a668d1a6dc30817c87c73c3 (diff) | |
download | CMake-a33b3949e5337da978828d611f3ca3f08bcda21b.zip CMake-a33b3949e5337da978828d611f3ca3f08bcda21b.tar.gz CMake-a33b3949e5337da978828d611f3ca3f08bcda21b.tar.bz2 |
foreach: Fix crash when parsing invalid integer
Fixes: #20393
Diffstat (limited to 'Source/cmForEachCommand.cxx')
-rw-r--r-- | Source/cmForEachCommand.cxx | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index ac48287..08e51ad 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -12,6 +12,8 @@ #include <cstdlib> #include <iterator> #include <map> +#include <sstream> +#include <stdexcept> #include <utility> #include <cm/memory> @@ -354,6 +356,21 @@ bool HandleInMode(std::vector<std::string> const& args, return true; } +bool TryParseInteger(cmExecutionStatus& status, const std::string& str, int& i) +{ + try { + i = std::stoi(str); + } catch (std::invalid_argument&) { + std::ostringstream e; + e << "Invalid integer: '" << str << "'"; + status.SetError(e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + + return true; +} + } // anonymous namespace bool cmForEachCommand(std::vector<std::string> const& args, @@ -376,16 +393,28 @@ bool cmForEachCommand(std::vector<std::string> const& args, int stop = 0; int step = 0; if (args.size() == 3) { - stop = std::stoi(args[2]); + if (!TryParseInteger(status, args[2], stop)) { + return false; + } } if (args.size() == 4) { - start = std::stoi(args[2]); - stop = std::stoi(args[3]); + if (!TryParseInteger(status, args[2], start)) { + return false; + } + if (!TryParseInteger(status, args[3], stop)) { + return false; + } } if (args.size() == 5) { - start = std::stoi(args[2]); - stop = std::stoi(args[3]); - step = std::stoi(args[4]); + if (!TryParseInteger(status, args[2], start)) { + return false; + } + if (!TryParseInteger(status, args[3], stop)) { + return false; + } + if (!TryParseInteger(status, args[4], step)) { + return false; + } } if (step == 0) { if (start > stop) { |