diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 9825c7967..53341c221 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -929,6 +929,7 @@ void CheckStl::string_c_str() if (Token::Match(tok, ") const| {")) { std::set localvar; + std::set pointers; // scan through this executable scope: unsigned int indentlevel = 0; @@ -948,6 +949,10 @@ void CheckStl::string_c_str() localvar.insert(tok->tokAt(3)->varId()); else if (Token::Match(tok->previous(), "[;{}] %type% %var% ;")) localvar.insert(tok->next()->varId()); + else if (Token::Match(tok->previous(), "[;{}] %type% * %var% ;")) + pointers.insert(tok->tokAt(2)->varId()); + else if (Token::Match(tok->previous(), "[;{}] %type% %type% * %var% ;")) + pointers.insert(tok->tokAt(3)->varId()); // Invalid usage.. else if (Token::Match(tok, "throw %var% . c_str ( ) ;") && @@ -956,6 +961,20 @@ void CheckStl::string_c_str() { string_c_strError(tok); } + else if (Token::Match(tok, "[;{}] %var% = %var% . str ( ) . c_str ( ) ;") && + tok->next()->varId() > 0 && + pointers.find(tok->next()->varId()) != pointers.end()) + { + string_c_strError(tok); + } + else if (Token::Match(tok, "[;{}] %var% = %var% (") && + Token::Match(tok->tokAt(4)->link(), ") . c_str ( ) ;") && + tok->next()->varId() > 0 && + pointers.find(tok->next()->varId()) != pointers.end() && + Token::findmatch(_tokenizer->tokens(), ("std :: string " + tok->strAt(3) + " (").c_str())) + { + string_c_strError(tok); + } } } } diff --git a/test/teststl.cpp b/test/teststl.cpp index 87d21aa86..08c5b3a4b 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -1116,12 +1116,18 @@ private: "}"); ASSERT_EQUALS("[test.cpp:3]: (error) Dangerous usage of c_str()\n", errout.str()); + check("void f() {\n" + " std::ostringstream errmsg;\n" + " const char *c = errmsg.str().c_str();\n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (error) Dangerous usage of c_str()\n", errout.str()); + check("std::string f();\n" "\n" "void foo() {\n" " const char *c = f().c_str();\n" "}"); - TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Dangerous usage of c_str()\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Dangerous usage of c_str()\n", errout.str()); } };