From 7217af55da2932fea518b6074eead127a41e95f3 Mon Sep 17 00:00:00 2001 From: Martin Duffy Date: Tue, 5 May 2026 01:42:38 -0400 Subject: [PATCH 1/4] pvs-studio: (V555) Clarify size_type comparison The expression 'r - l > 0' implies a sign to r and l that does not exist. --- .pvsconfig | 2 -- Source/cmStringReplaceHelper.cxx | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.pvsconfig b/.pvsconfig index 4d7413f0b4..ae3091a1fd 100644 --- a/.pvsconfig +++ b/.pvsconfig @@ -14,8 +14,6 @@ //-V::539 # Expression is always true/false. //-V::547 -# Expression of the 'A - B > 0' kind will work as 'A != B'. -//-V::555 # Possible array overrun. //-V::557 # Part of conditional expression is always true/false. diff --git a/Source/cmStringReplaceHelper.cxx b/Source/cmStringReplaceHelper.cxx index 0e1845776e..8ccc094b8d 100644 --- a/Source/cmStringReplaceHelper.cxx +++ b/Source/cmStringReplaceHelper.cxx @@ -93,7 +93,7 @@ void cmStringReplaceHelper::ParseReplaceExpression() this->Replacements.emplace_back( this->ReplaceExpression.substr(l, r - l)); } else { - if (r - l > 0) { + if (r != l) { this->Replacements.emplace_back( this->ReplaceExpression.substr(l, r - l)); } -- GitLab From a77b7aa836897944b9944b000afb0561e6c921cc Mon Sep 17 00:00:00 2001 From: Martin Duffy Date: Tue, 5 May 2026 01:43:23 -0400 Subject: [PATCH 2/4] pvs-studio: (V557) Harden array boundary checks Tighten array boundary checks to prevent possible overrun. --- .pvsconfig | 2 +- Source/bindexplib.cxx | 2 +- Source/cmStringReplaceHelper.cxx | 2 +- Source/cmTargetPropCommandBase.cxx | 9 ++++++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.pvsconfig b/.pvsconfig index ae3091a1fd..70fdcde8a9 100644 --- a/.pvsconfig +++ b/.pvsconfig @@ -14,7 +14,7 @@ //-V::539 # Expression is always true/false. //-V::547 -# Possible array overrun. +# Array underrun/overrun is possible. //-V::557 # Part of conditional expression is always true/false. //-V::560 diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index 59680aa4fd..b43ac0fd1f 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx @@ -391,7 +391,7 @@ static bool DumpFileWithLlvmNm(std::string const& nmPath, char const* filename, line.c_str()); return false; } - if (line.size() < sym_end + 1) { + if (line.size() < sym_end) { fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n", line.c_str()); return false; diff --git a/Source/cmStringReplaceHelper.cxx b/Source/cmStringReplaceHelper.cxx index 8ccc094b8d..aa00907435 100644 --- a/Source/cmStringReplaceHelper.cxx +++ b/Source/cmStringReplaceHelper.cxx @@ -93,7 +93,7 @@ void cmStringReplaceHelper::ParseReplaceExpression() this->Replacements.emplace_back( this->ReplaceExpression.substr(l, r - l)); } else { - if (r != l) { + if (r > l) { this->Replacements.emplace_back( this->ReplaceExpression.substr(l, r - l)); } diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 960e36cf40..aa3975f316 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -81,14 +81,16 @@ bool cmTargetPropCommandBase::HandleArguments( } bool prepend = false; - if ((flags & PROCESS_BEFORE) && args[argIndex] == "BEFORE") { + if ((flags & PROCESS_BEFORE) && argIndex < args.size() && + args[argIndex] == "BEFORE") { if (args.size() < 3) { this->SetError("called with incorrect number of arguments"); return false; } prepend = true; ++argIndex; - } else if ((flags & PROCESS_AFTER) && args[argIndex] == "AFTER") { + } else if ((flags & PROCESS_AFTER) && argIndex < args.size() && + args[argIndex] == "AFTER") { if (args.size() < 3) { this->SetError("called with incorrect number of arguments"); return false; @@ -97,7 +99,8 @@ bool cmTargetPropCommandBase::HandleArguments( ++argIndex; } - if ((flags & PROCESS_REUSE_FROM) && args[argIndex] == "REUSE_FROM") { + if ((flags & PROCESS_REUSE_FROM) && argIndex < args.size() && + args[argIndex] == "REUSE_FROM") { if (args.size() != 3) { this->SetError("called with incorrect number of arguments"); return false; -- GitLab From 77b874baa88a53fefb1b29de7b60d733f04e764a Mon Sep 17 00:00:00 2001 From: Martin Duffy Date: Mon, 18 May 2026 01:47:54 -0400 Subject: [PATCH 3/4] pvs-studio: (V1086) Fix buffer writes Replace space-filling memset calls with bounded character initialization that preserves null termination for the curses help text buffers. --- .pvsconfig | 2 -- Source/CursesDialog/cmCursesMainForm.cxx | 12 ++++++++---- Tests/CMakeLib/testUVStreambuf.cxx | 3 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.pvsconfig b/.pvsconfig index 70fdcde8a9..df665de4df 100644 --- a/.pvsconfig +++ b/.pvsconfig @@ -88,8 +88,6 @@ //-V::1071 # Conditional initialization inside the constructor may leave some members uninitialized. //-V::1077 -# Call of the 'Foo' function will lead to buffer underflow. -//-V::1086 # Waiting on condition variable without predicate. A thread can wait indefinitely or experience a spurious wake-up. //-V::1089 # The 'emplace' / 'insert' function call contains potentially dangerous move operation. Moved object can be destroyed even if there is no insertion. diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index 6b465c1512..74089e528a 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -314,9 +314,12 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */) char secondLine[512] = ""; char thirdLine[512] = ""; if (process) { - memset(firstLine, ' ', 68); - memset(secondLine, ' ', 68); - memset(thirdLine, ' ', 68); + std::fill_n(firstLine, 68, ' '); + firstLine[68] = '\0'; + std::fill_n(secondLine, 68, ' '); + secondLine[68] = '\0'; + std::fill_n(thirdLine, 68, ' '); + thirdLine[68] = '\0'; } else { if (this->OkToGenerate) { snprintf(firstLine, sizeof(firstLine), @@ -340,7 +343,8 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */) move(y - 4, 0); char fmt[512] = "Keys: [enter] Edit an entry [d] Delete an entry"; if (process) { - memset(fmt, ' ', 57); + std::fill_n(fmt, 57, ' '); + fmt[57] = '\0'; } printw(fmt_s, fmt); move(y - 3, 0); diff --git a/Tests/CMakeLib/testUVStreambuf.cxx b/Tests/CMakeLib/testUVStreambuf.cxx index a901ab2ad2..54a65c8280 100644 --- a/Tests/CMakeLib/testUVStreambuf.cxx +++ b/Tests/CMakeLib/testUVStreambuf.cxx @@ -246,7 +246,8 @@ static bool testUVStreambufRead( << std::endl; goto end; } - if (std::memcmp(inputData.data(), outputData, 64)) { + if (std::memcmp(inputData.data(), outputData, //-V1086 Ignore underflow + 64)) { std::cout << "Read data does not match write data" << std::endl; goto end; } -- GitLab From e2f4b9bedcfbec39dde8f0a4d0fb52c80168aef8 Mon Sep 17 00:00:00 2001 From: Martin Duffy Date: Mon, 18 May 2026 02:07:53 -0400 Subject: [PATCH 4/4] pvs-studio: (V522) Prevent possible null-pointer dereference in RemoveRPathELF --- .pvsconfig | 2 -- Source/cmSystemTools.cxx | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.pvsconfig b/.pvsconfig index df665de4df..2cb7888fa0 100644 --- a/.pvsconfig +++ b/.pvsconfig @@ -6,8 +6,6 @@ //-V::508 # The 'x' variable is assigned values twice successively. Perhaps this is a mistake. //-V::519 -# Possible null pointer dereference. -//-V::522 # Constant value is represented by an octal form. //-V::536 # Iterators are passed as arguments to 'Foo' function. Consider inspecting the expression. diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 79767575ea..d7a71f04a6 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -3889,7 +3889,8 @@ static cm::optional RemoveRPathELF(std::string const& file, // There is no RPATH or RUNPATH anyway. return true; } - if (se_count == 2 && se[1]->IndexInSection < se[0]->IndexInSection) { + if (se_count == 2 && se[0] && se[1] && + se[1]->IndexInSection < se[0]->IndexInSection) { std::swap(se[0], se[1]); } -- GitLab