diff --git a/lib/ctu.cpp b/lib/ctu.cpp index 61c2cf716..5ef5dc41c 100644 --- a/lib/ctu.cpp +++ b/lib/ctu.cpp @@ -358,7 +358,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer) fileInfo->functionCalls.push_back(functionCall); } // array - if (argtok->variable() && argtok->variable()->isArray() && argtok->variable()->dimensions().size()==1 && argtok->variable()->dimension(0)>1) { + if (argtok->variable() && argtok->variable()->isArray() && argtok->variable()->dimensions().size() == 1) { FileInfo::FunctionCall functionCall; functionCall.callValueType = ValueFlow::Value::ValueType::BUFFER_SIZE; functionCall.callId = getFunctionId(tokenizer, tokFunction); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 28f0517e3..6b8ec7ecb 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3153,7 +3153,7 @@ void Tokenizer::arraySize() if (!tok->isName() || !Token::Match(tok, "%var% [ ] =")) continue; bool addlength = false; - if (Token::Match(tok, "%var% [ ] = { %str% } ;")) { + if (Token::Match(tok->previous(), "!!* %var% [ ] = { %str% } ;")) { Token *t = tok->tokAt(3); t->deleteNext(); t->next()->deleteNext(); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 576b214be..3f7f06236 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -5118,6 +5118,23 @@ private: ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:1]: (error) Array index out of bounds; 's' buffer size is 2 and it is accessed at offset 2.\n" "[test.cpp:6] -> [test.cpp:2]: (error) Array index out of bounds; 's' buffer size is 2 and it is accessed at offset 2.\n", errout.str()); + + // #5140 + ctu("void g(const char* argv[]) { std::cout << \"argv: \" << argv[4] << std::endl; }\n" + "void f() {\n" + " const char* argv[] = { \"test\" };\n" + " g(argv);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1]: (error) Array index out of bounds; 'argv' buffer size is 1 and it is accessed at offset 4.\n", + errout.str()); + + ctu("void g(const char* argv[]) { std::cout << \"argv: \" << argv[5] << std::endl; }\n" + "void f() {\n" + " const char* argv[1] = { \"test\" };\n" + " g(argv);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1]: (error) Array index out of bounds; 'argv' buffer size is 1 and it is accessed at offset 5.\n", + errout.str()); } void ctu_variable() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index e5c74d0d6..3d79aa958 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -126,6 +126,7 @@ private: settings2.checkUnusedTemplates = true; TEST_CASE(array); + TEST_CASE(array_ptr); TEST_CASE(stlarray1); TEST_CASE(stlarray2); @@ -511,6 +512,29 @@ private: ASSERT_EQUALS(12U, v->dimension(0)); } + void array_ptr() { + GET_SYMBOL_DB("const char* a[] = { \"abc\" };\n" + "const char* b[] = { \"def\", \"ghijkl\" };"); + ASSERT(db != nullptr); + + ASSERT(db->variableList().size() == 3); // the first one is not used + const Variable* v = db->getVariableFromVarId(1); + ASSERT(v != nullptr); + + ASSERT(v->isArray()); + ASSERT(v->isPointerArray()); + ASSERT_EQUALS(1U, v->dimensions().size()); + ASSERT_EQUALS(1U, v->dimension(0)); + + v = db->getVariableFromVarId(2); + ASSERT(v != nullptr); + + ASSERT(v->isArray()); + ASSERT(v->isPointerArray()); + ASSERT_EQUALS(1U, v->dimensions().size()); + ASSERT_EQUALS(2U, v->dimension(0)); + } + void stlarray1() { GET_SYMBOL_DB("std::array arr;"); ASSERT(db != nullptr);