Fixed #1134 (improve check: pointer access out of bounds not detected (allocated with malloc))

This commit is contained in:
Daniel Marjamäki 2010-04-10 07:57:29 +02:00
parent 3388daadc3
commit b4e9185177
2 changed files with 35 additions and 23 deletions

View File

@ -913,19 +913,20 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = malloc ( %num% ) ;")) else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = malloc ( %num% ) ;"))
{ {
size = MathLib::toLongNumber(tok->strAt(5)); size = MathLib::toLongNumber(tok->strAt(5));
type = "char"; type = "char"; // minimum type, typesize=1
varid = tok->tokAt(1)->varId(); varid = tok->tokAt(1)->varId();
nextTok = 7; nextTok = 7;
// "int * x ; x = malloc (y);" if (varid > 0)
const Token *declTok = tok->tokAt(-3);
if (varid > 0 && declTok && Token::Match(declTok, "%type% * %varid% ;", varid))
{ {
type = declTok->strAt(0); // get type of variable
const Token *declTok = Token::findmatch(_tokenizer->tokens(), "[;{}] %type% * %varid% ;", varid);
type = declTok->next()->str();
// malloc() gets count of bytes and not count of // malloc() gets count of bytes and not count of
// elements, so we should calculate count of elements // elements, so we should calculate count of elements
// manually // manually
unsigned int sizeOfType = _tokenizer->sizeOfType(declTok); unsigned int sizeOfType = _tokenizer->sizeOfType(declTok->next());
if (sizeOfType > 0) if (sizeOfType > 0)
size /= sizeOfType; size /= sizeOfType;
} }

View File

@ -140,7 +140,8 @@ private:
TEST_CASE(assign1); TEST_CASE(assign1);
TEST_CASE(alloc); // Buffer allocated with new TEST_CASE(alloc1); // Buffer allocated with new
TEST_CASE(alloc2); // Buffer allocated with malloc
TEST_CASE(memset1); TEST_CASE(memset1);
TEST_CASE(memset2); TEST_CASE(memset2);
@ -1600,7 +1601,7 @@ private:
ASSERT_EQUALS("[test.cpp:5]: (error) Array 'str[3]' index 3 out of bounds\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Array 'str[3]' index 3 out of bounds\n", errout.str());
} }
void alloc() void alloc1()
{ {
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -1609,13 +1610,6 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' index 10 out of bounds\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' index 10 out of bounds\n", errout.str());
check("void foo()\n"
"{\n"
" char *s = (char *)malloc(10);\n"
" s[10] = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' index 10 out of bounds\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
"char * buf = new char[8];\n" "char * buf = new char[8];\n"
@ -1638,14 +1632,6 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:7]: (error) Array 'buf[9]' index 9 out of bounds\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (error) Array 'buf[9]' index 9 out of bounds\n", errout.str());
// ticket #842
check("void f() {\n"
" int *tab4 = malloc(20 * sizeof(int));\n"
" tab4[20] = 0;\n"
" free(tab4);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'tab4[20]' index 20 out of bounds\n", errout.str());
check("void f() {\n" check("void f() {\n"
" int *tab4 = malloc(20 * sizeof(int));\n" " int *tab4 = malloc(20 * sizeof(int));\n"
" tab4[19] = 0;\n" " tab4[19] = 0;\n"
@ -1666,6 +1652,31 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
// data is allocated with malloc
void alloc2()
{
check("void foo()\n"
"{\n"
" char *s = (char *)malloc(10);\n"
" s[10] = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' index 10 out of bounds\n", errout.str());
// ticket #842
check("void f() {\n"
" int *tab4 = malloc(20 * sizeof(int));\n"
" tab4[20] = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'tab4[20]' index 20 out of bounds\n", errout.str());
// ticket #1134
check("void f() {\n"
" int *x, i;\n"
" x = malloc(10 * sizeof(int));\n"
" x[10] = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'x[10]' index 10 out of bounds\n", errout.str());
}
void memset1() void memset1()
{ {