Declarations should occur before anything else

This commit is contained in:
Dmitry-Me 2016-11-11 10:34:56 +03:00
parent 6bbcda0215
commit 446c3bcae3
2 changed files with 28 additions and 9 deletions

View File

@ -981,9 +981,19 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd )
XMLDeclaration* decl = node->ToDeclaration(); XMLDeclaration* decl = node->ToDeclaration();
if ( decl ) { if ( decl ) {
// A declaration can only be the first child of a document. // Declarations are only allowed at document level
// Set error, if document already has children. bool wellLocated = ( ToDocument() != 0 );
if ( !_document->NoChildren() ) { 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 ); _document->SetError( XML_ERROR_PARSING_DECLARATION, decl->Value(), 0 );
DeleteNode( node ); DeleteNode( node );
break; break;

View File

@ -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 = "<?xml version=\"1.0\" ?>" const char* xml0 = "<?xml version=\"1.0\" ?>"
" <!-- xml version=\"1.1\" -->" " <!-- xml version=\"1.1\" -->"
"<first />"; "<first />";
const char* xml1 = "<?xml version=\"1.0\" ?>" const char* xml1 = "<?xml version=\"1.0\" ?>"
" <?xml version=\"1.1\" ?>" "<?xml-stylesheet type=\"text/xsl\" href=\"Anything.xsl\"?>"
"<first />"; "<first />";
const char* xml2 = "<first />" const char* xml2 = "<first />"
"<?xml version=\"1.0\" ?>"; "<?xml version=\"1.0\" ?>";
const char* xml3 = "<first></first>"
"<?xml version=\"1.0\" ?>";
const char* xml4 = "<first><?xml version=\"1.0\" ?></first>";
XMLDocument doc; XMLDocument doc;
doc.Parse(xml0); doc.Parse(xml0);
XMLTest("Test that the code changes do not affect normal parsing", doc.Error(), false); XMLTest("Test that the code changes do not affect normal parsing", doc.Error(), false);
doc.Parse(xml1); 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); 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);
} }
{ {