2009-01-31 20:29:27 +01:00
|
|
|
/*
|
|
|
|
* Cppcheck - A tool for static C/C++ code analysis
|
2019-02-09 07:24:06 +01:00
|
|
|
* Copyright (C) 2007-2019 Cppcheck team.
|
2009-01-31 20:29:27 +01:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2009-09-27 17:08:31 +02:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2009-01-31 20:29:27 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
2013-09-04 20:59:49 +02:00
|
|
|
#ifndef checkbufferoverrunH
|
|
|
|
#define checkbufferoverrunH
|
2009-01-31 20:29:27 +01:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2009-03-20 17:35:53 +01:00
|
|
|
#include "check.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "config.h"
|
|
|
|
#include "errorlogger.h"
|
2010-11-21 11:48:27 +01:00
|
|
|
#include "mathlib.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "tokenize.h"
|
Mapped toomanyconfigs ,AssignmentAddressToInteger
,AssignmentIntegerToAddress ,CastIntegerToAddressAtReturn
,CastAddressToIntegerAtReturn ,assertWithSideEffect ,assignmentInAssert
,uselessAssignmentArg ,uselessAssignmentPtrArg
,comparisonOfFuncReturningBoolError
,comparisonOfTwoFuncsReturningBoolError ,comparisonOfBoolWithBoolError
,incrementboolean ,comparisonOfBoolWithInt ,compareBoolExpressionWithInt
,negativeIndex ,pointerOutOfBounds ,arrayIndexThenCheck
,possibleBufferAccessOutOfBounds ,argumentSize
,arrayIndexOutOfBoundsCond ,noConstructor ,copyCtorPointerCopying
,noCopyConstructor ,uninitMemberVar ,operatorEqVarError
,unusedPrivateFunction ,memsetClassFloat ,mallocOnClassWarning
,operatorEq ,thisSubtraction ,operatorEqRetRefThis ,operatorEqToSelf
,useInitializationList ,duplInheritedMember ,assignIfError
,comparisonError ,multiCondition ,mismatchingBitAnd
,oppositeInnerCondition ,incorrectLogicOperator ,redundantCondition
,moduloAlwaysTrueFalse to their CWEs ids.
2016-02-20 23:56:36 +01:00
|
|
|
|
2017-05-27 04:33:47 +02:00
|
|
|
#include <cstddef>
|
2009-02-11 06:16:10 +01:00
|
|
|
#include <list>
|
2017-05-27 04:33:47 +02:00
|
|
|
#include <map>
|
2010-02-14 19:58:17 +01:00
|
|
|
#include <string>
|
2017-05-27 04:33:47 +02:00
|
|
|
#include <vector>
|
|
|
|
|
2009-01-31 20:29:27 +01:00
|
|
|
|
2009-07-17 10:49:01 +02:00
|
|
|
/// @addtogroup Checks
|
|
|
|
/// @{
|
|
|
|
|
2010-03-13 21:42:59 +01:00
|
|
|
/**
|
|
|
|
* @brief buffer overruns and array index out of bounds
|
|
|
|
*
|
|
|
|
* Buffer overrun and array index out of bounds are pretty much the same.
|
|
|
|
* But I generally use 'array index' if the code contains []. And the given
|
|
|
|
* index is out of bounds.
|
|
|
|
* I generally use 'buffer overrun' if you for example call a strcpy or
|
|
|
|
* other function and pass a buffer and reads or writes too much data.
|
|
|
|
*/
|
2012-06-10 14:19:09 +02:00
|
|
|
class CPPCHECKLIB CheckBufferOverrun : public Check {
|
2009-01-31 20:29:27 +01:00
|
|
|
public:
|
2009-03-20 17:35:53 +01:00
|
|
|
|
2009-03-21 07:53:23 +01:00
|
|
|
/** This constructor is used when registering the CheckClass */
|
2018-06-17 17:20:16 +02:00
|
|
|
CheckBufferOverrun() : Check(myName()) {
|
2013-08-07 16:27:37 +02:00
|
|
|
}
|
2009-03-20 17:35:53 +01:00
|
|
|
|
2010-03-17 22:16:18 +01:00
|
|
|
/** This constructor is used when running checks. */
|
2009-07-13 16:00:15 +02:00
|
|
|
CheckBufferOverrun(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
2018-06-17 17:20:16 +02:00
|
|
|
: Check(myName(), tokenizer, settings, errorLogger) {
|
2013-08-07 16:27:37 +02:00
|
|
|
}
|
2009-03-20 17:35:53 +01:00
|
|
|
|
2019-03-12 18:58:14 +01:00
|
|
|
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE {
|
2009-07-13 16:00:15 +02:00
|
|
|
CheckBufferOverrun checkBufferOverrun(tokenizer, settings, errorLogger);
|
2019-03-09 22:14:02 +01:00
|
|
|
checkBufferOverrun.arrayIndex();
|
|
|
|
checkBufferOverrun.bufferOverflow();
|
2019-03-11 19:20:06 +01:00
|
|
|
checkBufferOverrun.arrayIndexThenCheck();
|
2019-03-12 21:15:26 +01:00
|
|
|
checkBufferOverrun.stringNotZeroTerminated();
|
2009-03-20 17:35:53 +01:00
|
|
|
}
|
2009-01-31 20:29:27 +01:00
|
|
|
|
2019-03-12 18:58:14 +01:00
|
|
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE {
|
2019-03-09 22:14:02 +01:00
|
|
|
(void)tokenizer;
|
|
|
|
(void)settings;
|
|
|
|
(void)errorLogger;
|
2016-07-07 19:38:15 +02:00
|
|
|
}
|
2010-03-13 21:42:59 +01:00
|
|
|
|
2019-01-12 07:37:42 +01:00
|
|
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const OVERRIDE {
|
2016-05-07 16:30:54 +02:00
|
|
|
CheckBufferOverrun c(nullptr, settings, errorLogger);
|
2019-03-09 22:14:02 +01:00
|
|
|
c.arrayIndexError(nullptr, nullptr, nullptr);
|
|
|
|
c.negativeIndexError(nullptr, nullptr, nullptr);
|
2019-03-11 19:20:06 +01:00
|
|
|
c.arrayIndexThenCheckError(nullptr, "i");
|
2009-03-22 08:20:15 +01:00
|
|
|
}
|
2019-03-09 22:14:02 +01:00
|
|
|
|
2012-03-17 21:55:08 +01:00
|
|
|
private:
|
2009-06-12 12:19:37 +02:00
|
|
|
|
2019-03-09 22:14:02 +01:00
|
|
|
void arrayIndex();
|
|
|
|
void arrayIndexError(const Token *tok, const Variable *var, const ValueFlow::Value *index);
|
|
|
|
void negativeIndexError(const Token *tok, const Variable *var, const ValueFlow::Value *negativeValue);
|
|
|
|
|
|
|
|
void bufferOverflow();
|
|
|
|
void bufferOverflowError(const Token *tok);
|
|
|
|
|
2019-03-11 19:20:06 +01:00
|
|
|
void arrayIndexThenCheck();
|
|
|
|
void arrayIndexThenCheckError(const Token *tok, const std::string &indexName);
|
|
|
|
|
2019-03-12 21:15:26 +01:00
|
|
|
void stringNotZeroTerminated();
|
|
|
|
void terminateStrncpyError(const Token *tok, const std::string &varname);
|
|
|
|
void bufferNotZeroTerminatedError(const Token *tok, const std::string &varname, const std::string &function);
|
|
|
|
|
|
|
|
|
2019-03-09 22:14:02 +01:00
|
|
|
size_t getBufferSize(const Token *bufTok) const;
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
static std::string myName() {
|
2009-06-12 15:20:08 +02:00
|
|
|
return "Bounds checking";
|
|
|
|
}
|
|
|
|
|
2019-01-12 07:37:42 +01:00
|
|
|
std::string classInfo() const OVERRIDE {
|
2014-05-22 09:13:29 +02:00
|
|
|
return "Out of bounds checking:\n"
|
2019-03-09 22:14:02 +01:00
|
|
|
"- Array index out of bounds\n"
|
|
|
|
"- Buffer overflow\n"
|
2019-03-11 19:20:06 +01:00
|
|
|
"- Dangerous usage of strncat()\n"
|
2019-03-12 21:15:26 +01:00
|
|
|
"- Using array index before checking it\n"
|
|
|
|
"- Partial string write that leads to buffer that is not zero terminated.\n";
|
2009-06-12 12:19:37 +02:00
|
|
|
}
|
2009-01-31 20:29:27 +01:00
|
|
|
};
|
2009-07-17 10:49:01 +02:00
|
|
|
/// @}
|
2009-01-31 20:29:27 +01:00
|
|
|
//---------------------------------------------------------------------------
|
2013-09-04 20:59:49 +02:00
|
|
|
#endif // checkbufferoverrunH
|