Fix issue 9274: false negative: (error) Buffer is accessed out of bounds (std::string, std::wstring)

This commit is contained in:
Paul Fultz II 2019-09-03 06:43:54 +02:00 committed by Daniel Marjamäki
parent af449779f0
commit dc201d110d
2 changed files with 22 additions and 1 deletions

View File

@ -5249,6 +5249,18 @@ static void valueFlowContainerForward(Token *tok, nonneg int containerId, ValueF
if (isContainerSizeChanged(containerId, start, start->link())) if (isContainerSizeChanged(containerId, start, start->link()))
break; break;
} }
if (Token::simpleMatch(tok, ") {") && Token::Match(tok->link()->previous(), "while|for|if (")) {
const Token *start = tok->next();
if (isContainerSizeChanged(containerId, start, start->link()))
break;
tok = start->link();
if (Token::simpleMatch(tok, "} else {")) {
start = tok->tokAt(2);
if (isContainerSizeChanged(containerId, start, start->link()))
break;
tok = start->link();
}
}
if (tok->varId() != containerId) if (tok->varId() != containerId)
continue; continue;
if (Token::Match(tok, "%name% =")) if (Token::Match(tok, "%name% ="))
@ -5292,7 +5304,7 @@ static bool isContainerSizeChanged(nonneg int varId, const Token *start, const T
continue; continue;
if (!tok->valueType() || !tok->valueType()->container) if (!tok->valueType() || !tok->valueType()->container)
return true; return true;
if (Token::Match(tok, "%name% =")) if (Token::Match(tok, "%name% %assign%|<<"))
return true; return true;
if (Token::Match(tok, "%name% . %name% (")) { if (Token::Match(tok, "%name% . %name% (")) {
Library::Container::Action action = tok->valueType()->container->getAction(tok->strAt(2)); Library::Container::Action action = tok->valueType()->container->getAction(tok->strAt(2));

View File

@ -312,6 +312,15 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// # 9274
checkNormal("char f(bool b) {\n"
" const std::string s = \"<a><b>\";\n"
" int x = 6;\n"
" if(b) ++x;\n"
" return s[x];\n"
"}\n");
ASSERT_EQUALS("test.cpp:5:error:Out of bounds access in 's[x]', if 's' size is 6 and 'x' is 6\n", errout.str());
checkNormal("void f() {\n" checkNormal("void f() {\n"
" static const int N = 4;\n" " static const int N = 4;\n"
" std::array<int, N> x;\n" " std::array<int, N> x;\n"