Fix #7341: Dealloc string literal (#3586)

This commit is contained in:
Rikard Falkeborn 2021-11-30 07:31:28 +01:00 committed by GitHub
parent d565cde815
commit db4f94fdfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 6 deletions

View File

@ -266,16 +266,16 @@ void CheckAutoVariables::autoVariables()
errorAutoVariableAssignment(tok->next(), false); errorAutoVariableAssignment(tok->next(), false);
} }
// Invalid pointer deallocation // Invalid pointer deallocation
else if ((Token::Match(tok, "%name% ( %var% ) ;") && mSettings->library.getDeallocFuncInfo(tok)) || else if ((Token::Match(tok, "%name% ( %var%|%str% ) ;") && mSettings->library.getDeallocFuncInfo(tok)) ||
(mTokenizer->isCPP() && Token::Match(tok, "delete [| ]| (| %var% !!["))) { (mTokenizer->isCPP() && Token::Match(tok, "delete [| ]| (| %var%|%str% !!["))) {
tok = Token::findmatch(tok->next(), "%var%"); tok = Token::findmatch(tok->next(), "%var%|%str%");
if (isArrayVar(tok)) if (isArrayVar(tok) || tok->tokType() == Token::eString)
errorInvalidDeallocation(tok, nullptr); errorInvalidDeallocation(tok, nullptr);
else if (tok->variable() && tok->variable()->isPointer()) { else if (tok->variable() && tok->variable()->isPointer()) {
for (const ValueFlow::Value &v : tok->values()) { for (const ValueFlow::Value &v : tok->values()) {
if (!(v.isTokValue())) if (!(v.isTokValue()))
continue; continue;
if (isArrayVar(v.tokvalue)) { if (isArrayVar(v.tokvalue) || v.tokvalue->tokType() == Token::eString) {
errorInvalidDeallocation(tok, &v); errorInvalidDeallocation(tok, &v);
break; break;
} }
@ -804,7 +804,11 @@ void CheckAutoVariables::errorInvalidDeallocation(const Token *tok, const ValueF
const Variable *var = val ? val->tokvalue->variable() : (tok ? tok->variable() : nullptr); const Variable *var = val ? val->tokvalue->variable() : (tok ? tok->variable() : nullptr);
std::string type = "auto-variable"; std::string type = "auto-variable";
if (var) { if (tok && tok->tokType() == Token::eString)
type = "string literal";
else if (val && val->tokvalue->tokType() == Token::eString)
type = "pointer pointing to a string literal";
else if (var) {
if (var->isGlobal()) if (var->isGlobal())
type = "global variable"; type = "global variable";
else if (var->isStatic()) else if (var->isStatic())

View File

@ -79,6 +79,7 @@ private:
TEST_CASE(testautovar_extern); TEST_CASE(testautovar_extern);
TEST_CASE(testautovar_reassigned); TEST_CASE(testautovar_reassigned);
TEST_CASE(testinvaliddealloc); TEST_CASE(testinvaliddealloc);
TEST_CASE(testinvaliddealloc_string);
TEST_CASE(testinvaliddealloc_C); TEST_CASE(testinvaliddealloc_C);
TEST_CASE(testassign1); // Ticket #1819 TEST_CASE(testassign1); // Ticket #1819
TEST_CASE(testassign2); // Ticket #2765 TEST_CASE(testassign2); // Ticket #2765
@ -627,6 +628,11 @@ private:
"[test.cpp:9]: (error) Deallocation of an auto-variable results in undefined behaviour.\n" "[test.cpp:9]: (error) Deallocation of an auto-variable results in undefined behaviour.\n"
"[test.cpp:11]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str()); "[test.cpp:11]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str());
check("void func1(char * ptr) {\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void func1() {\n" check("void func1() {\n"
" char* tmp1[256];\n" " char* tmp1[256];\n"
" init(tmp1);\n" " init(tmp1);\n"
@ -758,6 +764,26 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void testinvaliddealloc_string() {
// #7341
check("void f() {\n"
" char *ptr = \"a\";\n"
" free(\"a\");\n"
" delete \"a\";\n"
" free(ptr);\n"
" delete ptr;\n"
" char * p = malloc(1000);\n"
" p = \"abc\";\n"
" free(p);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an string literal results in undefined behaviour.\n"
"[test.cpp:4]: (error) Deallocation of an string literal results in undefined behaviour.\n"
"[test.cpp:5]: (error) Deallocation of an pointer pointing to a string literal (\"a\") results in undefined behaviour.\n"
"[test.cpp:6]: (error) Deallocation of an pointer pointing to a string literal (\"a\") results in undefined behaviour.\n"
"[test.cpp:9]: (error) Deallocation of an pointer pointing to a string literal (\"abc\") results in undefined behaviour.\n",
errout.str());
}
void testinvaliddealloc_C() { void testinvaliddealloc_C() {
// #5691 // #5691
check("void svn_repos_dir_delta2() {\n" check("void svn_repos_dir_delta2() {\n"