Buffer Overrun: Broke out the checking for negative array index
This commit is contained in:
parent
af3f2faa41
commit
b6ab419a06
|
@ -210,7 +210,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
|
|||
if (Token::Match(tok, "%varid% [ %num% ]", varid))
|
||||
{
|
||||
int index = MathLib::toLongNumber(tok->strAt(2));
|
||||
if (index < 0 || index >= size)
|
||||
if (index >= size)
|
||||
{
|
||||
arrayIndexOutOfBounds(tok, size, index);
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
|
|||
else if (Token::Match(tok, (varnames + " [ %num% ]").c_str()))
|
||||
{
|
||||
int index = MathLib::toLongNumber(tok->strAt(2 + varc));
|
||||
if (index < 0 || index >= size)
|
||||
if (index >= size)
|
||||
{
|
||||
arrayIndexOutOfBounds(tok->tokAt(varc), size, index);
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
|
|||
else if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), (varnames + " [ %num% ]").c_str()))
|
||||
{
|
||||
int index = MathLib::toLongNumber(tok->strAt(3 + varc));
|
||||
if (index < 0 || index >= size)
|
||||
if (index >= size)
|
||||
{
|
||||
arrayIndexOutOfBounds(tok->tokAt(1 + varc), size, index);
|
||||
}
|
||||
|
@ -1265,6 +1265,27 @@ void CheckBufferOverrun::checkSprintfCall(const Token *tok, int size)
|
|||
}
|
||||
|
||||
|
||||
void CheckBufferOverrun::negativeIndexError(const Token *tok, long index)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "Array index " << index << " corresponds with " << (unsigned long)index << ", which is likely out of bounds";
|
||||
reportError(tok, Severity::error, "negativeIndex", ostr.str());
|
||||
}
|
||||
|
||||
void CheckBufferOverrun::negativeIndex()
|
||||
{
|
||||
const char pattern[] = "[ %num% ]";
|
||||
for (const Token *tok = Token::findmatch(_tokenizer->tokens(), pattern); tok; tok = Token::findmatch(tok->next(),pattern))
|
||||
{
|
||||
const long index = MathLib::toLongNumber(tok->next()->str());
|
||||
if (index < 0)
|
||||
{
|
||||
negativeIndexError(tok, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#include "executionpath.h"
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
{
|
||||
CheckBufferOverrun checkBufferOverrun(tokenizer, settings, errorLogger);
|
||||
checkBufferOverrun.bufferOverrun();
|
||||
checkBufferOverrun.negativeIndex();
|
||||
|
||||
/** ExecutionPath checking.. */
|
||||
checkBufferOverrun.executionPaths();
|
||||
|
@ -94,6 +95,9 @@ public:
|
|||
/** Check for buffer overruns - locate global variables and local function variables and check them with the checkScope function */
|
||||
void checkGlobalAndLocalVariable();
|
||||
|
||||
/** Check for negative index */
|
||||
void negativeIndex();
|
||||
|
||||
/** Check for buffer overruns - this is the function that performs the actual checking */
|
||||
void checkScope(const Token *tok, const std::vector<std::string> &varname, const int size, const int total_size, unsigned int varid);
|
||||
|
||||
|
@ -152,6 +156,7 @@ public:
|
|||
void outOfBounds(const Token *tok, const std::string &what);
|
||||
void sizeArgumentAsChar(const Token *tok);
|
||||
void terminateStrncpyError(const Token *tok);
|
||||
void negativeIndexError(const Token *tok, long index);
|
||||
|
||||
void getErrorMessages()
|
||||
{
|
||||
|
@ -162,6 +167,7 @@ public:
|
|||
outOfBounds(0, "index");
|
||||
sizeArgumentAsChar(0);
|
||||
terminateStrncpyError(0);
|
||||
negativeIndexError(0, -1);
|
||||
}
|
||||
|
||||
std::string name() const
|
||||
|
|
|
@ -58,6 +58,7 @@ private:
|
|||
settings._checkCodingStyle = true;
|
||||
CheckBufferOverrun checkBufferOverrun(&tokenizer, &settings, this);
|
||||
checkBufferOverrun.bufferOverrun();
|
||||
checkBufferOverrun.negativeIndex();
|
||||
}
|
||||
|
||||
void run()
|
||||
|
@ -780,8 +781,9 @@ private:
|
|||
" a[-1] = 0;\n" // negative index
|
||||
" a[128] = 0;\n" // 128 > CHAR_MAX
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'a[128]' index -1 out of bounds\n"
|
||||
"[test.cpp:4]: (error) Array 'a[128]' index 128 out of bounds\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[128]' index 128 out of bounds\n"
|
||||
"[test.cpp:3]: (error) Array index -1 corresponds with 4294967295, which is likely out of bounds\n", errout.str());
|
||||
|
||||
}
|
||||
else // plain char is unsigned
|
||||
{
|
||||
|
@ -799,40 +801,40 @@ private:
|
|||
" a[-1] = 0;\n" // negative index
|
||||
" a[128] = 0;\n" // 128 > SCHAR_MAX
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'a[128]' index -1 out of bounds\n"
|
||||
"[test.cpp:4]: (error) Array 'a[128]' index 128 out of bounds\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[128]' index 128 out of bounds\n"
|
||||
"[test.cpp:3]: (error) Array index -1 corresponds with 4294967295, which is likely out of bounds\n", errout.str());
|
||||
|
||||
check("void f(unsigned char n) {\n"
|
||||
" int a[n];\n" // n <= UCHAR_MAX
|
||||
" a[-1] = 0;\n" // negative index
|
||||
" a[256] = 0;\n" // 256 > UCHAR_MAX
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'a[256]' index -1 out of bounds\n"
|
||||
"[test.cpp:4]: (error) Array 'a[256]' index 256 out of bounds\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[256]' index 256 out of bounds\n"
|
||||
"[test.cpp:3]: (error) Array index -1 corresponds with 4294967295, which is likely out of bounds\n", errout.str());
|
||||
|
||||
check("void f(short n) {\n"
|
||||
" int a[n];\n" // n <= SHRT_MAX
|
||||
" a[-1] = 0;\n" // negative index
|
||||
" a[32768] = 0;\n" // 32768 > SHRT_MAX
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'a[32768]' index -1 out of bounds\n"
|
||||
"[test.cpp:4]: (error) Array 'a[32768]' index 32768 out of bounds\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[32768]' index 32768 out of bounds\n"
|
||||
"[test.cpp:3]: (error) Array index -1 corresponds with 4294967295, which is likely out of bounds\n", errout.str());
|
||||
|
||||
check("void f(unsigned short n) {\n"
|
||||
" int a[n];\n" // n <= USHRT_MAX
|
||||
" a[-1] = 0;\n" // negative index
|
||||
" a[65536] = 0;\n" // 65536 > USHRT_MAX
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'a[65536]' index -1 out of bounds\n"
|
||||
"[test.cpp:4]: (error) Array 'a[65536]' index 65536 out of bounds\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[65536]' index 65536 out of bounds\n"
|
||||
"[test.cpp:3]: (error) Array index -1 corresponds with 4294967295, which is likely out of bounds\n", errout.str());
|
||||
|
||||
check("void f(signed short n) {\n"
|
||||
" int a[n];\n" // n <= SHRT_MAX
|
||||
" a[-1] = 0;\n" // negative index
|
||||
" a[32768] = 0;\n" // 32768 > SHRT_MAX
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'a[32768]' index -1 out of bounds\n"
|
||||
"[test.cpp:4]: (error) Array 'a[32768]' index 32768 out of bounds\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[32768]' index 32768 out of bounds\n"
|
||||
"[test.cpp:3]: (error) Array index -1 corresponds with 4294967295, which is likely out of bounds\n", errout.str());
|
||||
|
||||
if (sizeof(int) == 4)
|
||||
{
|
||||
|
@ -840,19 +842,19 @@ private:
|
|||
" int a[n];\n" // n <= INT_MAX
|
||||
" a[-1] = 0;\n" // negative index
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'a[2147483647]' index -1 out of bounds\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array index -1 corresponds with 4294967295, which is likely out of bounds\n", errout.str());
|
||||
|
||||
check("void f(unsigned int n) {\n"
|
||||
" int a[n];\n" // n <= UINT_MAX
|
||||
" a[-1] = 0;\n" // negative index
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'a[2147483647]' index -1 out of bounds\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array index -1 corresponds with 4294967295, which is likely out of bounds\n", errout.str());
|
||||
|
||||
check("void f(signed int n) {\n"
|
||||
" int a[n];\n" // n <= INT_MAX
|
||||
" a[-1] = 0;\n" // negative index
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'a[2147483647]' index -1 out of bounds\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array index -1 corresponds with 4294967295, which is likely out of bounds\n", errout.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1014,7 @@ private:
|
|||
" char data[8];\n"
|
||||
" data[-1] = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'data[8]' index -1 out of bounds\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array index -1 corresponds with 4294967295, which is likely out of bounds\n", errout.str());
|
||||
}
|
||||
|
||||
void array_index_for_decr()
|
||||
|
|
Loading…
Reference in New Issue