#3521 implemented new check: wrong buffersize to pipe() function provided.
This commit is contained in:
parent
452dc23742
commit
f451dd1137
|
@ -523,6 +523,51 @@ void CheckOther::sizeofForNumericParameterError(const Token *tok)
|
|||
" and 'sizeof(char)' can return different results.");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// This check detects errors on POSIX systems, when a pipe command called
|
||||
// with a wrong dimensioned file descriptor array. The pipe command requires
|
||||
// exactly an integer array of dimension two as parameter.
|
||||
//
|
||||
// References:
|
||||
// - http://linux.die.net/man/2/pipe
|
||||
// - ticket #3521
|
||||
//---------------------------------------------------------------------------
|
||||
void CheckOther::checkPipeParameterSize()
|
||||
{
|
||||
if (!_settings->isEnabled("warning")
|
||||
|| !_settings->standards.posix)
|
||||
return;
|
||||
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "pipe ( %var% )") ||
|
||||
Token::Match(tok, "pipe2 ( %var% ,")) {
|
||||
const Token * const varTok = tok->tokAt(2);
|
||||
|
||||
const Variable *var = varTok->variable();
|
||||
MathLib::bigint dim;
|
||||
if (var && (var->isArray() || var->isPointer()) && ((dim=var->dimension(0U)) < 2)) {
|
||||
const std::string strDim = MathLib::longToString(dim);
|
||||
checkPipeParameterSizeError(varTok,varTok->str(), strDim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::checkPipeParameterSizeError(const Token *tok, const std::string &strVarName, const std::string &strDim)
|
||||
{
|
||||
reportError(tok, Severity::error,
|
||||
"wrongPipeParameterSize", "Variable " + strVarName + " must have size 2 when it is used as parameter of pipe() command.\n"
|
||||
"The pipe()/pipe2() system command takes an argument, which is an array of exactly two integers."
|
||||
"\nThe variable " + strVarName + " is an array of size "
|
||||
+ strDim + ", which does not match."
|
||||
);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
void CheckOther::checkSizeofForArrayParameter()
|
||||
|
|
|
@ -110,6 +110,7 @@ public:
|
|||
checkOther.checkSwitchCaseFallThrough();
|
||||
checkOther.checkAlwaysTrueOrFalseStringCompare();
|
||||
checkOther.checkModuloAlwaysTrueFalse();
|
||||
checkOther.checkPipeParameterSize();
|
||||
|
||||
checkOther.checkAssignBoolToPointer();
|
||||
checkOther.checkBitwiseOnBoolean();
|
||||
|
@ -297,11 +298,15 @@ public:
|
|||
/** @brief %Check that variadic function calls don't use NULL. If NULL is #defined as 0 and the function expects a pointer, the behaviour is undefined. */
|
||||
void checkVarFuncNullUB();
|
||||
|
||||
/** @brief %Check that calling the POSIX pipe() system call is called with an integer array of size two. */
|
||||
void checkPipeParameterSize();
|
||||
|
||||
private:
|
||||
bool isUnsigned(const Variable *var) const;
|
||||
bool isSigned(const Variable *var) const;
|
||||
|
||||
// Error messages..
|
||||
void checkPipeParameterSizeError(const Token *tok, const std::string &strVarName, const std::string &strDim);
|
||||
void oppositeInnerConditionError(const Token *tok);
|
||||
void clarifyCalculationError(const Token *tok, const std::string &op);
|
||||
void clarifyConditionError(const Token *tok, bool assign, bool boolop);
|
||||
|
@ -392,6 +397,7 @@ private:
|
|||
c.doubleFreeError(0, "varname");
|
||||
c.invalidPointerCastError(0, "float", "double", false);
|
||||
c.negativeBitwiseShiftError(0);
|
||||
c.checkPipeParameterSizeError(0, "varname", "dimension");
|
||||
|
||||
//performance
|
||||
c.redundantCopyError(0, "varname");
|
||||
|
@ -469,6 +475,7 @@ private:
|
|||
"* free() or delete of an invalid memory location\n"
|
||||
"* double free() or double closedir()\n"
|
||||
"* bitwise operation with negative right operand\n"
|
||||
"* provide wrong dimensioned array to pipe() system command (--std=posix)\n"
|
||||
|
||||
//performance
|
||||
"* redundant data copying for const variable\n"
|
||||
|
|
|
@ -194,6 +194,8 @@ private:
|
|||
TEST_CASE(redundantMemWrite);
|
||||
|
||||
TEST_CASE(varFuncNullUB);
|
||||
|
||||
TEST_CASE(checkPipeParameterSize); // ticket #3521
|
||||
}
|
||||
|
||||
void check(const char code[], const char *filename = NULL, bool experimental = false, bool inconclusive = true, bool posix = false) {
|
||||
|
@ -6977,6 +6979,56 @@ private:
|
|||
"void b() { a(NULL, 2); }");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void checkPipeParameterSize() { // #3521
|
||||
check("void f(){\n"
|
||||
"int pipefd[1];\n" //<-- array of two integers is needed
|
||||
"if (pipe(pipefd) == -1) {\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
"}",NULL,false,false,true);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Variable pipefd must have size 2 when it is used as parameter of pipe() command.\n", errout.str());
|
||||
|
||||
check("void f(){\n"
|
||||
"int pipefd[2];\n"
|
||||
"if (pipe(pipefd) == -1) {\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
"}",NULL,false,false,true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f(){\n"
|
||||
"int pipefd[20];\n"
|
||||
"if (pipe(pipefd) == -1) {\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
"}",NULL,false,false,true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f(){\n"
|
||||
"int pipefd[1];\n" //<-- array of two integers is needed
|
||||
"if (pipe2(pipefd,0) == -1) {\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
"}",NULL,false,false,true);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Variable pipefd must have size 2 when it is used as parameter of pipe() command.\n", errout.str());
|
||||
|
||||
check("void f(){\n"
|
||||
"int pipefd[2];\n"
|
||||
"if (pipe2(pipefd,0) == -1) {\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
"}",NULL,false,false,true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f(){\n"
|
||||
"int pipefd[20];\n"
|
||||
"if (pipe2(pipefd,0) == -1) {\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
"}",NULL,false,false,true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestOther)
|
||||
|
|
Loading…
Reference in New Issue