From 85835b15af438964d1bbf4b2cc81b1f148b8acdb Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 27 Jul 2023 13:27:59 +0200 Subject: [PATCH 1/4] CppCheckExecutor: avoid crash when `reportErr()` is called during settings creation --- cli/cppcheckexecutor.cpp | 10 ++++++++-- test/cli/test-other.py | 11 ++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index cb07f3f356e..901b25958d7 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -328,7 +328,7 @@ bool CppCheckExecutor::loadLibraries(Settings& settings) const std::string msg("Failed to load the library " + *failed_lib); const std::list callstack; ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", Certainty::normal); - reportErr(errmsg); + reportErr(errmsg); // TODO: depends on mSettings before they have been set return false; } @@ -346,7 +346,7 @@ bool CppCheckExecutor::loadLibraries(Settings& settings) "should be configured."); #endif ErrorMessage errmsg(callstack, emptyString, Severity::information, msg+" "+details, "failedToLoadCfg", Certainty::normal); - reportErr(errmsg); + reportErr(errmsg); // TODO: depends on mSettings before they have been set return false; } @@ -424,6 +424,12 @@ void CppCheckExecutor::reportErr(const ErrorMessage &msg) return; } + // TODO: workaround for calls during settings creation + if (!mSettings) { + reportOut(msg.toString(false)); + return; + } + // Alert only about unique errors if (!mShownErrors.insert(msg.toString(mSettings->verbose)).second) return; diff --git a/test/cli/test-other.py b/test/cli/test-other.py index 29db8ea0c9f..2d812793238 100644 --- a/test/cli/test-other.py +++ b/test/cli/test-other.py @@ -60,4 +60,13 @@ def test_missing_include_inline_suppr(tmpdir): args = ['--enable=missingInclude', '--inline-suppr', test_file] _, _, stderr = cppcheck(args) - assert stderr == '' \ No newline at end of file + assert stderr == '' + +def test_invalid_library(tmpdir): + args = ['--library=none', '--library=posix', '--library=none2', 'file.c'] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 1 + assert (stdout == "cppcheck: Failed to load library configuration file 'none'. File not found\n" + '(information) Failed to load the library none\n') + assert stderr == "" \ No newline at end of file From 7c5a6391af61f871ee9857b63a5eb5fbe4f79e05 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 27 Jul 2023 13:36:04 +0200 Subject: [PATCH 2/4] CppCheckExecutor: removed premature `reportErr()` calls / added TODO --- cli/cppcheckexecutor.cpp | 17 +++++------------ test/cli/test-other.py | 7 ++++--- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 901b25958d7..5de290ac61b 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -43,6 +43,7 @@ #endif #include +#include #include #include // EXIT_SUCCESS and EXIT_FAILURE #include @@ -66,6 +67,8 @@ #include #endif +// TODO: do not directly write to stdout + /*static*/ FILE* CppCheckExecutor::mExceptionOutput = stdout; @@ -325,15 +328,10 @@ bool CppCheckExecutor::loadLibraries(Settings& settings) return !tryLoadLibrary(settings.library, settings.exename, lib.c_str()); }); if (failed_lib != settings.libraries.end()) { - const std::string msg("Failed to load the library " + *failed_lib); - const std::list callstack; - ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", Certainty::normal); - reportErr(errmsg); // TODO: depends on mSettings before they have been set return false; } if (!std) { - const std::list callstack; const std::string msg("Failed to load std.cfg. Your Cppcheck installation is broken, please re-install."); #ifdef FILESDIR const std::string details("The Cppcheck binary was compiled with FILESDIR set to \"" @@ -345,8 +343,7 @@ bool CppCheckExecutor::loadLibraries(Settings& settings) "std.cfg should be available in " + cfgfolder + " or the FILESDIR " "should be configured."); #endif - ErrorMessage errmsg(callstack, emptyString, Severity::information, msg+" "+details, "failedToLoadCfg", Certainty::normal); - reportErr(errmsg); // TODO: depends on mSettings before they have been set + std::cout << msg << " " << details << std::endl; return false; } @@ -424,11 +421,7 @@ void CppCheckExecutor::reportErr(const ErrorMessage &msg) return; } - // TODO: workaround for calls during settings creation - if (!mSettings) { - reportOut(msg.toString(false)); - return; - } + assert(mSettings != nullptr); // Alert only about unique errors if (!mShownErrors.insert(msg.toString(mSettings->verbose)).second) diff --git a/test/cli/test-other.py b/test/cli/test-other.py index 2d812793238..9ab57189109 100644 --- a/test/cli/test-other.py +++ b/test/cli/test-other.py @@ -67,6 +67,7 @@ def test_invalid_library(tmpdir): exitcode, stdout, stderr = cppcheck(args) assert exitcode == 1 - assert (stdout == "cppcheck: Failed to load library configuration file 'none'. File not found\n" - '(information) Failed to load the library none\n') - assert stderr == "" \ No newline at end of file + assert (stdout == "cppcheck: Failed to load library configuration file 'none'. File not found\n") + assert stderr == "" + +# TODO: test missing std.cfg \ No newline at end of file From 2b0610724291aa9d8a6ad547ab126866758424d1 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 27 Jul 2023 16:57:53 +0200 Subject: [PATCH 3/4] CppCheckExecutor: report all library loading failures at once --- cli/cppcheckexecutor.cpp | 19 ++++++++----------- test/cli/test-other.py | 3 ++- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 5de290ac61b..66b44bae141 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -322,16 +322,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) bool CppCheckExecutor::loadLibraries(Settings& settings) { - const bool std = tryLoadLibrary(settings.library, settings.exename, "std.cfg"); - - const auto failed_lib = std::find_if(settings.libraries.begin(), settings.libraries.end(), [&](const std::string& lib) { - return !tryLoadLibrary(settings.library, settings.exename, lib.c_str()); - }); - if (failed_lib != settings.libraries.end()) { - return false; - } - - if (!std) { + if (!tryLoadLibrary(settings.library, settings.exename, "std.cfg")) { const std::string msg("Failed to load std.cfg. Your Cppcheck installation is broken, please re-install."); #ifdef FILESDIR const std::string details("The Cppcheck binary was compiled with FILESDIR set to \"" @@ -347,7 +338,13 @@ bool CppCheckExecutor::loadLibraries(Settings& settings) return false; } - return true; + bool result = true; + for (const auto& lib : settings.libraries) { + if (!tryLoadLibrary(settings.library, settings.exename, lib.c_str())) { + result = false; + } + } + return result; } #ifdef _WIN32 diff --git a/test/cli/test-other.py b/test/cli/test-other.py index 9ab57189109..519b307ae47 100644 --- a/test/cli/test-other.py +++ b/test/cli/test-other.py @@ -67,7 +67,8 @@ def test_invalid_library(tmpdir): exitcode, stdout, stderr = cppcheck(args) assert exitcode == 1 - assert (stdout == "cppcheck: Failed to load library configuration file 'none'. File not found\n") + assert (stdout == "cppcheck: Failed to load library configuration file 'none'. File not found\n" + "cppcheck: Failed to load library configuration file 'none2'. File not found\n") assert stderr == "" # TODO: test missing std.cfg \ No newline at end of file From aec5bcaf6675a071bad16d5d1ad64346ba543719 Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 1 Aug 2023 18:59:54 +0200 Subject: [PATCH 4/4] test/cli/test-other.py: avoid deprecation warning on Windows --- test/cli/test-other.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cli/test-other.py b/test/cli/test-other.py index 519b307ae47..d1e329434a1 100644 --- a/test/cli/test-other.py +++ b/test/cli/test-other.py @@ -63,7 +63,7 @@ def test_missing_include_inline_suppr(tmpdir): assert stderr == '' def test_invalid_library(tmpdir): - args = ['--library=none', '--library=posix', '--library=none2', 'file.c'] + args = ['--library=none', '--library=posix', '--library=none2', '--platform=native', 'file.c'] exitcode, stdout, stderr = cppcheck(args) assert exitcode == 1