mirror of
https://github.com/leethomason/tinyxml2.git
synced 2026-07-22 19:52:59 +04:00
Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ce9f9a3a7 | |||
| 682fda289f | |||
| e6a464942f | |||
| 98137e6936 | |||
| 111f462dc4 | |||
| aba13c50bf | |||
| e48a1310fe | |||
| 3324d04d58 | |||
| c4e29afeaf | |||
| 5c9a452c73 | |||
| 2722500313 | |||
| fc99428a82 | |||
| b5e767a6b9 | |||
| e186491558 | |||
| 36ff404c34 | |||
| 302f4661a7 | |||
| e6caeae857 | |||
| b765a210b3 | |||
| 6e246aec4d | |||
| 30dee1efa0 | |||
| a93163d2f5 | |||
| f87d0e3077 | |||
| 487f42aa69 | |||
| afff7bf328 | |||
| 9148bdf719 | |||
| 57eea48c5b | |||
| 198cb82c9b | |||
| c6ab6d76e8 | |||
| 008e32968f | |||
| 0ca3584fa4 | |||
| 57ec94127b | |||
| 1fadaae0c9 | |||
| 4cbb25155c | |||
| ff48ea1bae | |||
| 494735de30 | |||
| d418ac22f2 | |||
| d13a151c8d | |||
| 601a953b74 | |||
| 162bd4e925 | |||
| 1fdf653269 | |||
| 86fe31c836 | |||
| 20ecbb22d8 | |||
| 374292e9ba | |||
| 2ac336a253 | |||
| 38894bfa7f | |||
| 780b16b5ae | |||
| 04bbc06cd0 | |||
| 62f6b14e91 | |||
| b25c39aaad | |||
| 8a519a556a | |||
| c93b6f78d4 | |||
| 8e4bfebad5 | |||
| eb3ab0df5d | |||
| 3a893e5757 | |||
| a0f66fdf71 | |||
| a965e28c4f | |||
| 5b04868fee | |||
| 8df9b25bb9 | |||
| 53d8ec5573 | |||
| 5e27269c04 | |||
| 693052afe4 | |||
| 42875a9f60 | |||
| afb8fabf58 | |||
| a151353f3a | |||
| ef185a8f85 | |||
| 8fed517e5d | |||
| e269b2e91f | |||
| cd8c1a6322 | |||
| 668fd81256 | |||
| 095a8ffa42 | |||
| 574c760b7f | |||
| 5d219c893b | |||
| fd26a5ee1f | |||
| dded8bb2e9 | |||
| 312a809224 | |||
| c33aae04d9 | |||
| 0f9c021a44 | |||
| dfc20c5f8f | |||
| 1d658f0d95 | |||
| 321ea883b7 |
@@ -6,15 +6,15 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ windows-2019, macos-latest, ubuntu-20.04 ]
|
||||
os: [ windows-latest, macos-latest, ubuntu-latest ]
|
||||
cmake: [ 3.15, 3.x ]
|
||||
include:
|
||||
- os: windows-2019
|
||||
- os: windows-latest
|
||||
static_postfix: _static
|
||||
tree: tree /F
|
||||
CXX: cl
|
||||
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-latest
|
||||
tree: tree
|
||||
|
||||
- os: macos-latest
|
||||
@@ -31,10 +31,10 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
# System set-up
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- uses: seanmiddleditch/gha-setup-ninja@master
|
||||
- uses: jwlawson/actions-setup-cmake@v1.8
|
||||
- uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
- uses: jwlawson/actions-setup-cmake@v2
|
||||
with:
|
||||
cmake-version: ${{ matrix.cmake }}
|
||||
|
||||
|
||||
+13
-9
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(tinyxml2 VERSION 10.0.0)
|
||||
project(tinyxml2 VERSION 11.0.0)
|
||||
|
||||
include(CTest)
|
||||
option(tinyxml2_BUILD_TESTING "Build tests for tinyxml2" "${BUILD_TESTING}")
|
||||
@@ -63,7 +63,9 @@ endif ()
|
||||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
## Custom locations
|
||||
## Custom settings
|
||||
option(tinyxml2_INSTALL_PKGCONFIG "Create and install pkgconfig files" ON)
|
||||
|
||||
set(tinyxml2_INSTALL_PKGCONFIGDIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
|
||||
CACHE PATH "Directory for pkgconfig files")
|
||||
|
||||
@@ -121,10 +123,12 @@ install(
|
||||
|
||||
## pkg-config
|
||||
|
||||
configure_file(cmake/tinyxml2.pc.in tinyxml2.pc.gen @ONLY)
|
||||
file(GENERATE OUTPUT tinyxml2.pc INPUT "${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc.gen")
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc"
|
||||
DESTINATION "${tinyxml2_INSTALL_PKGCONFIGDIR}"
|
||||
COMPONENT tinyxml2_development
|
||||
)
|
||||
if (tinyxml2_INSTALL_PKGCONFIG)
|
||||
configure_file(cmake/tinyxml2.pc.in tinyxml2.pc.gen @ONLY)
|
||||
file(GENERATE OUTPUT tinyxml2.pc INPUT "${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc.gen")
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc"
|
||||
DESTINATION "${tinyxml2_INSTALL_PKGCONFIGDIR}"
|
||||
COMPONENT tinyxml2_development
|
||||
)
|
||||
endif ()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
// In HTML5, there are 16 so-called "void" elements. "void elements" NEVER have
|
||||
// inner content (but they MAY have attributes), and are assumed to be self-closing.
|
||||
// An example of a self-closig HTML5 element is "<br/>" (line break)
|
||||
// An example of a self-closing HTML5 element is "<br/>" (line break)
|
||||
// All other elements are called "non-void" and MUST never self-close.
|
||||
// Examples: "<div class='lolcats'></div>".
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = "TinyXML-2"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 10.0.0
|
||||
PROJECT_NUMBER = 11.0.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
project(
|
||||
'tinyxml2',
|
||||
['cpp'],
|
||||
version : '10.0.0',
|
||||
version : '11.0.0',
|
||||
meson_version : '>= 0.49.0',
|
||||
)
|
||||
|
||||
|
||||
@@ -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-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.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
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
|
||||
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.
|
||||
@@ -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.
|
||||
|
||||
(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.)
|
||||
|
||||
Building TinyXML-2 - Using vcpkg
|
||||
|
||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+128
-103
@@ -24,7 +24,7 @@ distribution.
|
||||
#include "tinyxml2.h"
|
||||
|
||||
#include <new> // yes, this one new style header, is in the Android SDK.
|
||||
#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
|
||||
#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) || defined(__CC_ARM)
|
||||
# include <stddef.h>
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
@@ -32,6 +32,27 @@ distribution.
|
||||
# include <cstdarg>
|
||||
#endif
|
||||
|
||||
// Handle fallthrough attribute for different compilers
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0
|
||||
#endif
|
||||
#ifndef __has_cpp_attribute
|
||||
# define __has_cpp_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# define TIXML_FALLTHROUGH (void(0))
|
||||
#elif (__cplusplus >= 201703L && __has_cpp_attribute(fallthrough))
|
||||
# define TIXML_FALLTHROUGH [[fallthrough]]
|
||||
#elif __has_cpp_attribute(clang::fallthrough)
|
||||
# define TIXML_FALLTHROUGH [[clang::fallthrough]]
|
||||
#elif __has_attribute(fallthrough)
|
||||
# define TIXML_FALLTHROUGH __attribute__((fallthrough))
|
||||
#else
|
||||
# define TIXML_FALLTHROUGH (void(0))
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
|
||||
// Microsoft Visual Studio, version 2005 and higher. Not WinCE.
|
||||
/*int _snprintf_s(
|
||||
@@ -93,6 +114,9 @@ distribution.
|
||||
#define TIXML_VSNPRINTF vsnprintf
|
||||
static inline int TIXML_VSCPRINTF( const char* format, va_list va )
|
||||
{
|
||||
if (!format) {
|
||||
return 0;
|
||||
}
|
||||
int len = vsnprintf( 0, 0, format, va );
|
||||
TIXMLASSERT( len >= 0 );
|
||||
return len;
|
||||
@@ -106,14 +130,9 @@ distribution.
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__CYGWIN__)
|
||||
#define TIXML_FSEEK fseeko
|
||||
#define TIXML_FTELL ftello
|
||||
#elif defined(__ANDROID__)
|
||||
#if __ANDROID_API__ > 24
|
||||
#define TIXML_FSEEK fseeko64
|
||||
#define TIXML_FTELL ftello64
|
||||
#else
|
||||
#define TIXML_FSEEK fseeko
|
||||
#define TIXML_FTELL ftello
|
||||
#endif
|
||||
#elif defined(__ANDROID__) && __ANDROID_API__ > 24
|
||||
#define TIXML_FSEEK fseeko64
|
||||
#define TIXML_FTELL ftello64
|
||||
#else
|
||||
#define TIXML_FSEEK fseek
|
||||
#define TIXML_FTELL ftell
|
||||
@@ -239,13 +258,13 @@ char* StrPair::ParseName( char* p )
|
||||
if ( !p || !(*p) ) {
|
||||
return 0;
|
||||
}
|
||||
if ( !XMLUtil::IsNameStartChar( (unsigned char) *p ) ) {
|
||||
if ( !XMLUtil::IsNameStartChar( static_cast<unsigned char>(*p) ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* const start = p;
|
||||
++p;
|
||||
while ( *p && XMLUtil::IsNameChar( (unsigned char) *p ) ) {
|
||||
while ( *p && XMLUtil::IsNameChar( static_cast<unsigned char>(*p) ) ) {
|
||||
++p;
|
||||
}
|
||||
|
||||
@@ -451,17 +470,17 @@ void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length
|
||||
--output;
|
||||
*output = static_cast<char>((input | BYTE_MARK) & BYTE_MASK);
|
||||
input >>= 6;
|
||||
//fall through
|
||||
TIXML_FALLTHROUGH;
|
||||
case 3:
|
||||
--output;
|
||||
*output = static_cast<char>((input | BYTE_MARK) & BYTE_MASK);
|
||||
input >>= 6;
|
||||
//fall through
|
||||
TIXML_FALLTHROUGH;
|
||||
case 2:
|
||||
--output;
|
||||
*output = static_cast<char>((input | BYTE_MARK) & BYTE_MASK);
|
||||
input >>= 6;
|
||||
//fall through
|
||||
TIXML_FALLTHROUGH;
|
||||
case 1:
|
||||
--output;
|
||||
*output = static_cast<char>(input | FIRST_BYTE_MARK[*length]);
|
||||
@@ -472,102 +491,94 @@ void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length
|
||||
}
|
||||
|
||||
|
||||
const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
|
||||
const char* XMLUtil::GetCharacterRef(const char* p, char* value, int* length)
|
||||
{
|
||||
// Presume an entity, and pull it out.
|
||||
// Assume an entity, and pull it out.
|
||||
*length = 0;
|
||||
|
||||
if ( *(p+1) == '#' && *(p+2) ) {
|
||||
unsigned long ucs = 0;
|
||||
TIXMLASSERT( sizeof( ucs ) >= 4 );
|
||||
static const uint32_t MAX_CODE_POINT = 0x10FFFF;
|
||||
|
||||
if (*(p + 1) == '#' && *(p + 2)) {
|
||||
uint32_t ucs = 0;
|
||||
ptrdiff_t delta = 0;
|
||||
unsigned mult = 1;
|
||||
uint32_t mult = 1;
|
||||
static const char SEMICOLON = ';';
|
||||
|
||||
if ( *(p+2) == 'x' ) {
|
||||
bool hex = false;
|
||||
uint32_t radix = 10;
|
||||
const char* q = 0;
|
||||
char terminator = '#';
|
||||
|
||||
if (*(p + 2) == 'x') {
|
||||
// Hexadecimal.
|
||||
const char* q = p+3;
|
||||
if ( !(*q) ) {
|
||||
return 0;
|
||||
}
|
||||
hex = true;
|
||||
radix = 16;
|
||||
terminator = 'x';
|
||||
|
||||
q = strchr( q, SEMICOLON );
|
||||
|
||||
if ( !q ) {
|
||||
return 0;
|
||||
}
|
||||
TIXMLASSERT( *q == SEMICOLON );
|
||||
|
||||
delta = q-p;
|
||||
--q;
|
||||
|
||||
while ( *q != 'x' ) {
|
||||
unsigned int digit = 0;
|
||||
|
||||
if ( *q >= '0' && *q <= '9' ) {
|
||||
digit = *q - '0';
|
||||
}
|
||||
else if ( *q >= 'a' && *q <= 'f' ) {
|
||||
digit = *q - 'a' + 10;
|
||||
}
|
||||
else if ( *q >= 'A' && *q <= 'F' ) {
|
||||
digit = *q - 'A' + 10;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
TIXMLASSERT( digit < 16 );
|
||||
TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
|
||||
const unsigned int digitScaled = mult * digit;
|
||||
TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
|
||||
ucs += digitScaled;
|
||||
TIXMLASSERT( mult <= UINT_MAX / 16 );
|
||||
mult *= 16;
|
||||
--q;
|
||||
}
|
||||
q = p + 3;
|
||||
}
|
||||
else {
|
||||
// Decimal.
|
||||
const char* q = p+2;
|
||||
if ( !(*q) ) {
|
||||
q = p + 2;
|
||||
}
|
||||
if (!(*q)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
q = strchr(q, SEMICOLON);
|
||||
if (!q) {
|
||||
return 0;
|
||||
}
|
||||
TIXMLASSERT(*q == SEMICOLON);
|
||||
|
||||
delta = q - p;
|
||||
--q;
|
||||
|
||||
while (*q != terminator) {
|
||||
uint32_t digit = 0;
|
||||
|
||||
if (*q >= '0' && *q <= '9') {
|
||||
digit = *q - '0';
|
||||
}
|
||||
else if (hex && (*q >= 'a' && *q <= 'f')) {
|
||||
digit = *q - 'a' + 10;
|
||||
}
|
||||
else if (hex && (*q >= 'A' && *q <= 'F')) {
|
||||
digit = *q - 'A' + 10;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
TIXMLASSERT(digit < radix);
|
||||
|
||||
q = strchr( q, SEMICOLON );
|
||||
|
||||
if ( !q ) {
|
||||
return 0;
|
||||
const unsigned int digitScaled = mult * digit;
|
||||
ucs += digitScaled;
|
||||
mult *= radix;
|
||||
|
||||
// Security check: could a value exist that is out of range?
|
||||
// Easily; limit to the MAX_CODE_POINT, which also allows for a
|
||||
// bunch of leading zeroes.
|
||||
if (mult > MAX_CODE_POINT) {
|
||||
mult = MAX_CODE_POINT;
|
||||
}
|
||||
TIXMLASSERT( *q == SEMICOLON );
|
||||
|
||||
delta = q-p;
|
||||
--q;
|
||||
|
||||
while ( *q != '#' ) {
|
||||
if ( *q >= '0' && *q <= '9' ) {
|
||||
const unsigned int digit = *q - '0';
|
||||
TIXMLASSERT( digit < 10 );
|
||||
TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
|
||||
const unsigned int digitScaled = mult * digit;
|
||||
TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
|
||||
ucs += digitScaled;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
TIXMLASSERT( mult <= UINT_MAX / 10 );
|
||||
mult *= 10;
|
||||
--q;
|
||||
}
|
||||
}
|
||||
// Out of range:
|
||||
if (ucs > MAX_CODE_POINT) {
|
||||
return 0;
|
||||
}
|
||||
// convert the UCS to UTF-8
|
||||
ConvertUTF32ToUTF8( ucs, value, length );
|
||||
ConvertUTF32ToUTF8(ucs, value, length);
|
||||
if (length == 0) {
|
||||
// If length is 0, there was an error. (Security? Bad input?)
|
||||
// Fail safely.
|
||||
return 0;
|
||||
}
|
||||
return p + delta + 1;
|
||||
}
|
||||
return p+1;
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
|
||||
void XMLUtil::ToStr( int v, char* buffer, int bufferSize )
|
||||
{
|
||||
TIXML_SNPRINTF( buffer, bufferSize, "%d", v );
|
||||
@@ -610,7 +621,7 @@ void XMLUtil::ToStr( int64_t v, char* buffer, int bufferSize )
|
||||
void XMLUtil::ToStr( uint64_t v, char* buffer, int bufferSize )
|
||||
{
|
||||
// horrible syntax trick to make the compiler happy about %llu
|
||||
TIXML_SNPRINTF(buffer, bufferSize, "%llu", (long long)v);
|
||||
TIXML_SNPRINTF(buffer, bufferSize, "%llu", static_cast<unsigned long long>(v));
|
||||
}
|
||||
|
||||
bool XMLUtil::ToInt(const char* str, int* value)
|
||||
@@ -705,7 +716,7 @@ bool XMLUtil::ToInt64(const char* str, int64_t* value)
|
||||
bool XMLUtil::ToUnsigned64(const char* str, uint64_t* value) {
|
||||
unsigned long long v = 0; // horrible syntax trick to make the compiler happy about %llu
|
||||
if(TIXML_SSCANF(str, IsPrefixHex(str) ? "%llx" : "%llu", &v) == 1) {
|
||||
*value = (uint64_t)v;
|
||||
*value = static_cast<uint64_t>(v);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -823,7 +834,17 @@ XMLNode::XMLNode( XMLDocument* doc ) :
|
||||
|
||||
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 ) {
|
||||
_parent->Unlink( this );
|
||||
}
|
||||
@@ -1982,7 +2003,7 @@ char* XMLElement::ParseAttributes( char* p, int* curLineNumPtr )
|
||||
}
|
||||
|
||||
// attribute.
|
||||
if (XMLUtil::IsNameStartChar( (unsigned char) *p ) ) {
|
||||
if (XMLUtil::IsNameStartChar( static_cast<unsigned char>(*p) ) ) {
|
||||
XMLAttribute* attrib = CreateAttribute();
|
||||
TIXMLASSERT( attrib );
|
||||
attrib->_parseLineNum = _document->_parseCurLineNum;
|
||||
@@ -2226,7 +2247,7 @@ void XMLDocument::MarkInUse(const XMLNode* const node)
|
||||
TIXMLASSERT(node);
|
||||
TIXMLASSERT(node->_parent == 0);
|
||||
|
||||
for (int i = 0; i < _unlinked.Size(); ++i) {
|
||||
for (size_t i = 0; i < _unlinked.Size(); ++i) {
|
||||
if (node == _unlinked[i]) {
|
||||
_unlinked.SwapRemove(i);
|
||||
break;
|
||||
@@ -2336,9 +2357,10 @@ static FILE* callfopen( const char* filepath, const char* mode )
|
||||
return fp;
|
||||
}
|
||||
|
||||
void XMLDocument::DeleteNode( XMLNode* node ) {
|
||||
TIXMLASSERT( node );
|
||||
TIXMLASSERT(node->_document == this );
|
||||
void XMLDocument::DeleteNode( XMLNode* node ) {
|
||||
if(node == 0) {
|
||||
return; // check for null pointer
|
||||
}
|
||||
if (node->_parent) {
|
||||
node->_parent->DeleteChild( node );
|
||||
}
|
||||
@@ -2509,7 +2531,7 @@ void XMLDocument::ClearError() {
|
||||
|
||||
void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ... )
|
||||
{
|
||||
TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT );
|
||||
TIXMLASSERT(error >= 0 && error < XML_ERROR_COUNT);
|
||||
_errorID = error;
|
||||
_errorLineNum = lineNum;
|
||||
_errorStr.Reset();
|
||||
@@ -2518,7 +2540,8 @@ void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ...
|
||||
char* buffer = new char[BUFFER_SIZE];
|
||||
|
||||
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);
|
||||
TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d",
|
||||
ErrorIDToName(error), static_cast<int>(error), static_cast<unsigned int>(error), lineNum);
|
||||
|
||||
if (format) {
|
||||
size_t len = strlen(buffer);
|
||||
@@ -2589,7 +2612,7 @@ void XMLDocument::PopDepth()
|
||||
--_parsingDepth;
|
||||
}
|
||||
|
||||
XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :
|
||||
XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth, EscapeAposCharsInAttributes aposInAttributes ) :
|
||||
_elementJustOpened( false ),
|
||||
_stack(),
|
||||
_firstElement( true ),
|
||||
@@ -2606,9 +2629,11 @@ XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :
|
||||
}
|
||||
for( int i=0; i<NUM_ENTITIES; ++i ) {
|
||||
const char entityValue = entities[i].value;
|
||||
const unsigned char flagIndex = static_cast<unsigned char>(entityValue);
|
||||
TIXMLASSERT( flagIndex < ENTITY_RANGE );
|
||||
_entityFlag[flagIndex] = true;
|
||||
if ((aposInAttributes == ESCAPE_APOS_CHARS_IN_ATTRIBUTES) || (entityValue != SINGLE_QUOTE)) {
|
||||
const unsigned char flagIndex = static_cast<unsigned char>(entityValue);
|
||||
TIXMLASSERT( flagIndex < ENTITY_RANGE );
|
||||
_entityFlag[flagIndex] = true;
|
||||
}
|
||||
}
|
||||
_restrictedEntityFlag[static_cast<unsigned char>('&')] = true;
|
||||
_restrictedEntityFlag[static_cast<unsigned char>('<')] = true;
|
||||
@@ -2645,7 +2670,7 @@ void XMLPrinter::Write( const char* data, size_t size )
|
||||
fwrite ( data , sizeof(char), size, _fp);
|
||||
}
|
||||
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 );
|
||||
p[size] = 0;
|
||||
}
|
||||
|
||||
Executable → Regular
+43
-48
@@ -42,14 +42,6 @@ distribution.
|
||||
#endif
|
||||
#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__)
|
||||
# ifndef TINYXML2_DEBUG
|
||||
# define TINYXML2_DEBUG
|
||||
@@ -96,11 +88,11 @@ distribution.
|
||||
/* Versioning, past 1.0.14:
|
||||
http://semver.org/
|
||||
*/
|
||||
static const int TIXML2_MAJOR_VERSION = 10;
|
||||
static const int TIXML2_MAJOR_VERSION = 11;
|
||||
static const int TIXML2_MINOR_VERSION = 0;
|
||||
static const int TIXML2_PATCH_VERSION = 0;
|
||||
|
||||
#define TINYXML2_MAJOR_VERSION 10
|
||||
#define TINYXML2_MAJOR_VERSION 11
|
||||
#define TINYXML2_MINOR_VERSION 0
|
||||
#define TINYXML2_PATCH_VERSION 0
|
||||
|
||||
@@ -199,7 +191,7 @@ private:
|
||||
Has a small initial memory pool, so that low or no usage will not
|
||||
cause a call to new/delete
|
||||
*/
|
||||
template <class T, int INITIAL_SIZE>
|
||||
template <class T, size_t INITIAL_SIZE>
|
||||
class DynArray
|
||||
{
|
||||
public:
|
||||
@@ -227,9 +219,8 @@ public:
|
||||
++_size;
|
||||
}
|
||||
|
||||
T* PushArr( int count ) {
|
||||
TIXMLASSERT( count >= 0 );
|
||||
TIXMLASSERT( _size <= INT_MAX - count );
|
||||
T* PushArr( size_t count ) {
|
||||
TIXMLASSERT( _size <= SIZE_MAX - count );
|
||||
EnsureCapacity( _size+count );
|
||||
T* ret = &_mem[_size];
|
||||
_size += count;
|
||||
@@ -242,7 +233,7 @@ public:
|
||||
return _mem[_size];
|
||||
}
|
||||
|
||||
void PopArr( int count ) {
|
||||
void PopArr( size_t count ) {
|
||||
TIXMLASSERT( _size >= count );
|
||||
_size -= count;
|
||||
}
|
||||
@@ -251,13 +242,13 @@ public:
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
T& operator[](int i) {
|
||||
TIXMLASSERT( i>= 0 && i < _size );
|
||||
T& operator[](size_t i) {
|
||||
TIXMLASSERT( i < _size );
|
||||
return _mem[i];
|
||||
}
|
||||
|
||||
const T& operator[](int i) const {
|
||||
TIXMLASSERT( i>= 0 && i < _size );
|
||||
const T& operator[](size_t i) const {
|
||||
TIXMLASSERT( i < _size );
|
||||
return _mem[i];
|
||||
}
|
||||
|
||||
@@ -266,18 +257,17 @@ public:
|
||||
return _mem[ _size - 1];
|
||||
}
|
||||
|
||||
int Size() const {
|
||||
TIXMLASSERT( _size >= 0 );
|
||||
size_t Size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
int Capacity() const {
|
||||
size_t Capacity() const {
|
||||
TIXMLASSERT( _allocated >= INITIAL_SIZE );
|
||||
return _allocated;
|
||||
}
|
||||
|
||||
void SwapRemove(int i) {
|
||||
TIXMLASSERT(i >= 0 && i < _size);
|
||||
void SwapRemove(size_t i) {
|
||||
TIXMLASSERT(i < _size);
|
||||
TIXMLASSERT(_size > 0);
|
||||
_mem[i] = _mem[_size - 1];
|
||||
--_size;
|
||||
@@ -297,14 +287,14 @@ private:
|
||||
DynArray( const DynArray& ); // not supported
|
||||
void operator=( const DynArray& ); // not supported
|
||||
|
||||
void EnsureCapacity( int cap ) {
|
||||
void EnsureCapacity( size_t cap ) {
|
||||
TIXMLASSERT( cap > 0 );
|
||||
if ( cap > _allocated ) {
|
||||
TIXMLASSERT( cap <= INT_MAX / 2 );
|
||||
const int newAllocated = cap * 2;
|
||||
T* newMem = new T[static_cast<unsigned int>(newAllocated)];
|
||||
TIXMLASSERT( cap <= SIZE_MAX / 2 / sizeof(T));
|
||||
const size_t newAllocated = cap * 2;
|
||||
T* newMem = new T[newAllocated];
|
||||
TIXMLASSERT( newAllocated >= _size );
|
||||
memcpy( newMem, _mem, sizeof(T)*static_cast<size_t>(_size) ); // warning: not using constructors, only works for PODs
|
||||
memcpy( newMem, _mem, sizeof(T) * _size ); // warning: not using constructors, only works for PODs
|
||||
if ( _mem != _pool ) {
|
||||
delete [] _mem;
|
||||
}
|
||||
@@ -314,9 +304,9 @@ private:
|
||||
}
|
||||
|
||||
T* _mem;
|
||||
T _pool[static_cast<size_t>(INITIAL_SIZE)];
|
||||
int _allocated; // objects allocated
|
||||
int _size; // number objects in use
|
||||
T _pool[INITIAL_SIZE];
|
||||
size_t _allocated; // objects allocated
|
||||
size_t _size; // number objects in use
|
||||
};
|
||||
|
||||
|
||||
@@ -330,7 +320,7 @@ public:
|
||||
MemPool() {}
|
||||
virtual ~MemPool() {}
|
||||
|
||||
virtual int ItemSize() const = 0;
|
||||
virtual size_t ItemSize() const = 0;
|
||||
virtual void* Alloc() = 0;
|
||||
virtual void Free( void* ) = 0;
|
||||
virtual void SetTracked() = 0;
|
||||
@@ -340,7 +330,7 @@ public:
|
||||
/*
|
||||
Template child class to create pools of the correct type.
|
||||
*/
|
||||
template< int ITEM_SIZE >
|
||||
template< size_t ITEM_SIZE >
|
||||
class MemPoolT : public MemPool
|
||||
{
|
||||
public:
|
||||
@@ -362,10 +352,10 @@ public:
|
||||
_nUntracked = 0;
|
||||
}
|
||||
|
||||
virtual int ItemSize() const override{
|
||||
virtual size_t ItemSize() const override {
|
||||
return ITEM_SIZE;
|
||||
}
|
||||
int CurrentAllocs() const {
|
||||
size_t CurrentAllocs() const {
|
||||
return _currentAllocs;
|
||||
}
|
||||
|
||||
@@ -376,7 +366,7 @@ public:
|
||||
_blockPtrs.Push( block );
|
||||
|
||||
Item* blockItems = block->items;
|
||||
for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
|
||||
for( size_t i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
|
||||
blockItems[i].next = &(blockItems[i + 1]);
|
||||
}
|
||||
blockItems[ITEMS_PER_BLOCK - 1].next = 0;
|
||||
@@ -417,7 +407,7 @@ public:
|
||||
--_nUntracked;
|
||||
}
|
||||
|
||||
int Untracked() const {
|
||||
size_t Untracked() const {
|
||||
return _nUntracked;
|
||||
}
|
||||
|
||||
@@ -448,10 +438,10 @@ private:
|
||||
DynArray< Block*, 10 > _blockPtrs;
|
||||
Item* _root;
|
||||
|
||||
int _currentAllocs;
|
||||
int _nAllocs;
|
||||
int _maxAllocs;
|
||||
int _nUntracked;
|
||||
size_t _currentAllocs;
|
||||
size_t _nAllocs;
|
||||
size_t _maxAllocs;
|
||||
size_t _nUntracked;
|
||||
};
|
||||
|
||||
|
||||
@@ -892,7 +882,7 @@ public:
|
||||
|
||||
If the 'target' is null, then the nodes will
|
||||
be allocated in the current document. If 'target'
|
||||
is specified, the memory will be allocated is the
|
||||
is specified, the memory will be allocated in the
|
||||
specified XMLDocument.
|
||||
|
||||
NOTE: This is probably not the correct tool to
|
||||
@@ -1981,11 +1971,11 @@ private:
|
||||
void PushDepth();
|
||||
void PopDepth();
|
||||
|
||||
template<class NodeType, int PoolElementSize>
|
||||
template<class NodeType, size_t PoolElementSize>
|
||||
NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
|
||||
};
|
||||
|
||||
template<class NodeType, int PoolElementSize>
|
||||
template<class NodeType, size_t PoolElementSize>
|
||||
inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
|
||||
{
|
||||
TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
|
||||
@@ -2241,13 +2231,18 @@ private:
|
||||
class TINYXML2_LIB XMLPrinter : public XMLVisitor
|
||||
{
|
||||
public:
|
||||
enum EscapeAposCharsInAttributes {
|
||||
ESCAPE_APOS_CHARS_IN_ATTRIBUTES,
|
||||
DONT_ESCAPE_APOS_CHARS_IN_ATTRIBUTES
|
||||
};
|
||||
|
||||
/** Construct the printer. If the FILE* is specified,
|
||||
this will print to the FILE. Else it will print
|
||||
to memory, and the result is available in CStr().
|
||||
If 'compact' is set to true, then output is created
|
||||
with only required whitespace and newlines.
|
||||
*/
|
||||
XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
|
||||
XMLPrinter( FILE* file=0, bool compact = false, int depth = 0, EscapeAposCharsInAttributes aposInAttributes = ESCAPE_APOS_CHARS_IN_ATTRIBUTES );
|
||||
virtual ~XMLPrinter() {}
|
||||
|
||||
/** If streaming, write the BOM and declaration. */
|
||||
@@ -2315,7 +2310,7 @@ public:
|
||||
of the XML file in memory. (Note the size returned
|
||||
includes the terminating null.)
|
||||
*/
|
||||
int CStrSize() const {
|
||||
size_t CStrSize() const {
|
||||
return _buffer.Size();
|
||||
}
|
||||
/**
|
||||
@@ -2375,7 +2370,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
} // tinyxml2
|
||||
} // namespace tinyxml2
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
|
||||
Executable → Regular
+99
-29
@@ -324,9 +324,9 @@ int main( int argc, const char ** argv )
|
||||
|
||||
printf( "Test file '%s' loaded. ErrorID=%d\n", argv[1], errorID );
|
||||
if ( !errorID ) {
|
||||
printf( "Load time=%u\n", (unsigned)(loadTime - startTime) );
|
||||
printf( "Delete time=%u\n", (unsigned)(deleteTime - loadTime) );
|
||||
printf( "Total time=%u\n", (unsigned)(deleteTime - startTime) );
|
||||
printf( "Load time=%u\n", static_cast<unsigned>(loadTime - startTime) );
|
||||
printf( "Delete time=%u\n", static_cast<unsigned>(deleteTime - loadTime) );
|
||||
printf( "Total time=%u\n", static_cast<unsigned>(deleteTime - startTime) );
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
@@ -595,8 +595,8 @@ int main( int argc, const char ** argv )
|
||||
|
||||
result = ele->QueryDoubleAttribute( "attr0", &dVal );
|
||||
XMLTest( "Query attribute: int as double", XML_SUCCESS, result);
|
||||
XMLTest( "Query attribute: int as double", 1, (int)dVal );
|
||||
XMLTest( "Query attribute: int as double", 1, (int)ele->DoubleAttribute("attr0"));
|
||||
XMLTest( "Query attribute: int as double", 1, static_cast<int>(dVal) );
|
||||
XMLTest( "Query attribute: int as double", 1, static_cast<int>(ele->DoubleAttribute("attr0")));
|
||||
|
||||
result = ele->QueryDoubleAttribute( "attr1", &dVal );
|
||||
XMLTest( "Query attribute: double as double", XML_SUCCESS, result);
|
||||
@@ -648,17 +648,17 @@ int main( int argc, const char ** argv )
|
||||
|
||||
{
|
||||
XMLError queryResult = ele->QueryAttribute( "int", &iVal2 );
|
||||
XMLTest( "Query int attribute generic", (int)XML_SUCCESS, queryResult);
|
||||
XMLTest( "Query int attribute generic", static_cast<int>(XML_SUCCESS), queryResult);
|
||||
}
|
||||
{
|
||||
XMLError queryResult = ele->QueryAttribute( "double", &dVal2 );
|
||||
XMLTest( "Query double attribute generic", (int)XML_SUCCESS, queryResult);
|
||||
XMLTest( "Query double attribute generic", static_cast<int>(XML_SUCCESS), queryResult);
|
||||
}
|
||||
|
||||
XMLTest( "Attribute match test", "strValue", ele->Attribute( "str", "strValue" ) );
|
||||
XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
|
||||
XMLTest( "Attribute round trip. int.", 1, iVal );
|
||||
XMLTest( "Attribute round trip. double.", -1, (int)dVal );
|
||||
XMLTest( "Attribute round trip. double.", -1, static_cast<int>(dVal) );
|
||||
XMLTest( "Alternate query", true, iVal == iVal2 );
|
||||
XMLTest( "Alternate query", true, dVal == dVal2 );
|
||||
XMLTest( "Alternate query", true, iVal == ele->IntAttribute("int") );
|
||||
@@ -675,7 +675,7 @@ int main( int argc, const char ** argv )
|
||||
const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
|
||||
0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
|
||||
|
||||
XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) );
|
||||
XMLTest( "UTF-8: Russian value.", reinterpret_cast<const char*>(correctValue), element->Attribute( "value" ) );
|
||||
|
||||
const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
|
||||
0xd1U, 0x81U, 0xd1U, 0x81U,
|
||||
@@ -683,7 +683,7 @@ int main( int argc, const char ** argv )
|
||||
0xd0U, 0xb9U, 0 };
|
||||
const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
|
||||
|
||||
XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText();
|
||||
XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( reinterpret_cast<const char*>(russianElementName) )->FirstChild()->ToText();
|
||||
XMLTest( "UTF-8: Browsing russian element name.",
|
||||
russianText,
|
||||
text->Value() );
|
||||
@@ -824,7 +824,7 @@ int main( int argc, const char ** argv )
|
||||
{
|
||||
int v = 0;
|
||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||
XMLTest("Attribute: int", (int)XML_SUCCESS, queryResult, true);
|
||||
XMLTest("Attribute: int", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||
XMLTest("Attribute: int", -100, v, true);
|
||||
}
|
||||
XMLTest("Attribute: int", -100, element->IntAttribute("attrib"), true);
|
||||
@@ -840,7 +840,7 @@ int main( int argc, const char ** argv )
|
||||
{
|
||||
unsigned v = 0;
|
||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||
XMLTest("Attribute: unsigned", (int)XML_SUCCESS, queryResult, true);
|
||||
XMLTest("Attribute: unsigned", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||
XMLTest("Attribute: unsigned", unsigned(100), v, true);
|
||||
}
|
||||
{
|
||||
@@ -864,7 +864,7 @@ int main( int argc, const char ** argv )
|
||||
{
|
||||
int64_t v = 0;
|
||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||
XMLTest("Attribute: int64_t", (int)XML_SUCCESS, queryResult, true);
|
||||
XMLTest("Attribute: int64_t", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||
XMLTest("Attribute: int64_t", BIG, v, true);
|
||||
}
|
||||
XMLTest("Attribute: int64_t", BIG, element->Int64Attribute("attrib"), true);
|
||||
@@ -880,7 +880,7 @@ int main( int argc, const char ** argv )
|
||||
{
|
||||
uint64_t v = 0;
|
||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||
XMLTest("Attribute: uint64_t", (int)XML_SUCCESS, queryResult, true);
|
||||
XMLTest("Attribute: uint64_t", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||
XMLTest("Attribute: uint64_t", BIG_POS, v, true);
|
||||
}
|
||||
XMLTest("Attribute: uint64_t", BIG_POS, element->Unsigned64Attribute("attrib"), true);
|
||||
@@ -896,7 +896,7 @@ int main( int argc, const char ** argv )
|
||||
{
|
||||
bool v = false;
|
||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||
XMLTest("Attribute: bool", (int)XML_SUCCESS, queryResult, true);
|
||||
XMLTest("Attribute: bool", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||
XMLTest("Attribute: bool", true, v, true);
|
||||
}
|
||||
XMLTest("Attribute: bool", true, element->BoolAttribute("attrib"), true);
|
||||
@@ -924,7 +924,7 @@ int main( int argc, const char ** argv )
|
||||
{
|
||||
double v = 0;
|
||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||
XMLTest("Attribute: bool", (int)XML_SUCCESS, queryResult, true);
|
||||
XMLTest("Attribute: bool", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||
XMLTest("Attribute: double", 100.0, v, true);
|
||||
}
|
||||
XMLTest("Attribute: double", 100.0, element->DoubleAttribute("attrib"), true);
|
||||
@@ -940,7 +940,7 @@ int main( int argc, const char ** argv )
|
||||
{
|
||||
float v = 0;
|
||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||
XMLTest("Attribute: float", (int)XML_SUCCESS, queryResult, true);
|
||||
XMLTest("Attribute: float", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||
XMLTest("Attribute: float", 100.0f, v, true);
|
||||
}
|
||||
XMLTest("Attribute: float", 100.0f, element->FloatAttribute("attrib"), true);
|
||||
@@ -1005,7 +1005,7 @@ int main( int argc, const char ** argv )
|
||||
FILE* fp1 = fopen("resources/out/printer_1.xml", "w");
|
||||
XMLPrinter printer(fp1);
|
||||
|
||||
printer.PushDeclaration("version = '1.0' enconding = 'utf-8'");
|
||||
printer.PushDeclaration("version = '1.0' encoding = 'utf-8'");
|
||||
|
||||
printer.OpenElement("foo");
|
||||
printer.PushAttribute("attrib-text", "text");
|
||||
@@ -1068,15 +1068,15 @@ int main( int argc, const char ** argv )
|
||||
|
||||
unsigned unsigned_value;
|
||||
unsigned_value = root->FirstChildElement("unsigned")->UnsignedText();
|
||||
XMLTest("PushText( unsigned value ) test", (unsigned)12, unsigned_value);
|
||||
XMLTest("PushText( unsigned value ) test", static_cast<unsigned>(12), unsigned_value);
|
||||
|
||||
int64_t int64_t_value;
|
||||
int64_t_value = root->FirstChildElement("int64_t")->Int64Text();
|
||||
XMLTest("PushText( int64_t value ) test", (int64_t) 13, int64_t_value);
|
||||
XMLTest("PushText( int64_t value ) test", static_cast<int64_t>(13), int64_t_value);
|
||||
|
||||
uint64_t uint64_t_value;
|
||||
uint64_t_value = root->FirstChildElement("uint64_t")->Unsigned64Text();
|
||||
XMLTest("PushText( uint64_t value ) test", (uint64_t) 14, uint64_t_value);
|
||||
XMLTest("PushText( uint64_t value ) test", static_cast<uint64_t>(14), uint64_t_value);
|
||||
|
||||
float float_value;
|
||||
float_value = root->FirstChildElement("float")->FloatText();
|
||||
@@ -1096,7 +1096,7 @@ int main( int argc, const char ** argv )
|
||||
|
||||
const XMLDeclaration* declaration = cdoc.FirstChild()->ToDeclaration();
|
||||
const char* declaration_value = declaration->Value();
|
||||
XMLTest("PushDeclaration() test", "version = '1.0' enconding = 'utf-8'", declaration_value);
|
||||
XMLTest("PushDeclaration() test", "version = '1.0' encoding = 'utf-8'", declaration_value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1397,7 +1397,7 @@ int main( int argc, const char ** argv )
|
||||
buf[61] = 0;
|
||||
|
||||
XMLDocument doc;
|
||||
doc.Parse( (const char*)buf);
|
||||
doc.Parse( reinterpret_cast<const char*>(buf) );
|
||||
XMLTest( "Broken CDATA", true, doc.Error() );
|
||||
}
|
||||
|
||||
@@ -1642,7 +1642,7 @@ int main( int argc, const char ** argv )
|
||||
|
||||
static const char* result = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||
XMLTest( "BOM and default declaration", result, printer.CStr(), false );
|
||||
XMLTest( "CStrSize", 42, printer.CStrSize(), false );
|
||||
XMLTest( "CStrSize", true, printer.CStrSize() == 42, false );
|
||||
}
|
||||
{
|
||||
const char* xml = "<ipxml ws='1'><info bla=' /></ipxml>";
|
||||
@@ -1753,7 +1753,7 @@ int main( int argc, const char ** argv )
|
||||
unsigned unsignedValue = 0;
|
||||
XMLError queryResult = pointElement->FirstChildElement( "y" )->QueryUnsignedText( &unsignedValue );
|
||||
XMLTest( "QueryUnsignedText result", XML_SUCCESS, queryResult, false );
|
||||
XMLTest( "QueryUnsignedText", (unsigned)1, unsignedValue, false );
|
||||
XMLTest( "QueryUnsignedText", static_cast<unsigned>(1), unsignedValue, false );
|
||||
}
|
||||
|
||||
{
|
||||
@@ -2025,7 +2025,13 @@ int main( int argc, const char ** argv )
|
||||
XMLTest("Parse nested elements with pedantic whitespace", false, doc.Error());
|
||||
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
|
||||
{
|
||||
XMLDocument doc(true, PEDANTIC_WHITESPACE);
|
||||
@@ -2639,7 +2645,7 @@ int main( int argc, const char ** argv )
|
||||
"<?xml version=\"1.0\"?>\n" // 2 DecL
|
||||
"<root>\r\n" // 3 Element
|
||||
"\n" // 4
|
||||
"text contining new line \n" // 5 Text
|
||||
"text containing new line \n" // 5 Text
|
||||
" and also containing crlf \r\n" // 6
|
||||
"<sub><![CDATA[\n" // 7 Element Text
|
||||
"cdata containing new line \n" // 8
|
||||
@@ -2666,6 +2672,70 @@ int main( int argc, const char ** argv )
|
||||
doc.PrintError();
|
||||
}
|
||||
|
||||
// ---------- CVE-2024-50615 -----------
|
||||
{
|
||||
const char* xml = "<Hello value='12A34' value2='56B78'>Text</Hello>";
|
||||
XMLDocument doc;
|
||||
doc.Parse(xml);
|
||||
const char* value = doc.FirstChildElement()->Attribute("value");
|
||||
const char* value2 = doc.FirstChildElement()->Attribute("value2");
|
||||
XMLTest("Test attribute encode", false, doc.Error());
|
||||
XMLTest("Test decimal value", value, "12A34");
|
||||
XMLTest("Test hex encode", value2, "56B78");
|
||||
}
|
||||
|
||||
{
|
||||
const char* xml = "<Hello value='&#ABC9000000065;' value2='�' value3='�' value4='E' value5='!'>Text</Hello>";
|
||||
XMLDocument doc;
|
||||
doc.Parse(xml);
|
||||
const char* value = doc.FirstChildElement()->Attribute("value");
|
||||
const char* value2 = doc.FirstChildElement()->Attribute("value2");
|
||||
const char* value3 = doc.FirstChildElement()->Attribute("value3");
|
||||
const char* value4 = doc.FirstChildElement()->Attribute("value4");
|
||||
const char* value5 = doc.FirstChildElement()->Attribute("value5");
|
||||
XMLTest("Test attribute encode", false, doc.Error());
|
||||
XMLTest("Test attribute encode too long value", value, "&#ABC9000000065;"); // test long value
|
||||
XMLTest("Test attribute encode out of unicode range", value2, "�"); // out of unicode range
|
||||
XMLTest("Test attribute encode out of int max value", value3, "�"); // out of int max value
|
||||
XMLTest("Test attribute encode with a Hex value", value4, "E"); // hex value in unicode value
|
||||
XMLTest("Test attribute encode with a Hex value", value5, "!"); // hex value in unicode value
|
||||
}
|
||||
|
||||
// ---------- XMLPrinter Apos Escaping ------
|
||||
{
|
||||
const char* testText = "text containing a ' character";
|
||||
XMLDocument doc;
|
||||
XMLElement* element = doc.NewElement( "element" );
|
||||
doc.InsertEndChild( element );
|
||||
element->SetAttribute( "attrib", testText );
|
||||
{
|
||||
XMLPrinter defaultPrinter;
|
||||
doc.Print( &defaultPrinter );
|
||||
const char* defaultOutput = defaultPrinter.CStr();
|
||||
const bool foundTextWithUnescapedApos = (strstr(defaultOutput, testText) != nullptr);
|
||||
XMLTest("Default XMLPrinter should escape ' characters", false, foundTextWithUnescapedApos);
|
||||
{
|
||||
XMLDocument parsingDoc;
|
||||
parsingDoc.Parse(defaultOutput);
|
||||
const XMLAttribute* attrib = parsingDoc.FirstChildElement("element")->FindAttribute("attrib");
|
||||
XMLTest("Default XMLPrinter should output parsable xml", testText, attrib->Value(), true);
|
||||
}
|
||||
}
|
||||
{
|
||||
XMLPrinter customPrinter(0, false, 0, XMLPrinter::DONT_ESCAPE_APOS_CHARS_IN_ATTRIBUTES);
|
||||
doc.Print( &customPrinter );
|
||||
const char* customOutput = customPrinter.CStr();
|
||||
const bool foundTextWithUnescapedApos = (strstr(customOutput, testText) != nullptr);
|
||||
XMLTest("Custom XMLPrinter should not escape ' characters", true, foundTextWithUnescapedApos);
|
||||
{
|
||||
XMLDocument parsingDoc;
|
||||
parsingDoc.Parse(customOutput);
|
||||
const XMLAttribute* attrib = parsingDoc.FirstChildElement("element")->FindAttribute("attrib");
|
||||
XMLTest("Custom XMLPrinter should output parsable xml", testText, attrib->Value(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------- Performance tracking --------------
|
||||
{
|
||||
#if defined( _MSC_VER )
|
||||
@@ -2715,9 +2785,9 @@ int main( int argc, const char ** argv )
|
||||
#endif
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
const double duration = 1000.0 * (double)(end - start) / ((double)freq * (double)COUNT);
|
||||
const double duration = 1000.0 * static_cast<double>(end - start) / (static_cast<double>(freq) * static_cast<double>(COUNT));
|
||||
#else
|
||||
const double duration = (double)(cend - cstart) / (double)COUNT;
|
||||
const double duration = static_cast<double>(cend - cstart) / static_cast<double>(COUNT);
|
||||
#endif
|
||||
printf("\nParsing dream.xml (%s): %.3f milli-seconds\n", note, duration);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user