#4706 fix crash when a struct member is used as first argument. Replaced Token::nexArgument with %any% in Token::Match call. Added unittests in testing Token::nexArgument.

This commit is contained in:
Ettl Martin 2013-04-04 15:12:18 +02:00
parent c5d636c074
commit ba8cca8fa9
3 changed files with 15 additions and 1 deletions

View File

@ -2248,7 +2248,7 @@ void CheckBufferOverrun::writeOutsideBufferSize()
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i]; const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) { for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "pwrite|write (") && Token::Match(tok->tokAt(2)->nextArgument(), "%str% , %num%")) { if (Token::Match(tok, "pwrite|write (") && Token::Match(tok->tokAt(2), "%any% , %str% , %num%")) {
const std::string & functionName(tok->str()); const std::string & functionName(tok->str());
tok = tok->tokAt(4); // set tokenptr to %str% parameter tok = tok->tokAt(4); // set tokenptr to %str% parameter
const std::size_t stringLength = Token::getStrLength(tok); const std::size_t stringLength = Token::getStrLength(tok);

View File

@ -4104,6 +4104,16 @@ private:
"write(1, \"Dump string \\n\", 10);\n" "write(1, \"Dump string \\n\", 10);\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #4706 avoid crashing when a struct member is used as first argument
check("static struct {\n"
" int i[2];\n"
"} p;\n"
"void foo()\n"
"{\n"
" write(p.i[1], \"\", 1);\n"
"}");
ASSERT_EQUALS("", errout.str());
} }
}; };

View File

@ -279,12 +279,16 @@ private:
void nextArgument() const { void nextArgument() const {
givenACodeSampleToTokenize example1("foo(1, 2, 3, 4);"); givenACodeSampleToTokenize example1("foo(1, 2, 3, 4);");
ASSERT_EQUALS(true, Token::simpleMatch(example1.tokens()->tokAt(2)->nextArgument(), "2 , 3")); ASSERT_EQUALS(true, Token::simpleMatch(example1.tokens()->tokAt(2)->nextArgument(), "2 , 3"));
ASSERT_EQUALS(true, Token::simpleMatch(example1.tokens()->tokAt(4)->nextArgument(), "3 , 4"));
givenACodeSampleToTokenize example2("foo();"); givenACodeSampleToTokenize example2("foo();");
ASSERT_EQUALS(true, example2.tokens()->tokAt(2)->nextArgument() == 0); ASSERT_EQUALS(true, example2.tokens()->tokAt(2)->nextArgument() == 0);
givenACodeSampleToTokenize example3("foo(bar(a, b), 2, 3);"); givenACodeSampleToTokenize example3("foo(bar(a, b), 2, 3);");
ASSERT_EQUALS(true, Token::simpleMatch(example3.tokens()->tokAt(2)->nextArgument(), "2 , 3")); ASSERT_EQUALS(true, Token::simpleMatch(example3.tokens()->tokAt(2)->nextArgument(), "2 , 3"));
givenACodeSampleToTokenize example4("foo(x.i[1], \"\", 3);");
ASSERT_EQUALS(true, Token::simpleMatch(example4.tokens()->tokAt(2)->nextArgument(), "\"\" , 3"));
} }
void eraseTokens() const { void eraseTokens() const {