diff --git a/CVE-2023-39070.patch b/CVE-2023-39070.patch deleted file mode 100644 index 27dd297..0000000 --- a/CVE-2023-39070.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 76695f6be2685a1ee7436e563bc550eab506952a Mon Sep 17 00:00:00 2001 -From: Dirk Mueller -Date: Tue, 19 Dec 2023 20:44:22 +0100 -Subject: [PATCH] Fix #12272 (removeContradiction() Avoid use-after-free on - multiple remove) (#5707) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -As reported in -https://sourceforge.net/p/cppcheck/discussion/general/thread/fa43fb8ab1/ -removeContradiction() minValue/maxValue.remove(..) can access free'd -memory as it removes all matching values by iterating over the complete -list. Creating a full copy instead of a reference avoids this issue. - -Signed-off-by: Dirk Müller ---- - lib/preprocessor.cpp | 16 +++++++----- - lib/token.cpp | 60 +++++++++++++++++++++++--------------------- - 2 files changed, 42 insertions(+), 34 deletions(-) - -Index: cppcheck-2.12.1/lib/token.cpp -=================================================================== ---- cppcheck-2.12.1.orig/lib/token.cpp -+++ cppcheck-2.12.1/lib/token.cpp -@@ -1955,64 +1955,68 @@ static bool isAdjacent(const ValueFlow:: - return std::abs(x.intvalue - y.intvalue) == 1; - } - --static bool removePointValue(std::list& values, ValueFlow::Value& x) -+static bool removePointValue(std::list& values, std::list::iterator& x) - { -- const bool isPoint = x.bound == ValueFlow::Value::Bound::Point; -+ const bool isPoint = x->bound == ValueFlow::Value::Bound::Point; - if (!isPoint) -- x.decreaseRange(); -+ x->decreaseRange(); - else -- values.remove(x); -+ x = values.erase(x); - return isPoint; - } - - static bool removeContradiction(std::list& values) - { - bool result = false; -- for (ValueFlow::Value& x : values) { -- if (x.isNonValue()) -+ for (auto itx = values.begin(); itx != values.end(); ++itx) { -+ if (itx->isNonValue()) - continue; -- for (ValueFlow::Value& y : values) { -- if (y.isNonValue()) -+ -+ auto ity = itx; -+ ++ity; -+ for (; ity != values.end(); ++ity) { -+ if (ity->isNonValue()) - continue; -- if (x == y) -+ if (*itx == *ity) - continue; -- if (x.valueType != y.valueType) -+ if (itx->valueType != ity->valueType) - continue; -- if (x.isImpossible() == y.isImpossible()) -+ if (itx->isImpossible() == ity->isImpossible()) - continue; -- if (x.isSymbolicValue() && !ValueFlow::Value::sameToken(x.tokvalue, y.tokvalue)) -+ if (itx->isSymbolicValue() && !ValueFlow::Value::sameToken(itx->tokvalue, ity->tokvalue)) - continue; -- if (!x.equalValue(y)) { -- auto compare = [](const ValueFlow::Value& x, const ValueFlow::Value& y) { -- return x.compareValue(y, less{}); -+ if (!itx->equalValue(*ity)) { -+ auto compare = [](const std::list::const_iterator& x, const std::list::const_iterator& y) { -+ return x->compareValue(*y, less{}); - }; -- const ValueFlow::Value& maxValue = std::max(x, y, compare); -- const ValueFlow::Value& minValue = std::min(x, y, compare); -+ auto itMax = std::max(itx, ity, compare); -+ auto itMin = std::min(itx, ity, compare); - // TODO: Adjust non-points instead of removing them -- if (maxValue.isImpossible() && maxValue.bound == ValueFlow::Value::Bound::Upper) { -- values.remove(minValue); -+ if (itMax->isImpossible() && itMax->bound == ValueFlow::Value::Bound::Upper) { -+ values.erase(itMin); - return true; - } -- if (minValue.isImpossible() && minValue.bound == ValueFlow::Value::Bound::Lower) { -- values.remove(maxValue); -+ if (itMin->isImpossible() && itMin->bound == ValueFlow::Value::Bound::Lower) { -+ values.erase(itMax); - return true; - } - continue; - } -- const bool removex = !x.isImpossible() || y.isKnown(); -- const bool removey = !y.isImpossible() || x.isKnown(); -- if (x.bound == y.bound) { -+ const bool removex = !itx->isImpossible() || ity->isKnown(); -+ const bool removey = !ity->isImpossible() || itx->isKnown(); -+ if (itx->bound == ity->bound) { - if (removex) -- values.remove(x); -+ values.erase(itx); - if (removey) -- values.remove(y); -+ values.erase(ity); -+ // itx and ity are invalidated - return true; - } - result = removex || removey; - bool bail = false; -- if (removex && removePointValue(values, x)) -+ if (removex && removePointValue(values, itx)) - bail = true; -- if (removey && removePointValue(values, y)) -+ if (removey && removePointValue(values, ity)) - bail = true; - if (bail) - return true; diff --git a/cppcheck-2.12.1.tar.gz b/cppcheck-2.12.1.tar.gz deleted file mode 100644 index af17852..0000000 --- a/cppcheck-2.12.1.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2a3d4ba1179419612183ab3d6aed6d3b18be75e98cd6f138ea8e2020905dced2 -size 3579702 diff --git a/cppcheck-2.13.0.tar.gz b/cppcheck-2.13.0.tar.gz new file mode 100644 index 0000000..c8bf4d7 --- /dev/null +++ b/cppcheck-2.13.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8229afe1dddc3ed893248b8a723b428dc221ea014fbc76e6289840857c03d450 +size 3643744 diff --git a/cppcheck.changes b/cppcheck.changes index 10c3c20..1f3ffb0 100644 --- a/cppcheck.changes +++ b/cppcheck.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Sun Dec 24 06:43:54 UTC 2023 - Christoph G + +- update to 2.13.0 + * newCheck passedByValueCallback for functions which take a + parameter by value but are used as callbacks + * newCheck returnImplicitInt for C functions without return type + * newCheck iterateByValue for iterating by value in a range-based + for loop when a const reference could be used +- Drop patches werror-return-type.patch, eb076d87.patch, and + CVE-2023-39070.patch which are part of upstream or fixed in a + similar way. + ------------------------------------------------------------------- Wed Dec 20 23:14:07 UTC 2023 - Dirk Müller diff --git a/cppcheck.spec b/cppcheck.spec index 8e4150c..8488b24 100644 --- a/cppcheck.spec +++ b/cppcheck.spec @@ -17,15 +17,12 @@ Name: cppcheck -Version: 2.12.1 +Version: 2.13.0 Release: 0 Summary: A tool for static C/C++ code analysis License: GPL-3.0-or-later URL: https://github.com/danmar/cppcheck Source: https://github.com/danmar/cppcheck/archive/refs/tags/%{version}.tar.gz#/%{name}-%{version}.tar.gz -Patch0: eb076d87.patch -Patch1: werror-return-type.patch -Patch2: CVE-2023-39070.patch BuildRequires: cmake BuildRequires: docbook-xsl-stylesheets BuildRequires: fdupes diff --git a/eb076d87.patch b/eb076d87.patch deleted file mode 100644 index 3190da3..0000000 --- a/eb076d87.patch +++ /dev/null @@ -1,73 +0,0 @@ -From eb076d877b48c09d5c34cad27b001d18971fde3f Mon Sep 17 00:00:00 2001 -From: moui0 <69300707+moui0@users.noreply.github.com> -Date: Sun, 8 Oct 2023 05:04:57 +0800 -Subject: [PATCH] Improve testcases for unsigned char platforms (#5524) - -I got error messages while building `cppcheck 2.12.0` for RISC-V Arch -Linux: -``` -Testing Complete -Number of tests: 4420 -Number of todos: 331 -Tests failed: 2 - -/usr/src/debug/cppcheck/cppcheck/test/testcondition.cpp:4501(TestCondition::alwaysTrue): Assertion failed. -Expected: -[test.cpp:6]: (style) Condition 'o[1]=='\0'' is always false\n - -Actual: -[test.cpp:4] -> [test.cpp:6]: (style) Condition 'o[1]=='\0'' is always false\n - -_____ -/usr/src/debug/cppcheck/cppcheck/test/testcondition.cpp:5014(TestCondition::alwaysTrueContainer): Assertion failed. -Expected: -[test.cpp:5]: (style) Condition 'buffer.back()=='\0'' is always false\n - -Actual: -[test.cpp:3] -> [test.cpp:5]: (style) Condition 'buffer.back()=='\0'' is always false\n -``` - -I found out the reason is that the testcases were designed for -x86/x86_64 or other `signed char` platforms (i.e. default character type -is `signed char` ), whereareas RISC-V is an `unsigned char` platform, -which causes different behavior in -`lib/valueflow.cpp:valueFlowImpossibleValues`. I'm not sure whether this -error leads from a functional bug, so if you have a better approach to -fix it, please let me know. - -Maybe you could reproduce this error on x86_64 platform by setting -`defaultSign = 'u';` in `Platform::set(Type t)`. ---- - test/testcondition.cpp | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/test/testcondition.cpp b/test/testcondition.cpp -index bfe9713fce3..ae9dfdb7a61 100644 ---- a/test/testcondition.cpp -+++ b/test/testcondition.cpp -@@ -4498,7 +4498,11 @@ class TestCondition : public TestFixture { - " if (o[1] == '\\0') {}\n" - " }\n" - "}\n"); -- ASSERT_EQUALS("[test.cpp:6]: (style) Condition 'o[1]=='\\0'' is always false\n", errout.str()); -+ if (std::numeric_limits::is_signed) { -+ ASSERT_EQUALS("[test.cpp:6]: (style) Condition 'o[1]=='\\0'' is always false\n", errout.str()); -+ } else { -+ ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (style) Condition 'o[1]=='\\0'' is always false\n", errout.str()); -+ } - - check("void f(int x) {\n" // #11449 - " int i = x;\n" -@@ -5016,7 +5020,11 @@ class TestCondition : public TestFixture { - " buffer.back() == '\\n' ||\n" - " buffer.back() == '\\0') {}\n" - "}\n"); -- ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'buffer.back()=='\\0'' is always false\n", errout.str()); -+ if (std::numeric_limits::is_signed) { -+ ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'buffer.back()=='\\0'' is always false\n", errout.str()); -+ } else { -+ ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (style) Condition 'buffer.back()=='\\0'' is always false\n", errout.str()); -+ } - - // #9353 - check("typedef struct { std::string s; } X;\n" diff --git a/werror-return-type.patch b/werror-return-type.patch deleted file mode 100644 index 9ead976..0000000 --- a/werror-return-type.patch +++ /dev/null @@ -1,35 +0,0 @@ -Index: cppcheck-2.12.0/lib/keywords.cpp -=================================================================== ---- cppcheck-2.12.0.orig/lib/keywords.cpp -+++ cppcheck-2.12.0/lib/keywords.cpp -@@ -165,6 +166,7 @@ const std::unordered_set& K - return c23_keywords_all;*/ - } - assert(false && "unreachable"); -+ __builtin_unreachable(); - } - - // cppcheck-suppress unusedFunction -@@ -185,6 +187,7 @@ const std::unordered_set& K - return cpp23_keywords_all; - } - assert(false && "unreachable"); -+ __builtin_unreachable(); - } - - // cppcheck-suppress unusedFunction -@@ -202,6 +205,7 @@ const std::unordered_set& K - return c23_keywords_all;*/ - } - assert(false && "unreachable"); -+ __builtin_unreachable(); - } - - // cppcheck-suppress unusedFunction -@@ -223,5 +227,6 @@ const std::unordered_set& K - return cpp23_keywords; - } - assert(false && "unreachable"); -+ __builtin_unreachable(); - } -