1
0
mirror of https://github.com/leethomason/tinyxml2.git synced 2026-07-29 07:03:00 +04:00

Compare commits

..

11 Commits

Author SHA1 Message Date
Lee Thomason 5ce9f9a3a7 fix assert logic 2026-05-23 16:10:29 -07:00
Lee Thomason 682fda289f add comment 2026-05-23 16:04:26 -07:00
Lee Thomason e6a464942f Merge branch 'master' of github.com:IMBIGFISH4/xml2 into IMBIGFISH4-master 2026-05-23 16:02:58 -07:00
Lee Thomason 98137e6936 Merge branch 'master' of github.com:leethomason/tinyxml2 2026-03-09 17:53:04 -07:00
Lee Thomason 111f462dc4 remove old comments 2026-03-09 17:41:19 -07:00
zhthhh aba13c50bf Fix issue #1048: Add null pointer check in XMLDocument::DeleteNode (#1057)
- Add null pointer check in XMLDocument::DeleteNode() method
- Add test case to verify null pointer handling
- Prevents segmentation fault when calling DeleteNode(nullptr)
2026-03-09 17:32:22 -07:00
sbaluja e48a1310fe Add null check for format in TIXML_VSCPRINTF (#1064) 2026-03-09 17:31:36 -07:00
Lee Thomason 3324d04d58 minor readme fixes (#1054) 2025-11-22 16:26:53 -08:00
LuridHound c4e29afeaf Fix issue 1000 (#1040)
* fix compilation warnings produced by -Wold-style-cast

* remove incorrect cast
2025-11-22 16:08:17 -08:00
Lee Thomason 5c9a452c73 Merge fallthrough to cpp (#1052)
Fix warnings on merge fallthroughs
2025-11-22 16:02:49 -08:00
Michael Mishin fc99428a82 Improved XMLNode::~XMLNode perfomance
XMLNode::~XMLNode uses interface method DeleteChildren(), which
iteratively removes the first child until the list is empty. Each single
removal performs additional checks and keeps _firstChild and _lastChild
links in a consistent state. This leads to a performance penalty.

The proposed patch solves this problem by iterating the list of the
children and directly destroying them without keeping links in a
consistent state.

The performance boost we gained on xmltest is:
- 3% for my laptop (x86_64)
- 9% for bananapi f3 board (riscv64)
2025-07-29 16:30:58 +03:00
4 changed files with 30 additions and 18 deletions
+4 -4
View File
@@ -59,7 +59,7 @@ browsers or have more complete XML needs, TinyXML-2 is not the parser for you.
TinyXML-1 vs. TinyXML-2 TinyXML-1 vs. TinyXML-2
----------------------- -----------------------
TinyXML-2 long been the focus of all development. It is well tested TinyXML-2 has long been the focus of all development. It is well tested
and should be used instead of TinyXML-1. and should be used instead of TinyXML-1.
TinyXML-2 uses a similar API to TinyXML-1 and the same TinyXML-2 uses a similar API to TinyXML-1 and the same
@@ -145,7 +145,7 @@ It essentially causes the XML to be parsed twice.
For applications that need to know about text nodes that are composed entirely of For applications that need to know about text nodes that are composed entirely of
whitespace, PEDANTIC_WHITESPACE is available. PEDANTIC_WHITESPACE maintains all the whitespace, PEDANTIC_WHITESPACE is available. PEDANTIC_WHITESPACE maintains all the
whilespace between elements. whitespace between elements.
PEDANTIC_WHITESPACE is a new mode and not as tested as the other whitespace modes. PEDANTIC_WHITESPACE is a new mode and not as tested as the other whitespace modes.
@@ -178,7 +178,7 @@ will have the Value() of "Far & Away" when queried from the XMLText object,
and will be written back to the XML stream/file as an ampersand. and will be written back to the XML stream/file as an ampersand.
Additionally, any character can be specified by its Unicode code point: Additionally, any character can be specified by its Unicode code point:
The syntax ` ` or ` ` are both to the non-breaking space character. The syntax ` ` or ` ` both refer to the non-breaking space character.
This is called a 'numeric character reference'. Any numeric character reference This is called a 'numeric character reference'. Any numeric character reference
that isn't one of the special entities above, will be read, but written as a that isn't one of the special entities above, will be read, but written as a
regular code point. The output is correct, but the entity syntax isn't preserved. regular code point. The output is correct, but the entity syntax isn't preserved.
@@ -270,7 +270,7 @@ tinyxml2.h files in your project and build with your other source code.
There is also a CMake build included. CMake is the general build for TinyXML-2. There is also a CMake build included. CMake is the general build for TinyXML-2.
(Additional build systems are costly to maintain, and tend to bit-rot. They are (Additional build systems are costly to maintain, and tend to become outdated. They are
being removed over time.) being removed over time.)
Building TinyXML-2 - Using vcpkg Building TinyXML-2 - Using vcpkg
+19 -5
View File
@@ -114,6 +114,9 @@ distribution.
#define TIXML_VSNPRINTF vsnprintf #define TIXML_VSNPRINTF vsnprintf
static inline int TIXML_VSCPRINTF( const char* format, va_list va ) static inline int TIXML_VSCPRINTF( const char* format, va_list va )
{ {
if (!format) {
return 0;
}
int len = vsnprintf( 0, 0, format, va ); int len = vsnprintf( 0, 0, format, va );
TIXMLASSERT( len >= 0 ); TIXMLASSERT( len >= 0 );
return len; return len;
@@ -831,7 +834,17 @@ XMLNode::XMLNode( XMLDocument* doc ) :
XMLNode::~XMLNode() XMLNode::~XMLNode()
{ {
DeleteChildren(); // Fast path: this node is dying, so maintaining _firstChild/_lastChild and
// sibling _prev/_next links is unnecessary. Only _parent must be zeroed to
// satisfy the MarkInUse assertion inside DeleteNode.
XMLNode *currentChild = _firstChild;
while (currentChild != NULL) {
XMLNode *next = currentChild->_next;
currentChild->_parent = 0;
DeleteNode(currentChild);
currentChild = next;
}
if ( _parent ) { if ( _parent ) {
_parent->Unlink( this ); _parent->Unlink( this );
} }
@@ -2344,9 +2357,10 @@ static FILE* callfopen( const char* filepath, const char* mode )
return fp; return fp;
} }
void XMLDocument::DeleteNode( XMLNode* node ) { void XMLDocument::DeleteNode( XMLNode* node ) {
TIXMLASSERT( node ); if(node == 0) {
TIXMLASSERT(node->_document == this ); return; // check for null pointer
}
if (node->_parent) { if (node->_parent) {
node->_parent->DeleteChild( node ); node->_parent->DeleteChild( node );
} }
@@ -2656,7 +2670,7 @@ void XMLPrinter::Write( const char* data, size_t size )
fwrite ( data , sizeof(char), size, _fp); fwrite ( data , sizeof(char), size, _fp);
} }
else { else {
char* p = _buffer.PushArr( static_cast<int>(size) ) - 1; // back up over the null terminator. char* p = _buffer.PushArr( size ) - 1; // back up over the null terminator.
memcpy( p, data, size ); memcpy( p, data, size );
p[size] = 0; p[size] = 0;
} }
-8
View File
@@ -42,14 +42,6 @@ distribution.
#endif #endif
#include <stdint.h> #include <stdint.h>
/*
gcc:
g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
Formatting, Artistic Style:
AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
*/
#if defined( _DEBUG ) || defined (__DEBUG__) #if defined( _DEBUG ) || defined (__DEBUG__)
# ifndef TINYXML2_DEBUG # ifndef TINYXML2_DEBUG
# define TINYXML2_DEBUG # define TINYXML2_DEBUG
+7 -1
View File
@@ -2025,7 +2025,13 @@ int main( int argc, const char ** argv )
XMLTest("Parse nested elements with pedantic whitespace", false, doc.Error()); XMLTest("Parse nested elements with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", true, 0 == doc.RootElement()->FirstChildElement()->GetText()); XMLTest("Pedantic whitespace", true, 0 == doc.RootElement()->FirstChildElement()->GetText());
} }
//Check the robustness of the DeleteNode function in handling null pointers.
{
XMLDocument doc;
doc.DeleteNode(nullptr);
XMLTest("DeleteNode with null pointer", true, doc.Error() == XML_SUCCESS);
}
// Check sample xml can be parsed with pedantic mode // Check sample xml can be parsed with pedantic mode
{ {
XMLDocument doc(true, PEDANTIC_WHITESPACE); XMLDocument doc(true, PEDANTIC_WHITESPACE);