bail out instead of crash when parsing unicode code (#207)
This commit is contained in:
parent
7b58e09a07
commit
b49997e69d
|
@ -32,6 +32,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -297,9 +298,12 @@ unsigned int CppCheck::check()
|
||||||
if (_settings._errorsOnly == false)
|
if (_settings._errorsOnly == false)
|
||||||
_errorLogger->reportOut(std::string("Checking ") + fname + std::string("..."));
|
_errorLogger->reportOut(std::string("Checking ") + fname + std::string("..."));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
Preprocessor preprocessor;
|
Preprocessor preprocessor;
|
||||||
std::list<std::string> configurations;
|
std::list<std::string> configurations;
|
||||||
std::string filedata = "";
|
std::string filedata = "";
|
||||||
|
|
||||||
if (_fileContents.size() > 0 && _fileContents.find(_filenames[c]) != _fileContents.end())
|
if (_fileContents.size() > 0 && _fileContents.find(_filenames[c]) != _fileContents.end())
|
||||||
{
|
{
|
||||||
// File content was given as a string
|
// File content was given as a string
|
||||||
|
@ -336,6 +340,12 @@ unsigned int CppCheck::check()
|
||||||
checkFile(codeWithoutCfg, _filenames[c].c_str());
|
checkFile(codeWithoutCfg, _filenames[c].c_str());
|
||||||
++checkCount;
|
++checkCount;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (std::runtime_error &e)
|
||||||
|
{
|
||||||
|
// Exception was thrown when checking this file..
|
||||||
|
_errorLogger->reportOut("Bailing out from checking " + fname + ": " + e.what());
|
||||||
|
}
|
||||||
|
|
||||||
_errorLogger->reportStatus(c + 1, _filenames.size());
|
_errorLogger->reportStatus(c + 1, _filenames.size());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -71,7 +72,7 @@ std::string Preprocessor::read(std::istream &istr)
|
||||||
for (char ch = readChar(istr); istr.good(); ch = readChar(istr))
|
for (char ch = readChar(istr); istr.good(); ch = readChar(istr))
|
||||||
{
|
{
|
||||||
if (ch < 0)
|
if (ch < 0)
|
||||||
continue;
|
throw std::runtime_error("The code contains characters that are unhandled");
|
||||||
|
|
||||||
if (ch == '\n')
|
if (ch == '\n')
|
||||||
++lineno;
|
++lineno;
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include "../src/tokenize.h"
|
#include "../src/tokenize.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
extern std::ostringstream errout;
|
extern std::ostringstream errout;
|
||||||
|
|
||||||
|
@ -115,6 +117,8 @@ private:
|
||||||
TEST_CASE(pragma);
|
TEST_CASE(pragma);
|
||||||
TEST_CASE(endifsemicolon);
|
TEST_CASE(endifsemicolon);
|
||||||
TEST_CASE(missing_doublequote);
|
TEST_CASE(missing_doublequote);
|
||||||
|
|
||||||
|
TEST_CASE(unicode1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -850,6 +854,13 @@ private:
|
||||||
ASSERT_EQUALS("[abc.h:2]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported.\n", errout.str());
|
ASSERT_EQUALS("[abc.h:2]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported.\n", errout.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unicode1()
|
||||||
|
{
|
||||||
|
const char filedata[] = {'a', (char)200, 0};
|
||||||
|
std::istringstream istr(filedata);
|
||||||
|
ASSERT_THROW(Preprocessor::read(istr), std::runtime_error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestPreprocessor)
|
REGISTER_TEST(TestPreprocessor)
|
||||||
|
|
|
@ -123,6 +123,12 @@ void TestFixture::assertEquals(const char *filename, int linenr, unsigned int ex
|
||||||
assertEquals(filename, linenr, ostr1.str(), ostr2.str());
|
assertEquals(filename, linenr, ostr1.str(), ostr2.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestFixture::assertThrowFail(const char *filename, int linenr)
|
||||||
|
{
|
||||||
|
errmsg << "Assertion failed in " << filename << " at line " << linenr << std::endl
|
||||||
|
<< "The expected exception was not thrown" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
void TestFixture::printTests()
|
void TestFixture::printTests()
|
||||||
{
|
{
|
||||||
const std::list<TestFixture *> &tests = TestRegistry::theInstance().tests();
|
const std::list<TestFixture *> &tests = TestRegistry::theInstance().tests();
|
||||||
|
|
|
@ -41,6 +41,7 @@ protected:
|
||||||
|
|
||||||
void assertEquals(const char *filename, int linenr, const std::string &expected, const std::string &actual);
|
void assertEquals(const char *filename, int linenr, const std::string &expected, const std::string &actual);
|
||||||
void assertEquals(const char *filename, int linenr, unsigned int expected, unsigned int actual);
|
void assertEquals(const char *filename, int linenr, unsigned int expected, unsigned int actual);
|
||||||
|
void assertThrowFail(const char *filename, int linenr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void reportOut(const std::string &outmsg);
|
virtual void reportOut(const std::string &outmsg);
|
||||||
|
@ -58,6 +59,7 @@ public:
|
||||||
|
|
||||||
#define TEST_CASE( NAME ) if ( runTest(#NAME) ) NAME ();
|
#define TEST_CASE( NAME ) if ( runTest(#NAME) ) NAME ();
|
||||||
#define ASSERT_EQUALS( EXPECTED , ACTUAL ) assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL)
|
#define ASSERT_EQUALS( EXPECTED , ACTUAL ) assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL)
|
||||||
|
#define ASSERT_THROW( CMD, EXCEPTION ) try { CMD ; assertThrowFail(__FILE__, __LINE__); } catch (EXCEPTION &) { } catch (...) { assertThrowFail(__FILE__, __LINE__); }
|
||||||
#define TODO_ASSERT_EQUALS( EXPECTED , ACTUAL ) if (EXPECTED==ACTUAL) assertEquals(__FILE__, __LINE__, "TODO assertion", "The assertion succeeded")
|
#define TODO_ASSERT_EQUALS( EXPECTED , ACTUAL ) if (EXPECTED==ACTUAL) assertEquals(__FILE__, __LINE__, "TODO assertion", "The assertion succeeded")
|
||||||
#define REGISTER_TEST( CLASSNAME ) namespace { CLASSNAME instance; }
|
#define REGISTER_TEST( CLASSNAME ) namespace { CLASSNAME instance; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue