@@ -24,7 +24,7 @@ distribution.
2424#include " tinyxml2.h"
2525
2626#include < new> // yes, this one new style header, is in the Android SDK.
27- #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
27+ #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) || defined(__CC_ARM)
2828# include < stddef.h>
2929# include < stdarg.h>
3030#else
@@ -106,14 +106,9 @@ distribution.
106106#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__CYGWIN__)
107107 #define TIXML_FSEEK fseeko
108108 #define TIXML_FTELL ftello
109- #elif defined(__ANDROID__)
110- #if __ANDROID_API__ > 24
111- #define TIXML_FSEEK fseeko64
112- #define TIXML_FTELL ftello64
113- #else
114- #define TIXML_FSEEK fseeko
115- #define TIXML_FTELL ftello
116- #endif
109+ #elif defined(__ANDROID__) && __ANDROID_API__ > 24
110+ #define TIXML_FSEEK fseeko64
111+ #define TIXML_FTELL ftello64
117112#else
118113 #define TIXML_FSEEK fseek
119114 #define TIXML_FTELL ftell
@@ -239,13 +234,13 @@ char* StrPair::ParseName( char* p )
239234 if ( !p || !(*p) ) {
240235 return 0 ;
241236 }
242- if ( !XMLUtil::IsNameStartChar ( ( unsigned char ) *p ) ) {
237+ if ( !XMLUtil::IsNameStartChar ( static_cast < unsigned char >(*p) ) ) {
243238 return 0 ;
244239 }
245240
246241 char * const start = p;
247242 ++p;
248- while ( *p && XMLUtil::IsNameChar ( ( unsigned char ) *p ) ) {
243+ while ( *p && XMLUtil::IsNameChar ( static_cast < unsigned char >(*p) ) ) {
249244 ++p;
250245 }
251246
@@ -472,102 +467,94 @@ void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length
472467}
473468
474469
475- const char * XMLUtil::GetCharacterRef ( const char * p, char * value, int * length )
470+ const char * XMLUtil::GetCharacterRef (const char * p, char * value, int * length)
476471{
477- // Presume an entity, and pull it out.
472+ // Assume an entity, and pull it out.
478473 *length = 0 ;
479474
480- if ( *(p+1 ) == ' #' && *(p+2 ) ) {
481- unsigned long ucs = 0 ;
482- TIXMLASSERT ( sizeof ( ucs ) >= 4 );
475+ static const uint32_t MAX_CODE_POINT = 0x10FFFF ;
476+
477+ if (*(p + 1 ) == ' #' && *(p + 2 )) {
478+ uint32_t ucs = 0 ;
483479 ptrdiff_t delta = 0 ;
484- unsigned mult = 1 ;
480+ uint32_t mult = 1 ;
485481 static const char SEMICOLON = ' ;' ;
486482
487- if ( *(p+2 ) == ' x' ) {
483+ bool hex = false ;
484+ uint32_t radix = 10 ;
485+ const char * q = 0 ;
486+ char terminator = ' #' ;
487+
488+ if (*(p + 2 ) == ' x' ) {
488489 // Hexadecimal.
489- const char * q = p+3 ;
490- if ( !(*q) ) {
491- return 0 ;
492- }
490+ hex = true ;
491+ radix = 16 ;
492+ terminator = ' x' ;
493493
494- q = strchr ( q, SEMICOLON );
494+ q = p + 3 ;
495+ }
496+ else {
497+ // Decimal.
498+ q = p + 2 ;
499+ }
500+ if (!(*q)) {
501+ return 0 ;
502+ }
495503
496- if ( !q ) {
497- return 0 ;
498- }
499- TIXMLASSERT ( *q == SEMICOLON );
504+ q = strchr (q, SEMICOLON);
505+ if (!q) {
506+ return 0 ;
507+ }
508+ TIXMLASSERT (*q == SEMICOLON);
500509
501- delta = q- p;
502- --q;
510+ delta = q - p;
511+ --q;
503512
504- while ( *q != ' x ' ) {
505- unsigned int digit = 0 ;
513+ while (*q != terminator ) {
514+ uint32_t digit = 0 ;
506515
507- if ( *q >= ' 0' && *q <= ' 9' ) {
508- digit = *q - ' 0' ;
509- }
510- else if ( *q >= ' a' && *q <= ' f' ) {
511- digit = *q - ' a' + 10 ;
512- }
513- else if ( *q >= ' A' && *q <= ' F' ) {
514- digit = *q - ' A' + 10 ;
515- }
516- else {
517- return 0 ;
518- }
519- TIXMLASSERT ( digit < 16 );
520- TIXMLASSERT ( digit == 0 || mult <= UINT_MAX / digit );
521- const unsigned int digitScaled = mult * digit;
522- TIXMLASSERT ( ucs <= ULONG_MAX - digitScaled );
523- ucs += digitScaled;
524- TIXMLASSERT ( mult <= UINT_MAX / 16 );
525- mult *= 16 ;
526- --q;
516+ if (*q >= ' 0' && *q <= ' 9' ) {
517+ digit = *q - ' 0' ;
527518 }
528- }
529- else {
530- // Decimal.
531- const char * q = p+2 ;
532- if ( !(*q) ) {
533- return 0 ;
519+ else if (hex && (*q >= ' a' && *q <= ' f' )) {
520+ digit = *q - ' a' + 10 ;
534521 }
535-
536- q = strchr ( q, SEMICOLON ) ;
537-
538- if ( !q ) {
522+ else if (hex && (*q >= ' A ' && *q <= ' F ' )) {
523+ digit = *q - ' A ' + 10 ;
524+ }
525+ else {
539526 return 0 ;
540527 }
541- TIXMLASSERT ( *q == SEMICOLON );
542-
543- delta = q-p;
544- --q;
545-
546- while ( *q != ' #' ) {
547- if ( *q >= ' 0' && *q <= ' 9' ) {
548- const unsigned int digit = *q - ' 0' ;
549- TIXMLASSERT ( digit < 10 );
550- TIXMLASSERT ( digit == 0 || mult <= UINT_MAX / digit );
551- const unsigned int digitScaled = mult * digit;
552- TIXMLASSERT ( ucs <= ULONG_MAX - digitScaled );
553- ucs += digitScaled;
554- }
555- else {
556- return 0 ;
557- }
558- TIXMLASSERT ( mult <= UINT_MAX / 10 );
559- mult *= 10 ;
560- --q;
528+ TIXMLASSERT (digit < radix);
529+
530+ const unsigned int digitScaled = mult * digit;
531+ ucs += digitScaled;
532+ mult *= radix;
533+
534+ // Security check: could a value exist that is out of range?
535+ // Easily; limit to the MAX_CODE_POINT, which also allows for a
536+ // bunch of leading zeroes.
537+ if (mult > MAX_CODE_POINT) {
538+ mult = MAX_CODE_POINT;
561539 }
540+ --q;
541+ }
542+ // Out of range:
543+ if (ucs > MAX_CODE_POINT) {
544+ return 0 ;
562545 }
563546 // convert the UCS to UTF-8
564- ConvertUTF32ToUTF8 ( ucs, value, length );
547+ ConvertUTF32ToUTF8 (ucs, value, length);
548+ if (length == 0 ) {
549+ // If length is 0, there was an error. (Security? Bad input?)
550+ // Fail safely.
551+ return 0 ;
552+ }
565553 return p + delta + 1 ;
566554 }
567- return p+ 1 ;
555+ return p + 1 ;
568556}
569557
570-
571558void XMLUtil::ToStr ( int v, char * buffer, int bufferSize )
572559{
573560 TIXML_SNPRINTF ( buffer, bufferSize, " %d" , v );
@@ -610,7 +597,7 @@ void XMLUtil::ToStr( int64_t v, char* buffer, int bufferSize )
610597void XMLUtil::ToStr ( uint64_t v, char * buffer, int bufferSize )
611598{
612599 // horrible syntax trick to make the compiler happy about %llu
613- TIXML_SNPRINTF (buffer, bufferSize, " %llu" , ( long long )v );
600+ TIXML_SNPRINTF (buffer, bufferSize, " %llu" , static_cast < unsigned long long >(v) );
614601}
615602
616603bool XMLUtil::ToInt (const char * str, int * value)
@@ -705,7 +692,7 @@ bool XMLUtil::ToInt64(const char* str, int64_t* value)
705692bool XMLUtil::ToUnsigned64 (const char * str, uint64_t * value) {
706693 unsigned long long v = 0 ; // horrible syntax trick to make the compiler happy about %llu
707694 if (TIXML_SSCANF (str, IsPrefixHex (str) ? " %llx" : " %llu" , &v) == 1 ) {
708- *value = ( uint64_t )v ;
695+ *value = static_cast < uint64_t >(v) ;
709696 return true ;
710697 }
711698 return false ;
@@ -1982,7 +1969,7 @@ char* XMLElement::ParseAttributes( char* p, int* curLineNumPtr )
19821969 }
19831970
19841971 // attribute.
1985- if (XMLUtil::IsNameStartChar ( ( unsigned char ) *p ) ) {
1972+ if (XMLUtil::IsNameStartChar ( static_cast < unsigned char >(*p) ) ) {
19861973 XMLAttribute* attrib = CreateAttribute ();
19871974 TIXMLASSERT ( attrib );
19881975 attrib->_parseLineNum = _document->_parseCurLineNum ;
@@ -2226,7 +2213,7 @@ void XMLDocument::MarkInUse(const XMLNode* const node)
22262213 TIXMLASSERT (node);
22272214 TIXMLASSERT (node->_parent == 0 );
22282215
2229- for (int i = 0 ; i < _unlinked.Size (); ++i) {
2216+ for (size_t i = 0 ; i < _unlinked.Size (); ++i) {
22302217 if (node == _unlinked[i]) {
22312218 _unlinked.SwapRemove (i);
22322219 break ;
@@ -2509,7 +2496,7 @@ void XMLDocument::ClearError() {
25092496
25102497void XMLDocument::SetError ( XMLError error, int lineNum, const char * format, ... )
25112498{
2512- TIXMLASSERT ( error >= 0 && error < XML_ERROR_COUNT );
2499+ TIXMLASSERT (error >= 0 && error < XML_ERROR_COUNT);
25132500 _errorID = error;
25142501 _errorLineNum = lineNum;
25152502 _errorStr.Reset ();
@@ -2518,7 +2505,8 @@ void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ...
25182505 char * buffer = new char [BUFFER_SIZE];
25192506
25202507 TIXMLASSERT (sizeof (error) <= sizeof (int ));
2521- TIXML_SNPRINTF (buffer, BUFFER_SIZE, " Error=%s ErrorID=%d (0x%x) Line number=%d" , ErrorIDToName (error), int (error), int (error), lineNum);
2508+ TIXML_SNPRINTF (buffer, BUFFER_SIZE, " Error=%s ErrorID=%d (0x%x) Line number=%d" ,
2509+ ErrorIDToName (error), static_cast <int >(error), static_cast <unsigned int >(error), lineNum);
25222510
25232511 if (format) {
25242512 size_t len = strlen (buffer);
0 commit comments