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

View File

@ -79,6 +79,7 @@ private:
TEST_CASE(testautovar_extern);
TEST_CASE(testautovar_reassigned);
TEST_CASE(testinvaliddealloc);
TEST_CASE(testinvaliddealloc_string);
TEST_CASE(testinvaliddealloc_C);
TEST_CASE(testassign1); // Ticket #1819
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: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"
" char* tmp1[256];\n"
" init(tmp1);\n"
@ -758,6 +764,26 @@ private:
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() {
// #5691
check("void svn_repos_dir_delta2() {\n"