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);
}
{