STL check: Detect return of implict string conversion + .c_str()
Examples are: std::string msg; return ("ERROR: " + msg).c_str(); or return ("ERROR: " + std::string("crash me")).c_str();
This commit is contained in:
parent
c4dabd61e9
commit
43e9c1f0bd
|
@ -1030,6 +1030,24 @@ void CheckStl::string_c_str()
|
||||||
} else if (Token::simpleMatch(tok, "return std :: string (") &&
|
} else if (Token::simpleMatch(tok, "return std :: string (") &&
|
||||||
Token::Match(tok->tokAt(4)->link(), ") . c_str ( ) ;")) {
|
Token::Match(tok->tokAt(4)->link(), ") . c_str ( ) ;")) {
|
||||||
string_c_strError(tok);
|
string_c_strError(tok);
|
||||||
|
} else if (Token::simpleMatch(tok, "return (") &&
|
||||||
|
Token::Match(tok->next()->link(), ") . c_str ( ) ;")) {
|
||||||
|
// Check for "+ localvar" or "+ std::string(" inside the bracket
|
||||||
|
bool is_implicit_std_string = false;
|
||||||
|
const Token *search_end = tok->next()->link();
|
||||||
|
for (const Token *search_tok = tok->tokAt(2); search_tok != search_end; search_tok = search_tok->next()) {
|
||||||
|
if (Token::Match(search_tok, "+ %var%") && search_tok->next()->varId() > 0 &&
|
||||||
|
localvar.find(search_tok->next()->varId()) != localvar.end()) {
|
||||||
|
is_implicit_std_string = true;
|
||||||
|
break;
|
||||||
|
} else if (Token::simpleMatch(search_tok, "+ std :: string (")) {
|
||||||
|
is_implicit_std_string = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_implicit_std_string)
|
||||||
|
string_c_strError(tok);
|
||||||
} else if (Token::Match(tok, "[;{}] %var% = %var% . str ( ) . c_str ( ) ;") &&
|
} else if (Token::Match(tok, "[;{}] %var% = %var% . str ( ) . c_str ( ) ;") &&
|
||||||
tok->next()->varId() > 0 &&
|
tok->next()->varId() > 0 &&
|
||||||
pointers.find(tok->next()->varId()) != pointers.end()) {
|
pointers.find(tok->next()->varId()) != pointers.end()) {
|
||||||
|
|
|
@ -1329,6 +1329,18 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Dangerous usage of c_str()\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Dangerous usage of c_str()\n", errout.str());
|
||||||
|
|
||||||
|
check("const char *get_msg() {\n"
|
||||||
|
" std::string errmsg;\n"
|
||||||
|
" return (\"ERROR: \" + errmsg).c_str();\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (error) Dangerous usage of c_str()\n", errout.str());
|
||||||
|
|
||||||
|
check("const char *get_msg() {\n"
|
||||||
|
" std::string errmsg;\n"
|
||||||
|
" return (\"ERROR: \" + std::string(\"crash me\")).c_str();\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (error) Dangerous usage of c_str()\n", errout.str());
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" std::ostringstream errmsg;\n"
|
" std::ostringstream errmsg;\n"
|
||||||
" const char *c = errmsg.str().c_str();\n"
|
" const char *c = errmsg.str().c_str();\n"
|
||||||
|
|
Loading…
Reference in New Issue