Fix so array access out of bounds for external arrays are detected again
This commit is contained in:
parent
7cae057615
commit
cc3ef7bbe8
|
@ -37,6 +37,10 @@
|
||||||
*/
|
*/
|
||||||
#define CHECK_WRONG_DATA(X) (X)
|
#define CHECK_WRONG_DATA(X) (X)
|
||||||
|
|
||||||
|
namespace tinyxml2 {
|
||||||
|
class XMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
/// @addtogroup Core
|
/// @addtogroup Core
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
@ -108,6 +112,11 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const {
|
||||||
|
(void)xmlElement;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void analyseWholeProgram(const std::list<FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger) {
|
virtual void analyseWholeProgram(const std::list<FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger) {
|
||||||
(void)fileInfo;
|
(void)fileInfo;
|
||||||
(void)settings;
|
(void)settings;
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <tinyxml2.h>
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -1966,6 +1967,38 @@ Check::FileInfo* CheckBufferOverrun::getFileInfo(const Tokenizer *tokenizer, con
|
||||||
return fileInfo;
|
return fileInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Check::FileInfo * CheckBufferOverrun::loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const
|
||||||
|
{
|
||||||
|
const std::string ArrayUsage("ArrayUsage");
|
||||||
|
const std::string ArraySize("ArraySize");
|
||||||
|
|
||||||
|
MyFileInfo *fileInfo = new MyFileInfo;
|
||||||
|
for (const tinyxml2::XMLElement *e = xmlElement->FirstChildElement(); e; e = e->NextSiblingElement()) {
|
||||||
|
if (e->Name() == ArrayUsage) {
|
||||||
|
const char *array = e->Attribute("array");
|
||||||
|
const char *arrayIndex = e->Attribute("index");
|
||||||
|
const char *fileName = e->Attribute("fileName");
|
||||||
|
const char *linenr = e->Attribute("linenr");
|
||||||
|
if (!array || !arrayIndex || !MathLib::isInt(arrayIndex) || !fileName || !linenr || !MathLib::isInt(linenr))
|
||||||
|
continue;
|
||||||
|
struct MyFileInfo::ArrayUsage arrayUsage;
|
||||||
|
arrayUsage.index = MathLib::toLongNumber(arrayIndex);
|
||||||
|
arrayUsage.fileName = fileName;
|
||||||
|
arrayUsage.linenr = MathLib::toLongNumber(linenr);
|
||||||
|
fileInfo->arrayUsage[array] = arrayUsage;
|
||||||
|
} else if (e->Name() == ArraySize) {
|
||||||
|
const char *array = e->Attribute("array");
|
||||||
|
const char *size = e->Attribute("size");
|
||||||
|
if (!array || !size || !MathLib::isInt(size))
|
||||||
|
continue;
|
||||||
|
fileInfo->arraySize[array] = MathLib::toLongNumber(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckBufferOverrun::analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings&, ErrorLogger &errorLogger)
|
void CheckBufferOverrun::analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings&, ErrorLogger &errorLogger)
|
||||||
{
|
{
|
||||||
// Merge all fileInfo
|
// Merge all fileInfo
|
||||||
|
|
|
@ -227,6 +227,8 @@ public:
|
||||||
/** @brief Parse current TU and extract file info */
|
/** @brief Parse current TU and extract file info */
|
||||||
Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const;
|
Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const;
|
||||||
|
|
||||||
|
Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const;
|
||||||
|
|
||||||
/** @brief Analyse all file infos for all TU */
|
/** @brief Analyse all file infos for all TU */
|
||||||
void analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger);
|
void analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger);
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,14 @@
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
|
||||||
#include "checkunusedfunctions.h"
|
#include "checkunusedfunctions.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "timer.h"
|
#include <tinyxml2.h>
|
||||||
#include "version.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_RULES
|
#ifdef HAVE_RULES
|
||||||
#define PCRE_STATIC
|
#define PCRE_STATIC
|
||||||
|
@ -742,6 +743,50 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::map<s
|
||||||
return;
|
return;
|
||||||
if (_settings.isEnabled("unusedFunction"))
|
if (_settings.isEnabled("unusedFunction"))
|
||||||
CheckUnusedFunctions::analyseWholeProgram(this, buildDir);
|
CheckUnusedFunctions::analyseWholeProgram(this, buildDir);
|
||||||
|
std::list<Check::FileInfo*> fileInfoList;
|
||||||
|
|
||||||
|
// Load all analyzer info data..
|
||||||
|
const std::string filesTxt(buildDir + "/files.txt");
|
||||||
|
std::ifstream fin(filesTxt.c_str());
|
||||||
|
std::string filesTxtLine;
|
||||||
|
while (std::getline(fin, filesTxtLine)) {
|
||||||
|
const std::string::size_type firstColon = filesTxtLine.find(':');
|
||||||
|
if (firstColon == std::string::npos)
|
||||||
|
continue;
|
||||||
|
const std::string::size_type lastColon = filesTxtLine.rfind(':');
|
||||||
|
if (firstColon == lastColon)
|
||||||
|
continue;
|
||||||
|
const std::string xmlfile = buildDir + '/' + filesTxtLine.substr(0,firstColon);
|
||||||
|
const std::string sourcefile = filesTxtLine.substr(lastColon+1);
|
||||||
|
|
||||||
|
tinyxml2::XMLDocument doc;
|
||||||
|
tinyxml2::XMLError error = doc.LoadFile(xmlfile.c_str());
|
||||||
|
if (error != tinyxml2::XML_SUCCESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const tinyxml2::XMLElement * const rootNode = doc.FirstChildElement();
|
||||||
|
if (rootNode == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (const tinyxml2::XMLElement *e = rootNode->FirstChildElement(); e; e = e->NextSiblingElement()) {
|
||||||
|
if (std::strcmp(e->Name(), "FileInfo") != 0)
|
||||||
|
continue;
|
||||||
|
const char *checkClassAttr = e->Attribute("check");
|
||||||
|
if (!checkClassAttr)
|
||||||
|
continue;
|
||||||
|
for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
|
||||||
|
if (checkClassAttr == (*it)->name())
|
||||||
|
fileInfoList.push_back((*it)->loadFileInfoFromXml(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Analyse the tokens
|
||||||
|
for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it)
|
||||||
|
(*it)->analyseWholeProgram(fileInfoList, _settings, *this);
|
||||||
|
|
||||||
|
for (std::list<Check::FileInfo*>::iterator fi = fileInfoList.begin(); fi != fileInfoList.end(); ++fi)
|
||||||
|
delete(*fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppCheck::isUnusedFunctionCheckEnabled() const
|
bool CppCheck::isUnusedFunctionCheckEnabled() const
|
||||||
|
|
Loading…
Reference in New Issue