Refactoring: CheckBufferOverrun refactorings. split up the checkScope into two separate functions. The ArrayInfo usage was improved. Also broke out for-loop handling into separate functions.
This commit is contained in:
parent
c26e619b23
commit
798aa84151
File diff suppressed because it is too large
Load Diff
|
@ -98,7 +98,7 @@ public:
|
||||||
/** Check for negative index */
|
/** Check for negative index */
|
||||||
void negativeIndex();
|
void negativeIndex();
|
||||||
|
|
||||||
/** Check for buffer overruns - this is the function that performs the actual checking */
|
/** Check for buffer overruns */
|
||||||
void checkScope(const Token *tok, const std::vector<std::string> &varname, const int size, const int total_size, unsigned int varid);
|
void checkScope(const Token *tok, const std::vector<std::string> &varname, const int size, const int total_size, unsigned int varid);
|
||||||
|
|
||||||
/** Information about N-dimensional array */
|
/** Information about N-dimensional array */
|
||||||
|
@ -122,6 +122,14 @@ public:
|
||||||
ArrayInfo(const ArrayInfo &);
|
ArrayInfo(const ArrayInfo &);
|
||||||
const ArrayInfo & operator=(const ArrayInfo &ai);
|
const ArrayInfo & operator=(const ArrayInfo &ai);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create array info with specified data
|
||||||
|
* The intention is that this is only a temporary solution.. all
|
||||||
|
* checking should be based on ArrayInfo from the start and then
|
||||||
|
* this will not be needed as the declare can be used instead.
|
||||||
|
*/
|
||||||
|
ArrayInfo(unsigned int id, const std::string &name, unsigned int size1, unsigned int n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare array - set info
|
* Declare array - set info
|
||||||
* \param tok first token in array declaration
|
* \param tok first token in array declaration
|
||||||
|
@ -143,6 +151,13 @@ public:
|
||||||
const std::string &varname;
|
const std::string &varname;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Check for buffer overruns (based on ArrayInfo) */
|
||||||
|
void checkScope(const Token *tok, const ArrayInfo &arrayInfo);
|
||||||
|
|
||||||
|
|
||||||
|
/** Helper function used when parsing for-loops */
|
||||||
|
void parse_for_body(const Token *tok2, const ArrayInfo &arrayInfo, const std::string &strindex, bool condition_out_of_bounds, unsigned int counter_varid, const std::string &min_counter_value, const std::string &max_counter_value);
|
||||||
|
|
||||||
|
|
||||||
/** callstack - used during intra-function checking */
|
/** callstack - used during intra-function checking */
|
||||||
std::list<const Token *> _callStack;
|
std::list<const Token *> _callStack;
|
||||||
|
|
|
@ -310,7 +310,7 @@ private:
|
||||||
" for (i = 0; i < 100; i++)\n"
|
" for (i = 0; i < 100; i++)\n"
|
||||||
" sum += val[i];\n"
|
" sum += val[i];\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer access out-of-bounds: val\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -321,7 +321,7 @@ private:
|
||||||
" for (i = 1; i < 100; i++)\n"
|
" for (i = 1; i < 100; i++)\n"
|
||||||
" sum += val[i];\n"
|
" sum += val[i];\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer access out-of-bounds: val\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ private:
|
||||||
" for (i = a; i < 100; i++)\n"
|
" for (i = a; i < 100; i++)\n"
|
||||||
" sum += val[i];\n"
|
" sum += val[i];\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer access out-of-bounds: val\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -457,7 +457,8 @@ private:
|
||||||
" char str[5];\n"
|
" char str[5];\n"
|
||||||
" memclr( str ); // ERROR\n"
|
" memclr( str ); // ERROR\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:3]: (possible error) Array index out of bounds\n", errout.str());
|
TODO_ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:3]: (error) Array index out of bounds\n", errout.str());
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("static void memclr( int i, char *data )\n"
|
check("static void memclr( int i, char *data )\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -469,7 +470,8 @@ private:
|
||||||
" char str[5];\n"
|
" char str[5];\n"
|
||||||
" memclr( 0, str ); // ERROR\n"
|
" memclr( 0, str ); // ERROR\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:3]: (possible error) Array index out of bounds\n", errout.str());
|
TODO_ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:3]: (error) Array index out of bounds\n", errout.str());
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("static void memclr( int i, char *data )\n"
|
check("static void memclr( int i, char *data )\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -496,8 +498,7 @@ private:
|
||||||
" char str[5];\n"
|
" char str[5];\n"
|
||||||
" memclr( str, 5 ); // ERROR\n"
|
" memclr( str, 5 ); // ERROR\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:3]: (possible error) Array index out of bounds\n", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
TODO_ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -876,7 +877,7 @@ private:
|
||||||
" for (int i = 3; 0 <= i; i--)\n"
|
" for (int i = 3; 0 <= i; i--)\n"
|
||||||
" a[i] = i;\n"
|
" a[i] = i;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Buffer access out-of-bounds: a\n", errout.str());
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -908,8 +909,7 @@ private:
|
||||||
" char a[2][2];\n"
|
" char a[2][2];\n"
|
||||||
" a[2][1] = 'a';\n"
|
" a[2][1] = 'a';\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str()); // catch changes
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[2][2]' index 2 out of bounds\n", errout.str());
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str());
|
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -917,15 +917,14 @@ private:
|
||||||
" a[1][2] = 'a';\n"
|
" a[1][2] = 'a';\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str()); // catch changes
|
ASSERT_EQUALS("", errout.str()); // catch changes
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str());
|
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[2][2]' index 2 out of bounds\n", errout.str());
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char a[2][2][2];\n"
|
" char a[2][2][2];\n"
|
||||||
" a[2][1][1] = 'a';\n"
|
" a[2][1][1] = 'a';\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str()); // catch changes
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[2][2][2]' index 2 out of bounds\n", errout.str());
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str());
|
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1040,7 +1039,7 @@ private:
|
||||||
" data[i] = 0;\n"
|
" data[i] = 0;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Buffer access out-of-bounds: data\n", errout.str());
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1087,7 +1086,7 @@ private:
|
||||||
" char str[3];\n"
|
" char str[3];\n"
|
||||||
" strcpy(str, \"abc\");\n"
|
" strcpy(str, \"abc\");\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: str\n", errout.str());
|
||||||
|
|
||||||
check("void f(int fd)\n"
|
check("void f(int fd)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1101,7 +1100,7 @@ private:
|
||||||
" char str[3];\n"
|
" char str[3];\n"
|
||||||
" read(fd, str, 4);\n"
|
" read(fd, str, 4);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: str\n", errout.str());
|
||||||
|
|
||||||
check("void f(int fd)\n"
|
check("void f(int fd)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1115,7 +1114,7 @@ private:
|
||||||
" char str[3];\n"
|
" char str[3];\n"
|
||||||
" write(fd, str, 4);\n"
|
" write(fd, str, 4);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: str\n", errout.str());
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1136,7 +1135,7 @@ private:
|
||||||
" char str[3];\n"
|
" char str[3];\n"
|
||||||
" fgets(str, 4, stdin);\n"
|
" fgets(str, 4, stdin);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: str\n", errout.str());
|
||||||
|
|
||||||
// fread
|
// fread
|
||||||
check("void f(FILE* fd)\n"
|
check("void f(FILE* fd)\n"
|
||||||
|
@ -1144,7 +1143,7 @@ private:
|
||||||
"char str[3];\n"
|
"char str[3];\n"
|
||||||
"fread(str,sizeof(char),4,fd);\n"
|
"fread(str,sizeof(char),4,fd);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: str\n", errout.str());
|
||||||
|
|
||||||
// fread
|
// fread
|
||||||
check("void f(FILE* fd)\n"
|
check("void f(FILE* fd)\n"
|
||||||
|
@ -1169,7 +1168,7 @@ private:
|
||||||
"char str[3];\n"
|
"char str[3];\n"
|
||||||
"fwrite(str,sizeof(char),4,fd);\n"
|
"fwrite(str,sizeof(char),4,fd);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: str\n", errout.str());
|
||||||
|
|
||||||
check("void f(FILE* fd)\n"
|
check("void f(FILE* fd)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1215,7 +1214,7 @@ private:
|
||||||
" for (i = 0; i <= 10; ++i)\n"
|
" for (i = 0; i <= 10; ++i)\n"
|
||||||
" a[i] = 0;\n"
|
" a[i] = 0;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:7]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:7]: (error) Buffer access out-of-bounds: a\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1227,7 +1226,7 @@ private:
|
||||||
" for (int i = 0; i < 8; ++i)\n"
|
" for (int i = 0; i < 8; ++i)\n"
|
||||||
" p[i] = 0;\n"
|
" p[i] = 0;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Buffer access out-of-bounds: p\n", errout.str());
|
||||||
|
|
||||||
// No false positive
|
// No false positive
|
||||||
check("void foo(int x, int y)\n"
|
check("void foo(int x, int y)\n"
|
||||||
|
@ -1248,8 +1247,8 @@ private:
|
||||||
" char s[3];\n"
|
" char s[3];\n"
|
||||||
" f1(s,3);\n"
|
" f1(s,3);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (possible error) Buffer access out-of-bounds\n", errout.str());
|
//ASSERT_EQUALS("[test.cpp:3]: (possible error) Buffer access out-of-bounds\n", errout.str());
|
||||||
TODO_ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void f1(char *s,int size)\n"
|
check("void f1(char *s,int size)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1282,14 +1281,14 @@ private:
|
||||||
" strcat(n, \"abc\");\n"
|
" strcat(n, \"abc\");\n"
|
||||||
" strcat(n, \"def\");\n"
|
" strcat(n, \"def\");\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Buffer access out-of-bounds: n\n", errout.str());
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char n[5];\n"
|
" char n[5];\n"
|
||||||
" strcat(strcat(n, \"abc\"), \"def\");\n"
|
" strcat(strcat(n, \"abc\"), \"def\");\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: n\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void buffer_overrun_7()
|
void buffer_overrun_7()
|
||||||
|
@ -1570,21 +1569,21 @@ private:
|
||||||
" char str[5];\n"
|
" char str[5];\n"
|
||||||
" memset(str, 0, 10);\n"
|
" memset(str, 0, 10);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: str\n", errout.str());
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char a[5], b[50];\n"
|
" char a[5], b[50];\n"
|
||||||
" memcpy(a, b, 10);\n"
|
" memcpy(a, b, 10);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: a\n", errout.str());
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char a[5], b[50];\n"
|
" char a[5], b[50];\n"
|
||||||
" memmove(a, b, 10);\n"
|
" memmove(a, b, 10);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: a\n", errout.str());
|
||||||
|
|
||||||
// When this TODO assertion works, ticket #909 can probably be closed
|
// When this TODO assertion works, ticket #909 can probably be closed
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
|
@ -1864,7 +1863,7 @@ private:
|
||||||
" strcpy(a,\"hello\");\n"
|
" strcpy(a,\"hello\");\n"
|
||||||
" strncpy(c,a,sizeof(c)+1);\n"
|
" strncpy(c,a,sizeof(c)+1);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer access out-of-bounds: c\n", errout.str());
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1878,7 +1877,7 @@ private:
|
||||||
" char c[6];\n"
|
" char c[6];\n"
|
||||||
" strncpy(c,\"hello!\",sizeof(c)+1);\n"
|
" strncpy(c,\"hello!\",sizeof(c)+1);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: c\n", errout.str());
|
||||||
|
|
||||||
check("struct AB { char a[10]; };\n"
|
check("struct AB { char a[10]; };\n"
|
||||||
"void foo(AB *ab)\n"
|
"void foo(AB *ab)\n"
|
||||||
|
|
Loading…
Reference in New Issue