Fix issue 10147: False positive: Out of bounds access in expression 'v[0]' because 'v' is empty. (#3123)

This commit is contained in:
Paul Fultz II 2021-02-10 01:11:06 -06:00 committed by GitHub
parent ff125f6ac6
commit 8569a970b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 17 deletions

View File

@ -403,6 +403,20 @@ void execute(const Token *expr,
*error = true;
}
else if (Token::Match(expr->tokAt(-3), "%var% . %name% (") && astIsContainer(expr->tokAt(-3))) {
const Token* containerTok = expr->tokAt(-3);
Library::Container::Yield yield = containerTok->valueType()->container->getYield(expr->strAt(-1));
if (yield == Library::Container::Yield::SIZE) {
if (!programMemory->getContainerSizeValue(containerTok->exprId(), result))
*error = true;
} else if (yield == Library::Container::Yield::EMPTY) {
if (!programMemory->getContainerEmptyValue(containerTok->exprId(), result))
*error = true;
} else {
*error = true;
}
}
else if (expr->exprId() > 0 && programMemory->hasValue(expr->exprId())) {
if (!programMemory->getIntValue(expr->exprId(), result))
*error = true;
@ -570,24 +584,7 @@ void execute(const Token *expr,
*result = 0;
else
*error = true;
} else if (Token::Match(expr->tokAt(-3), "%var% . %name% (")) {
const Token* containerTok = expr->tokAt(-3);
if (astIsContainer(containerTok)) {
Library::Container::Yield yield = containerTok->valueType()->container->getYield(expr->strAt(-1));
if (yield == Library::Container::Yield::SIZE) {
if (!programMemory->getContainerSizeValue(containerTok->exprId(), result))
*error = true;
} else if (yield == Library::Container::Yield::EMPTY) {
if (!programMemory->getContainerEmptyValue(containerTok->exprId(), result))
*error = true;
} else {
*error = true;
}
} else {
*error = true;
}
}
else
*error = true;
}

View File

@ -5069,6 +5069,18 @@ private:
" return a.size();\n"
"}\n";
ASSERT_EQUALS(true, tokenValues(code, "a . size", ValueFlow::Value::ValueType::CONTAINER_SIZE).empty());
code = "std::vector<int> g();\n"
"std::vector<int> f() {\n"
" std::vector<int> v = g();\n"
" if (!v.empty()) {\n"
" if (v[0] != 0)\n"
" v.clear();\n"
" }\n"
" if (!v.empty() && v[0] != 0) {}\n"
" return v;\n"
"}\n";
ASSERT_EQUALS(true, tokenValues(code, "v [ 0 ] != 0 ) { }", ValueFlow::Value::ValueType::CONTAINER_SIZE).empty());
}
void valueFlowDynamicBufferSize() {