From 90e6c10c1241fb07d3f115e0d6d6bc2a8b37cc4f Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Wed, 18 May 2022 01:29:30 -0500 Subject: [PATCH] Fix 11072: FP arrayIndexOutOfBounds, nullPointer with nested loops (#4113) * Fix 11072: FP arrayIndexOutOfBounds, nullPointer with nested loops * Format * Remove print statement --- lib/valueflow.cpp | 30 +++++++++++++++++------------- test/testvalueflow.cpp | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 1ca38b67d..f20800150 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6343,6 +6343,8 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, ErrorLogger* errorLogger, const Settings* settings) { + // TODO: Refactor this to use arbitary expressions + assert(expr->varId() > 0); const Token * const bodyEnd = bodyStart->link(); // Is variable modified inside for loop @@ -6512,24 +6514,26 @@ static void valueFlowForLoop(TokenList *tokenlist, SymbolDatabase* symboldatabas } else { ProgramMemory mem1, mem2, memAfter; if (valueFlowForLoop2(tok, &mem1, &mem2, &memAfter)) { - ProgramMemory::Map::const_iterator it; - for (it = mem1.begin(); it != mem1.end(); ++it) { - if (!it->second.isIntValue()) + for (const auto& p : mem1) { + if (!p.second.isIntValue()) continue; - valueFlowForLoopSimplify( - bodyStart, it->first.tok, false, it->second.intvalue, tokenlist, errorLogger, settings); + if (p.first.tok->varId() == 0) + continue; + valueFlowForLoopSimplify(bodyStart, p.first.tok, false, p.second.intvalue, tokenlist, errorLogger, settings); } - for (it = mem2.begin(); it != mem2.end(); ++it) { - if (!it->second.isIntValue()) + for (const auto& p : mem2) { + if (!p.second.isIntValue()) continue; - valueFlowForLoopSimplify( - bodyStart, it->first.tok, false, it->second.intvalue, tokenlist, errorLogger, settings); + if (p.first.tok->varId() == 0) + continue; + valueFlowForLoopSimplify(bodyStart, p.first.tok, false, p.second.intvalue, tokenlist, errorLogger, settings); } - for (it = memAfter.begin(); it != memAfter.end(); ++it) { - if (!it->second.isIntValue()) + for (const auto& p : memAfter) { + if (!p.second.isIntValue()) continue; - valueFlowForLoopSimplifyAfter( - tok, it->first.getExpressionId(), it->second.intvalue, tokenlist, settings); + if (p.first.tok->varId() == 0) + continue; + valueFlowForLoopSimplifyAfter(tok, p.first.getExpressionId(), p.second.intvalue, tokenlist, settings); } } } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 99ff9adcd..291b6fdf6 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -4267,6 +4267,22 @@ private: " }\n" "}\n"; testValueOfX(code, 0, 0); // <- don't throw + + // #11072 + code = "struct a {\n" + " long b;\n" + " long c[6];\n" + " long d;\n" + "};\n" + "void e(long) {\n" + " a f = {0};\n" + " for (f.d = 0; 2; f.d++)\n" + " e(f.c[f.b]);\n" + "}\n"; + values = tokenValues(code, ". c"); + ASSERT_EQUALS(true, values.empty()); + values = tokenValues(code, "[ f . b"); + ASSERT_EQUALS(true, values.empty()); } void valueFlowSubFunction() {