New check: negative size in array declaration. Ticket #1760
This commit is contained in:
parent
e837bad01d
commit
baa1ae079d
|
@ -970,6 +970,33 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Negative size in array declarations
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void CheckBufferOverrun::negativeArraySize()
|
||||
{
|
||||
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
for (unsigned int i = 1; i <= _tokenizer->varIdCount(); i++) {
|
||||
const Variable * const var = symbolDatabase->getVariableFromVarId(i);
|
||||
if (!var || !var->isArray())
|
||||
continue;
|
||||
const Token * const nameToken = var->nameToken();
|
||||
if (!Token::Match(nameToken, "%var% [") || !nameToken->next()->astOperand2())
|
||||
continue;
|
||||
const ValueFlow::Value *sz = nameToken->next()->astOperand2()->getValueLE(-1,_settings);
|
||||
if (!sz)
|
||||
continue;
|
||||
negativeArraySizeError(nameToken);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckBufferOverrun::negativeArraySizeError(const Token *tok)
|
||||
{
|
||||
reportError(tok, Severity::error, "negativeArraySize",
|
||||
"Declaration of array '" + (tok ? tok->str() : std::string()) + "' with negative size is undefined behaviour");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Checking member variables of structs.
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
checkBufferOverrun.bufferOverrun();
|
||||
checkBufferOverrun.bufferOverrun2();
|
||||
checkBufferOverrun.arrayIndexThenCheck();
|
||||
checkBufferOverrun.negativeArraySize();
|
||||
}
|
||||
|
||||
/** @brief %Check for buffer overruns */
|
||||
|
@ -71,6 +72,9 @@ public:
|
|||
/** @brief Using array index before bounds check */
|
||||
void arrayIndexThenCheck();
|
||||
|
||||
/** @brief negative size for array */
|
||||
void negativeArraySize();
|
||||
|
||||
/** @brief %Check for buffer overruns by inspecting execution paths */
|
||||
void executionPaths();
|
||||
|
||||
|
@ -218,6 +222,7 @@ private:
|
|||
void bufferOverrunError(const std::list<const Token *> &callstack, const std::string &varnames = emptyString);
|
||||
void strncatUsageError(const Token *tok);
|
||||
void negativeMemoryAllocationSizeError(const Token *tok); // provide a negative value to memory allocation function
|
||||
void negativeArraySizeError(const Token *tok);
|
||||
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 +256,7 @@ public:
|
|||
c.possibleBufferOverrunError(0, "source", "destination", false);
|
||||
c.argumentSizeError(0, "function", "array");
|
||||
c.negativeMemoryAllocationSizeError(0);
|
||||
c.negativeArraySizeError(0);
|
||||
c.reportError(nullptr, Severity::warning, "arrayIndexOutOfBoundsCond", "Array 'x[10]' accessed at index 20, which is out of bounds. Otherwise condition 'y==20' is redundant.");
|
||||
}
|
||||
private:
|
||||
|
|
|
@ -60,10 +60,8 @@ private:
|
|||
}
|
||||
|
||||
// Check for buffer overruns..
|
||||
CheckBufferOverrun checkBufferOverrun(&tokenizer, &settings, this);
|
||||
checkBufferOverrun.bufferOverrun();
|
||||
checkBufferOverrun.bufferOverrun2();
|
||||
checkBufferOverrun.arrayIndexThenCheck();
|
||||
CheckBufferOverrun checkBufferOverrun;
|
||||
checkBufferOverrun.runSimplifiedChecks(&tokenizer, &settings, this);
|
||||
}
|
||||
|
||||
void check(const char code[], const Settings &settings, const char filename[] = "test.cpp") {
|
||||
|
@ -246,6 +244,7 @@ private:
|
|||
TEST_CASE(bufferNotZeroTerminated);
|
||||
|
||||
TEST_CASE(negativeMemoryAllocationSizeError) // #389
|
||||
TEST_CASE(negativeArraySize);
|
||||
|
||||
TEST_CASE(garbage1) // #6303
|
||||
}
|
||||
|
@ -3806,6 +3805,14 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size is negative.\n", errout.str());
|
||||
}
|
||||
|
||||
void negativeArraySize() {
|
||||
check("void f(int sz) {\n" // #1760 - VLA
|
||||
" int a[sz];\n"
|
||||
"}\n"
|
||||
"void x() { f(-100); }");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Declaration of array 'a' with negative size is undefined behaviour\n", errout.str());
|
||||
}
|
||||
|
||||
void garbage1() {
|
||||
check("void foo() {\n"
|
||||
"char *a = malloc(10);\n"
|
||||
|
|
Loading…
Reference in New Issue