Bug hunting; When passing uninitialized data to unknown function it is inconclusive if that would be a problem for the function or not
This commit is contained in:
parent
0009b4c8af
commit
4465d033f6
|
@ -254,6 +254,7 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uninitialized function argument
|
// Uninitialized function argument
|
||||||
|
bool inconclusive = false;
|
||||||
if (Token::Match(tok->astParent(), "[,(]")) {
|
if (Token::Match(tok->astParent(), "[,(]")) {
|
||||||
const Token *parent = tok->astParent();
|
const Token *parent = tok->astParent();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -271,10 +272,16 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine:
|
||||||
const Variable *argvar = parent->astOperand1()->function()->getArgumentVar(count);
|
const Variable *argvar = parent->astOperand1()->function()->getArgumentVar(count);
|
||||||
if (argvar && argvar->isReference() && !argvar->isConst())
|
if (argvar && argvar->isReference() && !argvar->isConst())
|
||||||
return;
|
return;
|
||||||
if (uninitData && argvar && !argvar->isConst())
|
if (uninitData && argvar && !argvar->isConst()) {
|
||||||
return;
|
if (parent->astOperand1()->function()->hasBody())
|
||||||
if (!uninitStructMember.empty() && dataBase->isC() && argvar && !argvar->isConst())
|
return;
|
||||||
return;
|
inconclusive = true;
|
||||||
|
}
|
||||||
|
if (!uninitStructMember.empty() && dataBase->isC() && argvar && !argvar->isConst()) {
|
||||||
|
if (parent->astOperand1()->function()->hasBody())
|
||||||
|
return;
|
||||||
|
inconclusive = true;
|
||||||
|
}
|
||||||
} else if (uninitData) {
|
} else if (uninitData) {
|
||||||
if (dataBase->settings->library.getFunction(parent->astOperand1()))
|
if (dataBase->settings->library.getFunction(parent->astOperand1()))
|
||||||
return;
|
return;
|
||||||
|
@ -285,6 +292,9 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inconclusive && !dataBase->settings->inconclusive)
|
||||||
|
return;
|
||||||
|
|
||||||
// Avoid FP for array declaration
|
// Avoid FP for array declaration
|
||||||
const Token *parent = tok->astParent();
|
const Token *parent = tok->astParent();
|
||||||
while (parent && parent->str() == "[")
|
while (parent && parent->str() == "[")
|
||||||
|
@ -292,13 +302,15 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine:
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const std::string inconclusiveMessage(inconclusive ? ". It is inconclusive if there would be a problem in the function call." : "");
|
||||||
|
|
||||||
if (!uninitStructMember.empty()) {
|
if (!uninitStructMember.empty()) {
|
||||||
dataBase->reportError(tok,
|
dataBase->reportError(tok,
|
||||||
Severity::SeverityType::error,
|
Severity::SeverityType::error,
|
||||||
"bughuntingUninitStructMember",
|
"bughuntingUninitStructMember",
|
||||||
"Cannot determine that '" + tok->expressionString() + "." + uninitStructMember + "' is initialized",
|
"Cannot determine that '" + tok->expressionString() + "." + uninitStructMember + "' is initialized" + inconclusiveMessage,
|
||||||
CWE_USE_OF_UNINITIALIZED_VARIABLE,
|
CWE_USE_OF_UNINITIALIZED_VARIABLE,
|
||||||
false,
|
inconclusive,
|
||||||
value.type == ExprEngine::ValueType::BailoutValue);
|
value.type == ExprEngine::ValueType::BailoutValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -310,9 +322,9 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine:
|
||||||
dataBase->reportError(tok,
|
dataBase->reportError(tok,
|
||||||
Severity::SeverityType::error,
|
Severity::SeverityType::error,
|
||||||
"bughuntingUninit",
|
"bughuntingUninit",
|
||||||
"Cannot determine that '" + uninitexpr + "' is initialized",
|
"Cannot determine that '" + uninitexpr + "' is initialized" + inconclusiveMessage,
|
||||||
CWE_USE_OF_UNINITIALIZED_VARIABLE,
|
CWE_USE_OF_UNINITIALIZED_VARIABLE,
|
||||||
false,
|
inconclusive,
|
||||||
value.type == ExprEngine::ValueType::BailoutValue);
|
value.type == ExprEngine::ValueType::BailoutValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ private:
|
||||||
|
|
||||||
void run() OVERRIDE {
|
void run() OVERRIDE {
|
||||||
#ifdef USE_Z3
|
#ifdef USE_Z3
|
||||||
|
settings.inconclusive = true;
|
||||||
LOAD_LIB_2(settings.library, "std.cfg");
|
LOAD_LIB_2(settings.library, "std.cfg");
|
||||||
TEST_CASE(uninit);
|
TEST_CASE(uninit);
|
||||||
TEST_CASE(uninit_array);
|
TEST_CASE(uninit_array);
|
||||||
|
@ -86,7 +87,7 @@ private:
|
||||||
|
|
||||||
check("char foo(char id[]);\n"
|
check("char foo(char id[]);\n"
|
||||||
"void bar() { char data[10]; foo(data); }");
|
"void bar() { char data[10]; foo(data); }");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (error, inconclusive) Cannot determine that 'data[0]' is initialized. It is inconclusive if there would be a problem in the function call.\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { if (p) *p=0; }");
|
check("void foo(int *p) { if (p) *p=0; }");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
Loading…
Reference in New Issue