Fixed #389: Providing negative value to memory allocation function.

This commit is contained in:
Martin Ettl 2014-02-01 22:38:29 +01:00
parent b3bfd5014d
commit 6ca7daec10
3 changed files with 60 additions and 2 deletions

View File

@ -214,6 +214,15 @@ void CheckBufferOverrun::argumentSizeError(const Token *tok, const std::string &
reportError(tok, Severity::warning, "argumentSize", "The array '" + varname + "' is too small, the function '" + functionName + "' expects a bigger one.");
}
void CheckBufferOverrun::negativeMemoryAllocationSizeError(const Token *tok)
{
reportError(tok, Severity::error, "negativeMemoryAllocationSize",
"Memory allocation size have to be greater or equal to 0.\n"
"Memory allocation size have to be greater or equal to 0."
"The allocation size of memory have to be greater or equal to 0 because"
"negative size have no speficied behaviour.");
}
//---------------------------------------------------------------------------
@ -1503,6 +1512,9 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
type = tok->strAt(4);
var = tok->next()->variable();
nextTok = 8;
if (size < 0) {
negativeMemoryAllocationSizeError(tok->next()->next());
}
} else if (Token::Match(tok, "[*;{}] %var% = new %type% ( %num% )")) {
size = 1;
type = tok->strAt(4);
@ -1521,6 +1533,10 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
var = tok->next()->variable();
nextTok = 7;
if (size < 0) {
negativeMemoryAllocationSizeError(tok->next()->next());
}
/** @todo false negatives: this may be too conservative */
if (!var || var->typeEndToken()->str() != "*" || var->typeStartToken()->next() != var->typeEndToken())
continue;
@ -1531,9 +1547,13 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
// malloc() gets count of bytes and not count of
// elements, so we should calculate count of elements
// manually
unsigned int sizeOfType = _tokenizer->sizeOfType(var->typeStartToken());
if (sizeOfType > 0)
const unsigned int sizeOfType = _tokenizer->sizeOfType(var->typeStartToken());
if (sizeOfType > 0) {
size /= static_cast<int>(sizeOfType);
}
if (size < 0) {
negativeMemoryAllocationSizeError(tok->next()->next());
}
} else {
continue;
}

View File

@ -218,6 +218,7 @@ private:
void bufferOverrunError(const Token *tok, const std::string &varnames = "");
void bufferOverrunError(const std::list<const Token *> &callstack, const std::string &varnames = "");
void strncatUsageError(const Token *tok);
void negativeMemoryAllocationSizeError(const Token *tok); // provide a negative value to memory allocation function
void outOfBoundsError(const Token *tok, const std::string &what, const bool show_size_info, const MathLib::bigint &supplied_size, const MathLib::bigint &actual_size);
void sizeArgumentAsCharError(const Token *tok);
void terminateStrncpyError(const Token *tok, const std::string &varname);
@ -251,6 +252,7 @@ public:
c.possibleReadlinkBufferOverrunError(0, "readlink", "buffer");
c.argumentSizeError(0, "function", "array");
c.writeOutsideBufferSizeError(0,2,3,"write");
c.negativeMemoryAllocationSizeError(0);
}
private:

View File

@ -267,6 +267,8 @@ private:
TEST_CASE(readlinkat);
TEST_CASE(writeOutsideBufferSize)
TEST_CASE(negativeMemoryAllocationSizeError) // #389
}
@ -4111,6 +4113,40 @@ private:
"}");
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Writing 1 bytes outside buffer size.\n", "", errout.str());
}
void negativeMemoryAllocationSizeError() { // #389
check("void f()\n"
"{\n"
" int *a;\n"
" a = new int[-1];\n"
" delete [] a;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size have to be greater or equal to 0.\n", errout.str());
check("void f()\n"
"{\n"
" int *a;\n"
" a = malloc( -10 );\n"
" free(a);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size have to be greater or equal to 0.\n", errout.str());
check("void f()\n"
"{\n"
" int *a;\n"
" a = malloc( -10);\n"
" free(a);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size have to be greater or equal to 0.\n", errout.str());
check("void f()\n"
"{\n"
" int *a;\n"
" a = alloca( -10 );\n"
" free(a);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size have to be greater or equal to 0.\n", errout.str());
}
};
REGISTER_TEST(TestBufferOverrun)