Fixed #389: Providing negative value to memory allocation function.
This commit is contained in:
parent
b3bfd5014d
commit
6ca7daec10
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue