Merge pull request #233 from orbitcowboy/master
Fixed #389: Providing negative value to memory allocation function.
This commit is contained in:
commit
ec61143623
|
@ -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.");
|
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);
|
type = tok->strAt(4);
|
||||||
var = tok->next()->variable();
|
var = tok->next()->variable();
|
||||||
nextTok = 8;
|
nextTok = 8;
|
||||||
|
if (size < 0) {
|
||||||
|
negativeMemoryAllocationSizeError(tok->next()->next());
|
||||||
|
}
|
||||||
} else if (Token::Match(tok, "[*;{}] %var% = new %type% ( %num% )")) {
|
} else if (Token::Match(tok, "[*;{}] %var% = new %type% ( %num% )")) {
|
||||||
size = 1;
|
size = 1;
|
||||||
type = tok->strAt(4);
|
type = tok->strAt(4);
|
||||||
|
@ -1521,6 +1533,10 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
|
||||||
var = tok->next()->variable();
|
var = tok->next()->variable();
|
||||||
nextTok = 7;
|
nextTok = 7;
|
||||||
|
|
||||||
|
if (size < 0) {
|
||||||
|
negativeMemoryAllocationSizeError(tok->next()->next());
|
||||||
|
}
|
||||||
|
|
||||||
/** @todo false negatives: this may be too conservative */
|
/** @todo false negatives: this may be too conservative */
|
||||||
if (!var || var->typeEndToken()->str() != "*" || var->typeStartToken()->next() != var->typeEndToken())
|
if (!var || var->typeEndToken()->str() != "*" || var->typeStartToken()->next() != var->typeEndToken())
|
||||||
continue;
|
continue;
|
||||||
|
@ -1531,9 +1547,13 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
|
||||||
// malloc() gets count of bytes and not count of
|
// malloc() gets count of bytes and not count of
|
||||||
// elements, so we should calculate count of elements
|
// elements, so we should calculate count of elements
|
||||||
// manually
|
// manually
|
||||||
unsigned int sizeOfType = _tokenizer->sizeOfType(var->typeStartToken());
|
const unsigned int sizeOfType = _tokenizer->sizeOfType(var->typeStartToken());
|
||||||
if (sizeOfType > 0)
|
if (sizeOfType > 0) {
|
||||||
size /= static_cast<int>(sizeOfType);
|
size /= static_cast<int>(sizeOfType);
|
||||||
|
}
|
||||||
|
if (size < 0) {
|
||||||
|
negativeMemoryAllocationSizeError(tok->next()->next());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,6 +218,7 @@ private:
|
||||||
void bufferOverrunError(const Token *tok, const std::string &varnames = "");
|
void bufferOverrunError(const Token *tok, const std::string &varnames = "");
|
||||||
void bufferOverrunError(const std::list<const Token *> &callstack, const std::string &varnames = "");
|
void bufferOverrunError(const std::list<const Token *> &callstack, const std::string &varnames = "");
|
||||||
void strncatUsageError(const Token *tok);
|
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 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 sizeArgumentAsCharError(const Token *tok);
|
||||||
void terminateStrncpyError(const Token *tok, const std::string &varname);
|
void terminateStrncpyError(const Token *tok, const std::string &varname);
|
||||||
|
@ -251,6 +252,7 @@ public:
|
||||||
c.possibleReadlinkBufferOverrunError(0, "readlink", "buffer");
|
c.possibleReadlinkBufferOverrunError(0, "readlink", "buffer");
|
||||||
c.argumentSizeError(0, "function", "array");
|
c.argumentSizeError(0, "function", "array");
|
||||||
c.writeOutsideBufferSizeError(0,2,3,"write");
|
c.writeOutsideBufferSizeError(0,2,3,"write");
|
||||||
|
c.negativeMemoryAllocationSizeError(0);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -267,6 +267,8 @@ private:
|
||||||
TEST_CASE(readlinkat);
|
TEST_CASE(readlinkat);
|
||||||
|
|
||||||
TEST_CASE(writeOutsideBufferSize)
|
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());
|
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)
|
REGISTER_TEST(TestBufferOverrun)
|
||||||
|
|
Loading…
Reference in New Issue