From 0d4e9d8e823520e26d5ded0bda05b9e5c187909b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 6 Mar 2026 16:22:32 +0100 Subject: [PATCH 1/7] Fix #14577 (Checkers report: unsigned integer overflow can lead to huge string) --- lib/checkersreport.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/checkersreport.cpp b/lib/checkersreport.cpp index 59b3cf99495..e94e5c3e1d7 100644 --- a/lib/checkersreport.cpp +++ b/lib/checkersreport.cpp @@ -209,13 +209,20 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const fout << title << std::endl; fout << std::string(title.size(), '-') << std::endl; + maxCheckerSize = 0; + for (const auto& checkReq: addonInfo.checkers) { + const std::string& checker = checkReq.first; + if (maxCheckerSize < checker.size()) + maxCheckerSize = checker.size(); + } + for (const auto& checkReq: addonInfo.checkers) { const std::string& checker = checkReq.first; const bool active = mActiveCheckers.count(checkReq.first) > 0; const std::string& req = checkReq.second; fout << (active ? "Yes " : "No ") << checker; if (!active && !req.empty()) - fout << std::string(maxCheckerSize + 4 - checker.size(), ' ') << "require:" + req; + fout << std::string(maxCheckerSize + 4 - checker.size(), ' ') << "require:" << req; fout << std::endl; } } From b38ad627701e348f06b5cc747a46d3e07bcbd40e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 6 Mar 2026 16:58:21 +0100 Subject: [PATCH 2/7] test --- Makefile | 4 ++++ test/testrunner.vcxproj | 1 + 2 files changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 37156d357af..7dd1228a0d7 100644 --- a/Makefile +++ b/Makefile @@ -294,6 +294,7 @@ TESTOBJ = test/fixture.o \ test/testbufferoverrun.o \ test/testcharvar.o \ test/testcheck.o \ + test/testcheckersreport.o \ test/testclangimport.o \ test/testclass.o \ test/testcmdlineparser.o \ @@ -757,6 +758,9 @@ test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checker test/testcheck.o: test/testcheck.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheck.cpp +test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheckersreport.cpp + test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp diff --git a/test/testrunner.vcxproj b/test/testrunner.vcxproj index cd7a039c418..1c5230c5535 100755 --- a/test/testrunner.vcxproj +++ b/test/testrunner.vcxproj @@ -53,6 +53,7 @@ + From 2672481fe844e5c93156dbd770e59cf01216b6be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 6 Mar 2026 17:00:28 +0100 Subject: [PATCH 3/7] testcheckersreport.cpp --- test/testcheckersreport.cpp | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 test/testcheckersreport.cpp diff --git a/test/testcheckersreport.cpp b/test/testcheckersreport.cpp new file mode 100644 index 00000000000..acbdc12841b --- /dev/null +++ b/test/testcheckersreport.cpp @@ -0,0 +1,57 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2025 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "checkersreport.h" +#include "fixture.h" +#include "helpers.h" +#include "settings.h" + +#include + +class TestCheckersReport : public TestFixture { +public: + TestCheckersReport() : TestFixture("TestCheckersReport") {} + + + void run() final { + // AddonInfo::checkers + TEST_CASE(addonInfoCheckers); + } + + void addonInfoCheckers() { + AddonInfo a; + a.name = "test"; + a.checkers["abcdefghijklmnopqrstuvwxyz::abcdefghijklmnopqrstuvwxyz"] = "123"; + Settings s; + s.addonInfos.emplace_back(a); + CheckersReport r(s, {}); + const std::string report = r.getReport(""); + const auto pos = report.rfind("\n\n"); + ASSERT(pos != std::string::npos); + + const char expected[] = + "test checkers\n" + "-------------\n" + "No abcdefghijklmnopqrstuvwxyz::abcdefghijklmnopqrstuvwxyz require:123\n"; + + ASSERT_EQUALS(expected, report.substr(pos+2)); + } +}; + +REGISTER_TEST(TestCheckersReport) From b50596b0849f7fce11cf79bb2864b3693fb1d28b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 6 Mar 2026 21:36:26 +0100 Subject: [PATCH 4/7] runformat --- test/testcheckersreport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testcheckersreport.cpp b/test/testcheckersreport.cpp index acbdc12841b..7af909278b2 100644 --- a/test/testcheckersreport.cpp +++ b/test/testcheckersreport.cpp @@ -45,7 +45,7 @@ class TestCheckersReport : public TestFixture { const auto pos = report.rfind("\n\n"); ASSERT(pos != std::string::npos); - const char expected[] = + const char expected[] = "test checkers\n" "-------------\n" "No abcdefghijklmnopqrstuvwxyz::abcdefghijklmnopqrstuvwxyz require:123\n"; From d9cf79387ea285c8c0a1a0f9b75543804d0511ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 7 Mar 2026 07:02:47 +0100 Subject: [PATCH 5/7] selfcheck --- test/testcheckersreport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testcheckersreport.cpp b/test/testcheckersreport.cpp index 7af909278b2..e005a6bc69e 100644 --- a/test/testcheckersreport.cpp +++ b/test/testcheckersreport.cpp @@ -34,7 +34,7 @@ class TestCheckersReport : public TestFixture { TEST_CASE(addonInfoCheckers); } - void addonInfoCheckers() { + void addonInfoCheckers() const { AddonInfo a; a.name = "test"; a.checkers["abcdefghijklmnopqrstuvwxyz::abcdefghijklmnopqrstuvwxyz"] = "123"; From d97c92cf592df5424ff65728c5b3001de4d1a642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 10 Mar 2026 14:36:08 +0100 Subject: [PATCH 6/7] clang-tidy --- lib/checkersreport.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/checkersreport.cpp b/lib/checkersreport.cpp index e94e5c3e1d7..0bbe02f3d7b 100644 --- a/lib/checkersreport.cpp +++ b/lib/checkersreport.cpp @@ -212,8 +212,7 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const maxCheckerSize = 0; for (const auto& checkReq: addonInfo.checkers) { const std::string& checker = checkReq.first; - if (maxCheckerSize < checker.size()) - maxCheckerSize = checker.size(); + maxCheckerSize = std::max(checker.size(), maxCheckerSize); } for (const auto& checkReq: addonInfo.checkers) { From 4afe4fd5d47fdec6cbdffbac272c15d56361fe66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 10 Mar 2026 14:46:08 +0100 Subject: [PATCH 7/7] crash --- test/testcheckersreport.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/testcheckersreport.cpp b/test/testcheckersreport.cpp index e005a6bc69e..2d539ee77cf 100644 --- a/test/testcheckersreport.cpp +++ b/test/testcheckersreport.cpp @@ -40,7 +40,8 @@ class TestCheckersReport : public TestFixture { a.checkers["abcdefghijklmnopqrstuvwxyz::abcdefghijklmnopqrstuvwxyz"] = "123"; Settings s; s.addonInfos.emplace_back(a); - CheckersReport r(s, {}); + const std::set activeCheckers; + CheckersReport r(s, activeCheckers); const std::string report = r.getReport(""); const auto pos = report.rfind("\n\n"); ASSERT(pos != std::string::npos);