Skip to content

Commit 7156afe

Browse files
Fix #5140 FN (error) buffer access out of bounds - known argument (#4402)
* Fix #5140 FN (error) buffer access out of bounds - known argument const char* argv[] * Format
1 parent b815153 commit 7156afe

4 files changed

Lines changed: 43 additions & 2 deletions

File tree

lib/ctu.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer)
358358
fileInfo->functionCalls.push_back(functionCall);
359359
}
360360
// array
361-
if (argtok->variable() && argtok->variable()->isArray() && argtok->variable()->dimensions().size()==1 && argtok->variable()->dimension(0)>1) {
361+
if (argtok->variable() && argtok->variable()->isArray() && argtok->variable()->dimensions().size() == 1) {
362362
FileInfo::FunctionCall functionCall;
363363
functionCall.callValueType = ValueFlow::Value::ValueType::BUFFER_SIZE;
364364
functionCall.callId = getFunctionId(tokenizer, tokFunction);

lib/tokenize.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3153,7 +3153,7 @@ void Tokenizer::arraySize()
31533153
if (!tok->isName() || !Token::Match(tok, "%var% [ ] ="))
31543154
continue;
31553155
bool addlength = false;
3156-
if (Token::Match(tok, "%var% [ ] = { %str% } ;")) {
3156+
if (Token::Match(tok->previous(), "!!* %var% [ ] = { %str% } ;")) {
31573157
Token *t = tok->tokAt(3);
31583158
t->deleteNext();
31593159
t->next()->deleteNext();

test/testbufferoverrun.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5118,6 +5118,23 @@ class TestBufferOverrun : public TestFixture {
51185118
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"
51195119
"[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",
51205120
errout.str());
5121+
5122+
// #5140
5123+
ctu("void g(const char* argv[]) { std::cout << \"argv: \" << argv[4] << std::endl; }\n"
5124+
"void f() {\n"
5125+
" const char* argv[] = { \"test\" };\n"
5126+
" g(argv);\n"
5127+
"}\n");
5128+
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",
5129+
errout.str());
5130+
5131+
ctu("void g(const char* argv[]) { std::cout << \"argv: \" << argv[5] << std::endl; }\n"
5132+
"void f() {\n"
5133+
" const char* argv[1] = { \"test\" };\n"
5134+
" g(argv);\n"
5135+
"}\n");
5136+
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",
5137+
errout.str());
51215138
}
51225139

51235140
void ctu_variable() {

test/testsymboldatabase.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class TestSymbolDatabase : public TestFixture {
126126
settings2.checkUnusedTemplates = true;
127127

128128
TEST_CASE(array);
129+
TEST_CASE(array_ptr);
129130
TEST_CASE(stlarray1);
130131
TEST_CASE(stlarray2);
131132

@@ -511,6 +512,29 @@ class TestSymbolDatabase : public TestFixture {
511512
ASSERT_EQUALS(12U, v->dimension(0));
512513
}
513514

515+
void array_ptr() {
516+
GET_SYMBOL_DB("const char* a[] = { \"abc\" };\n"
517+
"const char* b[] = { \"def\", \"ghijkl\" };");
518+
ASSERT(db != nullptr);
519+
520+
ASSERT(db->variableList().size() == 3); // the first one is not used
521+
const Variable* v = db->getVariableFromVarId(1);
522+
ASSERT(v != nullptr);
523+
524+
ASSERT(v->isArray());
525+
ASSERT(v->isPointerArray());
526+
ASSERT_EQUALS(1U, v->dimensions().size());
527+
ASSERT_EQUALS(1U, v->dimension(0));
528+
529+
v = db->getVariableFromVarId(2);
530+
ASSERT(v != nullptr);
531+
532+
ASSERT(v->isArray());
533+
ASSERT(v->isPointerArray());
534+
ASSERT_EQUALS(1U, v->dimensions().size());
535+
ASSERT_EQUALS(2U, v->dimension(0));
536+
}
537+
514538
void stlarray1() {
515539
GET_SYMBOL_DB("std::array<int, 16 + 4> arr;");
516540
ASSERT(db != nullptr);

0 commit comments

Comments
 (0)