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

improve fix

This commit is contained in:
Lee Thomason
2024-12-09 21:17:33 -08:00
parent 494735de30
commit ff48ea1bae
+32 -47
View File
@@ -469,7 +469,7 @@ 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;
@@ -480,9 +480,23 @@ const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
uint32_t mult = 1; uint32_t mult = 1;
static const char SEMICOLON = ';'; static const char SEMICOLON = ';';
bool hex = false;
uint32_t radix = 10;
const char* q = 0;
char terminator = '#';
if (*(p + 2) == 'x') { if (*(p + 2) == 'x') {
// Hexadecimal. // Hexadecimal.
const char* q = p+3; hex = true;
radix = 16;
terminator = 'x';
q = p + 3;
}
else {
// Decimal.
q = p + 2;
}
if (!(*q)) { if (!(*q)) {
return 0; return 0;
} }
@@ -496,75 +510,46 @@ const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
delta = q - p; delta = q - p;
--q; --q;
while ( *q != 'x' ) { while (*q != terminator) {
uint32_t digit = 0; uint32_t digit = 0;
if (*q >= '0' && *q <= '9') { if (*q >= '0' && *q <= '9') {
digit = *q - '0'; digit = *q - '0';
} }
else if ( *q >= 'a' && *q <= 'f' ) { else if (hex && (*q >= 'a' && *q <= 'f')) {
digit = *q - 'a' + 10; digit = *q - 'a' + 10;
} }
else if ( *q >= 'A' && *q <= 'F' ) { else if (hex && (*q >= 'A' && *q <= 'F')) {
digit = *q - 'A' + 10; digit = *q - 'A' + 10;
} }
else { else {
return 0; return 0;
} }
TIXMLASSERT( digit < 16 ); TIXMLASSERT(digit < radix);
const unsigned int digitScaled = mult * digit; const unsigned int digitScaled = mult * digit;
ucs += digitScaled; 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;
}
--q;
}
// Out of range:
if (ucs > MAX_CODE_POINT) { if (ucs > MAX_CODE_POINT) {
return 0; return 0;
} }
mult *= 16;
--q;
}
}
else {
// Decimal.
const char* q = p+2;
if ( !(*q) ) {
return 0;
}
q = strchr( q, SEMICOLON );
if ( !q ) {
return 0;
}
TIXMLASSERT( *q == SEMICOLON );
delta = q-p;
--q;
while ( *q != '#' ) {
if ( *q >= '0' && *q <= '9' ) {
const uint32_t digit = *q - '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 );