Skip to content

Commit

Permalink
+ make XML parser more robust against unexpected structure
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Apr 11, 2015
1 parent 9ea9980 commit c62319d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 5 deletions.
29 changes: 26 additions & 3 deletions src/Base/Reader.cpp
Expand Up @@ -60,7 +60,8 @@ using namespace std;
// ---------------------------------------------------------------------------

Base::XMLReader::XMLReader(const char* FileName, std::istream& str)
: DocumentSchema(0), ProgramVersion(""), FileVersion(0), Level(0), _File(FileName), _verbose(true)
: DocumentSchema(0), ProgramVersion(""), FileVersion(0), Level(0),
_File(FileName), _valid(false), _verbose(true)
{
#ifdef _MSC_VER
str.imbue(std::locale::empty());
Expand All @@ -85,7 +86,7 @@ Base::XMLReader::XMLReader(const char* FileName, std::istream& str)

try {
StdInputSource file(str, _File.filePath().c_str());
_valid = parser->parseFirst( file,token);
_valid = parser->parseFirst(file, token);
}
catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage());
Expand Down Expand Up @@ -238,18 +239,30 @@ void Base::XMLReader::readElement(const char* ElementName)
// thus we must stop reading on.
break;
}
else if (ReadType == EndDocument) {
// the end of the document has been reached but we still try to continue on reading
throw Base::XMLParseException("End of document reached");
}
} while ((ReadType != StartElement && ReadType != StartEndElement) ||
(ElementName && LocalName != ElementName));
}

void Base::XMLReader::readEndElement(const char* ElementName)
{
// if we are already at the end of the current element
if (ReadType == EndElement && LocalName == ElementName)
if (ReadType == EndElement && LocalName == ElementName) {
return;
}
else if (ReadType == EndDocument) {
// the end of the document has been reached but we still try to continue on reading
throw Base::XMLParseException("End of document reached");
}

bool ok;
do {
ok = read(); if (!ok) break;
if (ReadType == EndDocument)
break;
} while (ReadType != EndElement || (ElementName && LocalName != ElementName));
}

Expand Down Expand Up @@ -378,6 +391,16 @@ bool Base::XMLReader::doNameMapping() const
// ---------------------------------------------------------------------------
// Base::XMLReader: Implementation of the SAX DocumentHandler interface
// ---------------------------------------------------------------------------
void Base::XMLReader::startDocument()
{
ReadType = StartDocument;
}

void Base::XMLReader::endDocument()
{
ReadType = EndDocument;
}

void Base::XMLReader::startElement(const XMLCh* const /*uri*/, const XMLCh* const localname, const XMLCh* const /*qname*/, const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs)
{
Level++; // new scope
Expand Down
22 changes: 20 additions & 2 deletions src/Base/Reader.h
Expand Up @@ -180,27 +180,43 @@ class BaseExport XMLReader : public XERCES_CPP_NAMESPACE_QUALIFIER DefaultHandle
// -----------------------------------------------------------------------
// Handlers for the SAX ContentHandler interface
// -----------------------------------------------------------------------
/** @name Content handler */
//@{
virtual void startDocument();
virtual void endDocument();
virtual void startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs);
virtual void endElement (const XMLCh* const uri, const XMLCh *const localname, const XMLCh *const qname);
virtual void startCDATA ();
virtual void endCDATA ();
#if (XERCES_VERSION_MAJOR == 2)
virtual void characters (const XMLCh* const chars, const unsigned int length);
virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int length);
#else
virtual void characters (const XMLCh* const chars, const XMLSize_t length);
virtual void ignorableWhitespace(const XMLCh* const chars, const XMLSize_t length);
#endif
//@}

/** @name Lexical handler */
//@{
virtual void startCDATA ();
virtual void endCDATA ();
//@}

/** @name Document handler */
//@{
virtual void resetDocument();
//@}


// -----------------------------------------------------------------------
// Handlers for the SAX ErrorHandler interface
// -----------------------------------------------------------------------
/** @name Error handler */
//@{
void warning(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException& exc);
void error(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException& exc);
void fatalError(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException& exc);
void resetErrors();
//@}


int Level;
Expand All @@ -214,6 +230,8 @@ class BaseExport XMLReader : public XERCES_CPP_NAMESPACE_QUALIFIER DefaultHandle
enum {
None = 0,
Chars,
StartDocument,
EndDocument,
StartElement,
StartEndElement,
EndElement,
Expand Down

0 comments on commit c62319d

Please sign in to comment.