From 446c3bcae3b3c89e119e83763ba46804e4559080 Mon Sep 17 00:00:00 2001 From: Dmitry-Me Date: Fri, 11 Nov 2016 10:34:56 +0300 Subject: [PATCH] Declarations should occur before anything else --- tinyxml2.cpp | 20 +++++++++++++++----- xmltest.cpp | 17 +++++++++++++---- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/tinyxml2.cpp b/tinyxml2.cpp index a7c2b1c..cd03772 100755 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -981,13 +981,23 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) XMLDeclaration* decl = node->ToDeclaration(); if ( decl ) { - // A declaration can only be the first child of a document. - // Set error, if document already has children. - if ( !_document->NoChildren() ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, decl->Value(), 0); - DeleteNode( node ); + // Declarations are only allowed at document level + bool wellLocated = ( ToDocument() != 0 ); + if ( wellLocated ) { + // Multiple declarations are allowed but all declarations + // must occur before anything else + for ( const XMLNode* existingNode = _document->FirstChild(); existingNode; existingNode = existingNode->NextSibling() ) { + if ( !existingNode->ToDeclaration() ) { + wellLocated = false; break; + } } + } + if ( !wellLocated ) { + _document->SetError( XML_ERROR_PARSING_DECLARATION, decl->Value(), 0 ); + DeleteNode( node ); + break; + } } XMLElement* ele = node->ToElement(); diff --git a/xmltest.cpp b/xmltest.cpp index f474951..141694d 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -1570,22 +1570,31 @@ int main( int argc, const char ** argv ) } { - // Check that declarations are parsed only as the FirstChild + // Check that declarations are allowed only at beginning of document const char* xml0 = "" " " ""; const char* xml1 = "" - " " + "" ""; const char* xml2 = "" ""; + const char* xml3 = "" + ""; + + const char* xml4 = ""; + XMLDocument doc; doc.Parse(xml0); XMLTest("Test that the code changes do not affect normal parsing", doc.Error(), false); doc.Parse(xml1); - XMLTest("Test that the second declaration throws an error", doc.ErrorID(), XML_ERROR_PARSING_DECLARATION); + XMLTest("Test that the second declaration is allowed", doc.Error(), false); doc.Parse(xml2); - XMLTest("Test that declaration after a child throws an error", doc.ErrorID(), XML_ERROR_PARSING_DECLARATION); + XMLTest("Test that declaration after a child is not allowed", doc.ErrorID(), XML_ERROR_PARSING_DECLARATION); + doc.Parse(xml3); + XMLTest("Test that declaration after a child is not allowed", doc.ErrorID(), XML_ERROR_PARSING_DECLARATION); + doc.Parse(xml4); + XMLTest("Test that declaration inside a child is not allowed", doc.ErrorID(), XML_ERROR_PARSING_DECLARATION); } {