Fixed #3255 (Error message for std::string::c_str() is not descriptive)
This commit is contained in:
parent
6889a28d31
commit
9a8c48b36e
|
@ -1018,7 +1018,7 @@ void CheckStl::string_c_str()
|
||||||
else if (Token::Match(tok, "throw %var% . c_str ( ) ;") &&
|
else if (Token::Match(tok, "throw %var% . c_str ( ) ;") &&
|
||||||
tok->next()->varId() > 0 &&
|
tok->next()->varId() > 0 &&
|
||||||
localvar.find(tok->next()->varId()) != localvar.end()) {
|
localvar.find(tok->next()->varId()) != localvar.end()) {
|
||||||
string_c_strError(tok);
|
string_c_strThrowError(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()) {
|
||||||
|
@ -1073,12 +1073,20 @@ void CheckStl::string_c_str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckStl::string_c_strThrowError(const Token* tok)
|
||||||
|
{
|
||||||
|
reportError(tok, Severity::error, "stlcstrthrow", "Dangerous usage of c_str(). The returned value by c_str() is invalid after throw call.\n"
|
||||||
|
"Dangerous usage of c_str(). The string is destroyed after the c_str() call so the thrown pointer is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
void CheckStl::string_c_strError(const Token* tok, bool is_inconlusive)
|
void CheckStl::string_c_strError(const Token* tok, bool is_inconlusive)
|
||||||
{
|
{
|
||||||
if (is_inconlusive)
|
if (is_inconlusive)
|
||||||
reportInconclusiveError(tok, Severity::error, "stlcstr", "Possible dangerous usage of c_str()");
|
reportInconclusiveError(tok, Severity::error, "stlcstr", "Possible dangerous usage of c_str()\n"
|
||||||
|
"Possible dangerous usage of c_str() in return statement. The c_str() return value is only valid until its string is deleted.");
|
||||||
else
|
else
|
||||||
reportError(tok, Severity::error, "stlcstr", "Dangerous usage of c_str()");
|
reportError(tok, Severity::error, "stlcstr", "Dangerous usage of c_str(). The returned value by c_str() is invalid after this call.\n"
|
||||||
|
"Dangerous usage of c_str(). The c_str() return value is only valid until its string is deleted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasArrayEnd(const Token *tok1)
|
static bool hasArrayEnd(const Token *tok1)
|
||||||
|
|
|
@ -133,6 +133,7 @@ public:
|
||||||
|
|
||||||
/** Check for common mistakes when using the function string::c_str() */
|
/** Check for common mistakes when using the function string::c_str() */
|
||||||
void string_c_str();
|
void string_c_str();
|
||||||
|
void string_c_strThrowError(const Token *tok);
|
||||||
void string_c_strError(const Token *tok, bool is_inconlusive=false);
|
void string_c_strError(const Token *tok, bool is_inconlusive=false);
|
||||||
|
|
||||||
/** @brief %Check for use and copy auto pointer */
|
/** @brief %Check for use and copy auto pointer */
|
||||||
|
|
|
@ -1311,7 +1311,7 @@ private:
|
||||||
" std::string errmsg;\n"
|
" std::string errmsg;\n"
|
||||||
" throw errmsg.c_str();\n"
|
" throw errmsg.c_str();\n"
|
||||||
"}");
|
"}");
|
||||||
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(). The returned value by c_str() is invalid after throw call.\n", errout.str());
|
||||||
|
|
||||||
check("const char *get_msg() {\n"
|
check("const char *get_msg() {\n"
|
||||||
" std::string errmsg;\n"
|
" std::string errmsg;\n"
|
||||||
|
@ -1355,14 +1355,14 @@ private:
|
||||||
" std::ostringstream errmsg;\n"
|
" std::ostringstream errmsg;\n"
|
||||||
" const char *c = errmsg.str().c_str();\n"
|
" const char *c = errmsg.str().c_str();\n"
|
||||||
"}");
|
"}");
|
||||||
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(). The returned value by c_str() is invalid after this call.\n", errout.str());
|
||||||
|
|
||||||
check("std::string f();\n"
|
check("std::string f();\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void foo() {\n"
|
"void foo() {\n"
|
||||||
" const char *c = f().c_str();\n"
|
" const char *c = f().c_str();\n"
|
||||||
"}");
|
"}");
|
||||||
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(). The returned value by c_str() is invalid after this call.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void cstr_inconclusive() {
|
void cstr_inconclusive() {
|
||||||
|
|
Loading…
Reference in New Issue