From 36299b45306e52de646065bf9a22beb89e4a723b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 12 Jan 2024 17:12:27 +0100 Subject: [PATCH] Fix #12344 (cmdline: better validation of premium options) (#5875) --- cli/cmdlineparser.cpp | 20 ++++++++++++++++++-- test/testcmdlineparser.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index a870c571726..6b6eac98329 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -889,11 +889,26 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a // Special Cppcheck Premium options else if (std::strncmp(argv[i], "--premium=", 10) == 0 && isCppcheckPremium()) { + const std::set valid{ + "autosar", + "cert-c-2016", + "cert-c++-2016", + "misra-c-2012", + "misra-c-2023", + "misra-c++-2008", + "misra-c++-2023", + "bughunting", + "safety"}; + if (std::strcmp(argv[i], "--premium=safety") == 0) mSettings.safety = true; if (!mSettings.premiumArgs.empty()) mSettings.premiumArgs += " "; const std::string p(argv[i] + 10); + if (!valid.count(p) && !startsWith(p, "cert-c-int-precision=")) { + mLogger.printError("invalid --premium option '" + p + "'."); + return Result::Fail; + } mSettings.premiumArgs += "--" + p; if (p == "misra-c-2012" || p == "misra-c-2023") mSettings.addons.emplace("misra"); @@ -1515,10 +1530,11 @@ void CmdLineParser::printHelp() const " * cert-c++-2016 Cert C++ 2016 checking\n" " * misra-c-2012 Misra C 2012\n" " * misra-c-2023 Misra C 2023\n" - " * misra-c++-2008 Misra C++ 2008 (partial)\n" + " * misra-c++-2008 Misra C++ 2008\n" " Other:\n" " * bughunting Soundy analysis\n" - " * cert-c-int-precision=BITS Integer precision to use in Cert C analysis.\n"; + " * cert-c-int-precision=BITS Integer precision to use in Cert C analysis.\n" + " * safety Safe mode\n"; } oss << diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 22bea9219bc..678732b4f37 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -212,6 +212,7 @@ class TestCmdlineParser : public TestFixture { TEST_CASE(maxConfigsMissingCount); TEST_CASE(maxConfigsInvalid); TEST_CASE(maxConfigsTooSmall); + TEST_CASE(premiumOptions); TEST_CASE(premiumSafety); TEST_CASE(reportProgress1); TEST_CASE(reportProgress2); @@ -1186,6 +1187,36 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS("cppcheck: error: argument to '--max-configs=' must be greater than 0.\n", logger->str()); } + void premiumOptions() { + REDIRECT; + settings->cppcheckCfgProductName = "Cppcheck Premium 0.0.0"; + { + const char * const argv[] = {"cppcheck", "--premium=misra-c-2012", "file.c"}; + ASSERT_EQUALS(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv)); + } + { + const char * const argv[] = {"cppcheck", "--premium=misra-c++-2023", "file.c"}; + ASSERT_EQUALS(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv)); + } + { + const char * const argv[] = {"cppcheck", "--premium=cert-c++-2016", "file.c"}; + ASSERT_EQUALS(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv)); + } + // invalid options + { + const char * const argv[] = {"cppcheck", "--premium=misra", "file.c"}; + ASSERT_EQUALS(CmdLineParser::Result::Fail, parser->parseFromArgs(3, argv)); + ASSERT_EQUALS("cppcheck: error: invalid --premium option 'misra'.\n", logger->str()); + } + { + const char * const argv[] = {"cppcheck", "--premium=cert", "file.c"}; + ASSERT_EQUALS(CmdLineParser::Result::Fail, parser->parseFromArgs(3, argv)); + ASSERT_EQUALS("cppcheck: error: invalid --premium option 'cert'.\n", logger->str()); + } + settings->cppcheckCfgProductName.clear(); + settings->premiumArgs.clear(); + } + void premiumSafety() { REDIRECT; const char * const argv[] = {"cppcheck", "--premium=safety", "file.cpp"};