Upgrade to tinyxml2 7.0.1 (2018-11-17)

Test: builds, boots, tinyxml2 tests pass
Change-Id: Ia4ca2327925f9a678cbae6febdb5341151a1ec10
diff --git a/tinyxml2.cpp b/tinyxml2.cpp
index 04cf697..fd27f78 100644
--- a/tinyxml2.cpp
+++ b/tinyxml2.cpp
@@ -760,7 +760,7 @@
     }

 }

 

-const char* XMLNode::Value() const 

+const char* XMLNode::Value() const

 {

     // Edge case: XMLDocuments don't have a Value. Return null.

     if ( this->ToDocument() )

@@ -1004,7 +1004,11 @@
     // 'endTag' is the end tag for this node, it is returned by a call to a child.

     // 'parentEnd' is the end tag for the parent, which is filled in and returned.

 

-    while( p && *p ) {

+	XMLDocument::DepthTracker tracker(_document);

+	if (_document->Error())

+		return 0;

+

+	while( p && *p ) {

         XMLNode* node = 0;

 

         p = _document->Identify( p, &node );

@@ -1028,15 +1032,25 @@
         XMLDeclaration* decl = node->ToDeclaration();

         if ( decl ) {

             // 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;

-                    }

+            //

+            // Multiple declarations are allowed but all declarations

+            // must occur before anything else. 

+            //

+            // Optimized due to a security test case. If the first node is 

+            // a declaration, and the last node is a declaration, then only 

+            // declarations have so far been addded.

+            bool wellLocated = false;

+

+            if (ToDocument()) {

+                if (FirstChild()) {

+                    wellLocated =

+                        FirstChild() &&

+                        FirstChild()->ToDeclaration() &&

+                        LastChild() &&

+                        LastChild()->ToDeclaration();

+                }

+                else {

+                    wellLocated = true;

                 }

             }

             if ( !wellLocated ) {

@@ -1329,12 +1343,12 @@
 

 // --------- XMLAttribute ---------- //

 

-const char* XMLAttribute::Name() const 

+const char* XMLAttribute::Name() const

 {

     return _name.GetStr();

 }

 

-const char* XMLAttribute::Value() const 

+const char* XMLAttribute::Value() const

 {

     return _value.GetStr();

 }

@@ -1521,42 +1535,42 @@
     return 0;

 }

 

-int XMLElement::IntAttribute(const char* name, int defaultValue) const 

+int XMLElement::IntAttribute(const char* name, int defaultValue) const

 {

 	int i = defaultValue;

 	QueryIntAttribute(name, &i);

 	return i;

 }

 

-unsigned XMLElement::UnsignedAttribute(const char* name, unsigned defaultValue) const 

+unsigned XMLElement::UnsignedAttribute(const char* name, unsigned defaultValue) const

 {

 	unsigned i = defaultValue;

 	QueryUnsignedAttribute(name, &i);

 	return i;

 }

 

-int64_t XMLElement::Int64Attribute(const char* name, int64_t defaultValue) const 

+int64_t XMLElement::Int64Attribute(const char* name, int64_t defaultValue) const

 {

 	int64_t i = defaultValue;

 	QueryInt64Attribute(name, &i);

 	return i;

 }

 

-bool XMLElement::BoolAttribute(const char* name, bool defaultValue) const 

+bool XMLElement::BoolAttribute(const char* name, bool defaultValue) const

 {

 	bool b = defaultValue;

 	QueryBoolAttribute(name, &b);

 	return b;

 }

 

-double XMLElement::DoubleAttribute(const char* name, double defaultValue) const 

+double XMLElement::DoubleAttribute(const char* name, double defaultValue) const

 {

 	double d = defaultValue;

 	QueryDoubleAttribute(name, &d);

 	return d;

 }

 

-float XMLElement::FloatAttribute(const char* name, float defaultValue) const 

+float XMLElement::FloatAttribute(const char* name, float defaultValue) const

 {

 	float f = defaultValue;

 	QueryFloatAttribute(name, &f);

@@ -1583,7 +1597,7 @@
 }

 

 

-void XMLElement::SetText( int v ) 

+void XMLElement::SetText( int v )

 {

     char buf[BUF_SIZE];

     XMLUtil::ToStr( v, buf, BUF_SIZE );

@@ -1591,7 +1605,7 @@
 }

 

 

-void XMLElement::SetText( unsigned v ) 

+void XMLElement::SetText( unsigned v )

 {

     char buf[BUF_SIZE];

     XMLUtil::ToStr( v, buf, BUF_SIZE );

@@ -1615,7 +1629,7 @@
 }

 

 

-void XMLElement::SetText( float v ) 

+void XMLElement::SetText( float v )

 {

     char buf[BUF_SIZE];

     XMLUtil::ToStr( v, buf, BUF_SIZE );

@@ -1623,7 +1637,7 @@
 }

 

 

-void XMLElement::SetText( double v ) 

+void XMLElement::SetText( double v )

 {

     char buf[BUF_SIZE];

     XMLUtil::ToStr( v, buf, BUF_SIZE );

@@ -1973,10 +1987,8 @@
     "XML_ERROR_FILE_NOT_FOUND",

     "XML_ERROR_FILE_COULD_NOT_BE_OPENED",

     "XML_ERROR_FILE_READ_ERROR",

-    "UNUSED_XML_ERROR_ELEMENT_MISMATCH",

     "XML_ERROR_PARSING_ELEMENT",

     "XML_ERROR_PARSING_ATTRIBUTE",

-    "UNUSED_XML_ERROR_IDENTIFYING_TAG",

     "XML_ERROR_PARSING_TEXT",

     "XML_ERROR_PARSING_CDATA",

     "XML_ERROR_PARSING_COMMENT",

@@ -1986,7 +1998,8 @@
     "XML_ERROR_MISMATCHED_ELEMENT",

     "XML_ERROR_PARSING",

     "XML_CAN_NOT_CONVERT_TEXT",

-    "XML_NO_TEXT_NODE"

+    "XML_NO_TEXT_NODE",

+	"XML_ELEMENT_DEPTH_EXCEEDED"

 };

 

 

@@ -2000,6 +2013,7 @@
     _errorLineNum( 0 ),

     _charBuffer( 0 ),

     _parseCurLineNum( 0 ),

+	_parsingDepth(0),

     _unlinked(),

     _elementPool(),

     _attributePool(),

@@ -2037,13 +2051,14 @@
 		DeleteNode(_unlinked[0]);	// Will remove from _unlinked as part of delete.

 	}

 

-#ifdef DEBUG

+#ifdef TINYXML2_DEBUG

     const bool hadError = Error();

 #endif

     ClearError();

 

     delete [] _charBuffer;

     _charBuffer = 0;

+	_parsingDepth = 0;

 

 #if 0

     _textPool.Trace( "text" );

@@ -2051,8 +2066,8 @@
     _commentPool.Trace( "comment" );

     _attributePool.Trace( "attribute" );

 #endif

-    

-#ifdef DEBUG

+

+#ifdef TINYXML2_DEBUG

     if ( !hadError ) {

         TIXMLASSERT( _elementPool.CurrentAllocs()   == _elementPool.Untracked() );

         TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() );

@@ -2130,7 +2145,7 @@
 #endif

     return fp;

 }

-    

+

 void XMLDocument::DeleteNode( XMLNode* node )	{

     TIXMLASSERT( node );

     TIXMLASSERT(node->_document == this );

@@ -2151,10 +2166,16 @@
 

 XMLError XMLDocument::LoadFile( const char* filename )

 {

+    if ( !filename ) {

+        TIXMLASSERT( false );

+        SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=<null>" );

+        return _errorID;

+    }

+

     Clear();

     FILE* fp = callfopen( filename, "rb" );

     if ( !fp ) {

-        SetError( XML_ERROR_FILE_NOT_FOUND, 0, "filename=%s", filename ? filename : "<null>");

+        SetError( XML_ERROR_FILE_NOT_FOUND, 0, "filename=%s", filename );

         return _errorID;

     }

     LoadFile( fp );

@@ -2233,9 +2254,15 @@
 

 XMLError XMLDocument::SaveFile( const char* filename, bool compact )

 {

+    if ( !filename ) {

+        TIXMLASSERT( false );

+        SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=<null>" );

+        return _errorID;

+    }

+

     FILE* fp = callfopen( filename, "w" );

     if ( !fp ) {

-        SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=%s", filename ? filename : "<null>");

+        SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=%s", filename );

         return _errorID;

     }

     SaveFile(fp, compact);

@@ -2305,20 +2332,24 @@
     _errorLineNum = lineNum;

 	_errorStr.Reset();

 

-    if (format) {

-        size_t BUFFER_SIZE = 1000;

-        char* buffer = new char[BUFFER_SIZE];

-        TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d: ", ErrorIDToName(error), int(error), int(error), lineNum);

-        size_t len = strlen(buffer);

+    size_t BUFFER_SIZE = 1000;

+    char* buffer = new char[BUFFER_SIZE];

 

-        va_list va;

-        va_start( va, format );

-        TIXML_VSNPRINTF( buffer + len, BUFFER_SIZE - len, format, va );

-        va_end( va );

+    TIXMLASSERT(sizeof(error) <= sizeof(int));

+    TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d", ErrorIDToName(error), int(error), int(error), lineNum);

 

-        _errorStr.SetStr(buffer);

-        delete [] buffer;

-    }

+	if (format) {

+		size_t len = strlen(buffer);

+		TIXML_SNPRINTF(buffer + len, BUFFER_SIZE - len, ": ");

+		len = strlen(buffer);

+

+		va_list va;

+		va_start(va, format);

+		TIXML_VSNPRINTF(buffer + len, BUFFER_SIZE - len, format, va);

+		va_end(va);

+	}

+	_errorStr.SetStr(buffer);

+	delete[] buffer;

 }

 

 

@@ -2330,7 +2361,7 @@
     return errorName;

 }

 

-const char* XMLDocument::ErrorStr() const 

+const char* XMLDocument::ErrorStr() const

 {

 	return _errorStr.Empty() ? "" : _errorStr.GetStr();

 }

@@ -2362,6 +2393,20 @@
     ParseDeep(p, 0, &_parseCurLineNum );

 }

 

+void XMLDocument::PushDepth()

+{

+	_parsingDepth++;

+	if (_parsingDepth == TINYXML2_MAX_ELEMENT_DEPTH) {

+		SetError(XML_ELEMENT_DEPTH_EXCEEDED, _parseCurLineNum, "Element nesting is too deep." );

+	}

+}

+

+void XMLDocument::PopDepth()

+{

+	TIXMLASSERT(_parsingDepth > 0);

+	--_parsingDepth;

+}

+

 XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :

     _elementJustOpened( false ),

     _stack(),

@@ -2487,14 +2532,16 @@
             ++q;

             TIXMLASSERT( p <= q );

         }

+        // Flush the remaining string. This will be the entire

+        // string if an entity wasn't found.

+        if ( p < q ) {

+            const size_t delta = q - p;

+            const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta;

+            Write( p, toPrint );

+        }

     }

-    // Flush the remaining string. This will be the entire

-    // string if an entity wasn't found.

-    TIXMLASSERT( p <= q );

-    if ( !_processEntities || ( p < q ) ) {

-        const size_t delta = q - p;

-        const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta;

-        Write( p, toPrint );

+    else {

+        Write( p );

     }

 }

 

@@ -2788,4 +2835,3 @@
 }

 

 }   // namespace tinyxml2

-