value flow: Use ValueFlow in CheckBufferOverrun
This commit is contained in:
parent
45c9a63157
commit
0b4de97e2b
|
@ -1138,6 +1138,18 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
|
|||
continue;
|
||||
}
|
||||
|
||||
else if (Token::Match(tok, "%varid% [", arrayInfo.declarationId()) && tok->next()->astOperand2() && !tok->next()->astOperand2()->values.empty()) {
|
||||
const std::list<ValueFlow::Value> &values = tok->next()->astOperand2()->values;
|
||||
std::list<ValueFlow::Value>::const_iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it) {
|
||||
if (it->intvalue >= arrayInfo.num()[0]) {
|
||||
std::vector<MathLib::bigint> indexes;
|
||||
indexes.push_back(it->intvalue);
|
||||
arrayIndexOutOfBoundsError(tok, arrayInfo, indexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (Token::Match(tok, "%varid% [ %num% ]", arrayInfo.declarationId())) {
|
||||
std::vector<MathLib::bigint> indexes;
|
||||
for (const Token *tok2 = tok->next(); Token::Match(tok2, "[ %num% ]"); tok2 = tok2->tokAt(3)) {
|
||||
|
|
|
@ -72,6 +72,25 @@ private:
|
|||
checkBufferOverrun.writeOutsideBufferSize();
|
||||
}
|
||||
|
||||
void checkValueFlow(const char code[]) {
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
Settings settings;
|
||||
settings.valueFlow = true;
|
||||
settings.addEnabled("warning");
|
||||
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
tokenizer.simplifyTokenList2();
|
||||
|
||||
// Check for buffer overruns..
|
||||
CheckBufferOverrun checkBufferOverrun(&tokenizer, &settings, this);
|
||||
checkBufferOverrun.bufferOverrun();
|
||||
}
|
||||
|
||||
void run() {
|
||||
TEST_CASE(noerr1);
|
||||
TEST_CASE(noerr2);
|
||||
|
@ -142,6 +161,7 @@ private:
|
|||
TEST_CASE(array_index_cast); // FP after cast. #2841
|
||||
TEST_CASE(array_index_string_literal);
|
||||
TEST_CASE(array_index_same_struct_and_var_name); // #4751 - not handled well when struct name and var name is same
|
||||
TEST_CASE(array_index_valueflow);
|
||||
|
||||
TEST_CASE(buffer_overrun_1_standard_functions);
|
||||
TEST_CASE(buffer_overrun_2_struct);
|
||||
|
@ -2050,6 +2070,15 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:7]: (error) Array 'tt.name[21]' accessed at index 22, which is out of bounds.\n", errout.str());
|
||||
}
|
||||
|
||||
void array_index_valueflow() {
|
||||
checkValueFlow("void f(int i) {\n"
|
||||
" char str[3];\n"
|
||||
" str[i] = 0;\n"
|
||||
" if (i==10) {}\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'str[3]' accessed at index 10, which is out of bounds.\n", errout.str());
|
||||
}
|
||||
|
||||
void buffer_overrun_1_standard_functions() {
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue