summaryrefslogtreecommitdiffstats
path: root/Source/cmForEachCommand.cxx
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2020-02-27 18:51:09 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2020-02-27 19:52:06 (GMT)
commita33b3949e5337da978828d611f3ca3f08bcda21b (patch)
tree8fcb374c3a5e20596f3c9135160a9698cf1777cc /Source/cmForEachCommand.cxx
parent813b28902320831c0a668d1a6dc30817c87c73c3 (diff)
downloadCMake-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.cxx41
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) {