diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 9e3651bf7..266432dd0 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1079,6 +1079,30 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable() if (value && value->intvalue > strLen) bufferOverrunError(tok, tok->str()); } + + if (Token::Match(tok, "%var% [") && tok->variable() && tok->variable()->isPointer()) { + const ValueFlow::Value *value = tok->next()->astOperand2()->getMaxValue(false); + if (!value) + continue; + + for (std::list::const_iterator it = tok->values.begin(); it != tok->values.end(); ++it) { + if (!it->tokvalue) + continue; + const Variable *var = it->tokvalue->variable(); + if (var && var->isArray() && value->intvalue > var->dimension(0)) { + std::list callstack; + callstack.push_back(it->tokvalue); + callstack.push_back(tok); + + std::vector index; + index.push_back(value->intvalue); + + const ArrayInfo arrayInfo(var, _tokenizer, &_settings->library); + + arrayIndexOutOfBoundsError(callstack, arrayInfo, index); + } + } + } } // check all known fixed size arrays first by just looking them up diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 4a97b379e..86fc4e937 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -2058,6 +2058,13 @@ private: check("namespace { class X { static const int x[100]; };\n" // #6232 "const int X::x[100] = {0}; }", false, "test.cpp"); ASSERT_EQUALS("", errout.str()); + + check("void f() {\n" + " int a[10];\n" + " int *p = a;\n" + " p[20] = 0;\n" + "}"); + ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (error) Array 'a[10]' accessed at index 20, which is out of bounds.\n", errout.str()); } void array_index_function_parameter() {