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)
|
||||
|
||||
namespace tinyxml2 {
|
||||
class XMLElement;
|
||||
}
|
||||
|
||||
/// @addtogroup Core
|
||||
/// @{
|
||||
|
||||
|
@ -108,6 +112,11 @@ public:
|
|||
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) {
|
||||
(void)fileInfo;
|
||||
(void)settings;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <list>
|
||||
#include <cstdlib>
|
||||
#include <stack>
|
||||
#include <tinyxml2.h>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
@ -1966,6 +1967,38 @@ Check::FileInfo* CheckBufferOverrun::getFileInfo(const Tokenizer *tokenizer, con
|
|||
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)
|
||||
{
|
||||
// Merge all fileInfo
|
||||
|
|
|
@ -227,6 +227,8 @@ public:
|
|||
/** @brief Parse current TU and extract file info */
|
||||
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 */
|
||||
void analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger);
|
||||
|
||||
|
|
|
@ -25,13 +25,14 @@
|
|||
#include "path.h"
|
||||
|
||||
#include "checkunusedfunctions.h"
|
||||
#include "timer.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include "timer.h"
|
||||
#include "version.h"
|
||||
#include <tinyxml2.h>
|
||||
|
||||
#ifdef HAVE_RULES
|
||||
#define PCRE_STATIC
|
||||
|
@ -742,6 +743,50 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::map<s
|
|||
return;
|
||||
if (_settings.isEnabled("unusedFunction"))
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue