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

improve fix

This commit is contained in:
Lee Thomason
2024-12-09 21:17:33 -08:00
parent 494735de30
commit ff48ea1bae
+58 -73
View File
@@ -467,104 +467,89 @@ 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; *length = 0;
static const uint32_t MAX_CODE_POINT = 0x10FFFF; static const uint32_t MAX_CODE_POINT = 0x10FFFF;
if ( *(p+1) == '#' && *(p+2) ) { if (*(p + 1) == '#' && *(p + 2)) {
uint32_t ucs = 0; uint32_t ucs = 0;
ptrdiff_t delta = 0; ptrdiff_t delta = 0;
uint32_t mult = 1; uint32_t mult = 1;
static const char SEMICOLON = ';'; 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. // Hexadecimal.
const char* q = p+3; hex = true;
if ( !(*q) ) { radix = 16;
return 0; terminator = 'x';
}
q = strchr( q, SEMICOLON ); q = p + 3;
if ( !q ) {
return 0;
}
TIXMLASSERT( *q == SEMICOLON );
delta = q-p;
--q;
while ( *q != 'x' ) {
uint32_t 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 );
const unsigned int digitScaled = mult * digit;
ucs += digitScaled;
if (ucs > MAX_CODE_POINT) {
return 0;
}
mult *= 16;
--q;
}
} }
else { else {
// Decimal. // Decimal.
const char* q = p+2; q = p + 2;
if ( !(*q) ) { }
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; return 0;
} }
TIXMLASSERT(digit < radix);
q = strchr( q, SEMICOLON ); const unsigned int digitScaled = mult * digit;
ucs += digitScaled;
if ( !q ) { mult *= radix;
return 0;
// 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; --q;
}
while ( *q != '#' ) { // Out of range:
if ( *q >= '0' && *q <= '9' ) { if (ucs > MAX_CODE_POINT) {
const uint32_t digit = *q - '0'; return 0;
TIXMLASSERT( digit < 10 );
const uint32_t digitScaled = mult * digit;
ucs += digitScaled;
if (ucs > MAX_CODE_POINT) {
return 0;
}
}
else {
return 0;
}
mult *= 10;
--q;
}
} }
// convert the UCS to UTF-8 // convert the UCS to UTF-8
TIXMLASSERT(ucs <= MAX_CODE_POINT); ConvertUTF32ToUTF8(ucs, value, length);
ConvertUTF32ToUTF8( ucs, value, length );
return p + delta + 1; return p + delta + 1;
} }
return p+1; return p + 1;
} }
void XMLUtil::ToStr( int v, char* buffer, int bufferSize ) void XMLUtil::ToStr( int v, char* buffer, int bufferSize )
{ {
TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); TIXML_SNPRINTF( buffer, bufferSize, "%d", v );