From b4e918517782687899703f4f884f56be3118eadd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 10 Apr 2010 07:57:29 +0200 Subject: [PATCH] Fixed #1134 (improve check: pointer access out of bounds not detected (allocated with malloc)) --- lib/checkbufferoverrun.cpp | 13 ++++++----- test/testbufferoverrun.cpp | 45 ++++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index ecde2cff3..68c901d18 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -913,19 +913,20 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable() else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = malloc ( %num% ) ;")) { size = MathLib::toLongNumber(tok->strAt(5)); - type = "char"; + type = "char"; // minimum type, typesize=1 varid = tok->tokAt(1)->varId(); nextTok = 7; - // "int * x ; x = malloc (y);" - const Token *declTok = tok->tokAt(-3); - if (varid > 0 && declTok && Token::Match(declTok, "%type% * %varid% ;", varid)) + if (varid > 0) { - 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 // elements, so we should calculate count of elements // manually - unsigned int sizeOfType = _tokenizer->sizeOfType(declTok); + unsigned int sizeOfType = _tokenizer->sizeOfType(declTok->next()); if (sizeOfType > 0) size /= sizeOfType; } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 6aaabee14..91613c6a8 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -140,7 +140,8 @@ private: 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(memset2); @@ -1600,7 +1601,7 @@ private: 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" "{\n" @@ -1609,13 +1610,6 @@ private: "}\n"); 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" "{\n" "char * buf = new char[8];\n" @@ -1638,14 +1632,6 @@ private: "}\n"); 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" " int *tab4 = malloc(20 * sizeof(int));\n" " tab4[19] = 0;\n" @@ -1666,6 +1652,31 @@ private: 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() {