From ba8cca8fa98026d67c2d5cf3ebb7a113271e09eb Mon Sep 17 00:00:00 2001 From: Ettl Martin Date: Thu, 4 Apr 2013 15:12:18 +0200 Subject: [PATCH] #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. --- lib/checkbufferoverrun.cpp | 2 +- test/testbufferoverrun.cpp | 10 ++++++++++ test/testtoken.cpp | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 4fe4f6437..487dd735e 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -2248,7 +2248,7 @@ void CheckBufferOverrun::writeOutsideBufferSize() for (std::size_t i = 0; i < functions; ++i) { const Scope * scope = symbolDatabase->functionScopes[i]; 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()); tok = tok->tokAt(4); // set tokenptr to %str% parameter const std::size_t stringLength = Token::getStrLength(tok); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index c9a645052..af157227d 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -4104,6 +4104,16 @@ private: "write(1, \"Dump string \\n\", 10);\n" "}"); 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()); } }; diff --git a/test/testtoken.cpp b/test/testtoken.cpp index 8bb08c034..bdbfce1ab 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -279,12 +279,16 @@ private: void nextArgument() const { 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(4)->nextArgument(), "3 , 4")); givenACodeSampleToTokenize example2("foo();"); ASSERT_EQUALS(true, example2.tokens()->tokAt(2)->nextArgument() == 0); givenACodeSampleToTokenize example3("foo(bar(a, b), 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 {