+ make XML parser more robust against unexpected structure

This commit is contained in:
wmayer 2015-04-11 13:11:12 +02:00
parent 9ea9980b2c
commit c62319d2d9
2 changed files with 46 additions and 5 deletions

View File

@ -60,7 +60,8 @@ using namespace std;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Base::XMLReader::XMLReader(const char* FileName, std::istream& str) 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 #ifdef _MSC_VER
str.imbue(std::locale::empty()); str.imbue(std::locale::empty());
@ -85,7 +86,7 @@ Base::XMLReader::XMLReader(const char* FileName, std::istream& str)
try { try {
StdInputSource file(str, _File.filePath().c_str()); StdInputSource file(str, _File.filePath().c_str());
_valid = parser->parseFirst( file,token); _valid = parser->parseFirst(file, token);
} }
catch (const XMLException& toCatch) { catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage()); char* message = XMLString::transcode(toCatch.getMessage());
@ -238,6 +239,10 @@ void Base::XMLReader::readElement(const char* ElementName)
// thus we must stop reading on. // thus we must stop reading on.
break; 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) || } while ((ReadType != StartElement && ReadType != StartEndElement) ||
(ElementName && LocalName != ElementName)); (ElementName && LocalName != ElementName));
} }
@ -245,11 +250,19 @@ void Base::XMLReader::readElement(const char* ElementName)
void Base::XMLReader::readEndElement(const char* ElementName) void Base::XMLReader::readEndElement(const char* ElementName)
{ {
// if we are already at the end of the current element // if we are already at the end of the current element
if (ReadType == EndElement && LocalName == ElementName) if (ReadType == EndElement && LocalName == ElementName) {
return; 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; bool ok;
do { do {
ok = read(); if (!ok) break; ok = read(); if (!ok) break;
if (ReadType == EndDocument)
break;
} while (ReadType != EndElement || (ElementName && LocalName != ElementName)); } while (ReadType != EndElement || (ElementName && LocalName != ElementName));
} }
@ -378,6 +391,16 @@ bool Base::XMLReader::doNameMapping() const
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Base::XMLReader: Implementation of the SAX DocumentHandler interface // 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) 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 Level++; // new scope

View File

@ -180,10 +180,12 @@ protected:
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Handlers for the SAX ContentHandler interface // 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 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 endElement (const XMLCh* const uri, const XMLCh *const localname, const XMLCh *const qname);
virtual void startCDATA ();
virtual void endCDATA ();
#if (XERCES_VERSION_MAJOR == 2) #if (XERCES_VERSION_MAJOR == 2)
virtual void characters (const XMLCh* const chars, const unsigned int length); virtual void characters (const XMLCh* const chars, const unsigned int length);
virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int length); virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int length);
@ -191,16 +193,30 @@ protected:
virtual void characters (const XMLCh* const chars, const XMLSize_t length); virtual void characters (const XMLCh* const chars, const XMLSize_t length);
virtual void ignorableWhitespace(const XMLCh* const chars, const XMLSize_t length); virtual void ignorableWhitespace(const XMLCh* const chars, const XMLSize_t length);
#endif #endif
//@}
/** @name Lexical handler */
//@{
virtual void startCDATA ();
virtual void endCDATA ();
//@}
/** @name Document handler */
//@{
virtual void resetDocument(); virtual void resetDocument();
//@}
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Handlers for the SAX ErrorHandler interface // Handlers for the SAX ErrorHandler interface
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
/** @name Error handler */
//@{
void warning(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException& exc); void warning(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException& exc);
void error(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 fatalError(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException& exc);
void resetErrors(); void resetErrors();
//@}
int Level; int Level;
@ -214,6 +230,8 @@ protected:
enum { enum {
None = 0, None = 0,
Chars, Chars,
StartDocument,
EndDocument,
StartElement, StartElement,
StartEndElement, StartEndElement,
EndElement, EndElement,