Skip to content

Commit 81c0eb5

Browse files
fix(tinyxml2): CVE-2024-50614/50615 - fix integer overflow in char refs
Fix integer overflow vulnerability in XML character reference parsing. The code could overflow when parsing large numeric character references. - Use uint32_t instead of unsigned long for UCS values - Add MAX_CODE_POINT check (0x10FFFF) to prevent overflow - Remove unnecessary assertion checks that don't prevent overflow Upstream: leethomason/tinyxml2@494735de30c9 Generated-By: glm-5.1 Co-Authored-By: hudeng <hudeng@deepin.org>
1 parent fa4041e commit 81c0eb5

2 files changed

Lines changed: 95 additions & 91 deletions

File tree

Lines changed: 77 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,77 @@
1-
Index: tinyxml2/tinyxml2.cpp
2-
===================================================================
3-
--- tinyxml2.orig/tinyxml2.cpp
4-
+++ tinyxml2/tinyxml2.cpp
5-
@@ -472,11 +472,11 @@ const char* XMLUtil::GetCharacterRef( co
6-
// Presume an entity, and pull it out.
7-
*length = 0;
8-
9-
+ static const uint32_t MAX_CODE_POINT = 0x10FFFF;
10-
+
11-
if ( *(p+1) == '#' && *(p+2) ) {
12-
- unsigned long ucs = 0;
13-
- TIXMLASSERT( sizeof( ucs ) >= 4 );
14-
- ptrdiff_t delta = 0;
15-
- unsigned mult = 1;
16-
+ uint32_t ucs = 0;
17-
+ uint32_t mult = 1;
18-
static const char SEMICOLON = ';';
19-
20-
if ( *(p+2) == 'x' ) {
21-
@@ -497,7 +497,7 @@ const char* XMLUtil::GetCharacterRef( co
22-
--q;
23-
24-
while ( *q != 'x' ) {
25-
- unsigned int digit = 0;
26-
+ uint32_t digit = 0;
27-
28-
if ( *q >= '0' && *q <= '9' ) {
29-
digit = *q - '0';
30-
@@ -512,11 +512,12 @@ const char* XMLUtil::GetCharacterRef( co
31-
return 0;
32-
}
33-
TIXMLASSERT( digit < 16 );
34-
- TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
35-
- const unsigned int digitScaled = mult * digit;
36-
- TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
37-
+ const uint32_t digitScaled = mult * digit;
38-
ucs += digitScaled;
39-
- TIXMLASSERT( mult <= UINT_MAX / 16 );
40-
+ if (ucs > MAX_CODE_POINT) {
41-
+ return 0;
42-
+ }
43-
+
44-
mult *= 16;
45-
--q;
46-
}
47-
@@ -540,22 +541,23 @@ const char* XMLUtil::GetCharacterRef( co
48-
49-
while ( *q != '#' ) {
50-
if ( *q >= '0' && *q <= '9' ) {
51-
- const unsigned int digit = *q - '0';
52-
+ const uint32_t digit = *q - '0';
53-
TIXMLASSERT( digit < 10 );
54-
- TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
55-
- const unsigned int digitScaled = mult * digit;
56-
- TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
57-
+ const uint32_t digitScaled = mult * digit;
58-
ucs += digitScaled;
59-
+ if (ucs > MAX_CODE_POINT) {
60-
+ return 0;
61-
+ }
62-
}
63-
else {
64-
return 0;
65-
}
66-
- TIXMLASSERT( mult <= UINT_MAX / 10 );
67-
mult *= 10;
68-
--q;
69-
}
70-
}
71-
// convert the UCS to UTF-8
72-
+ TIXMLASSERT(ucs <= MAX_CODE_POINT);
73-
ConvertUTF32ToUTF8( ucs, value, length );
74-
return p + delta + 1;
75-
}
1+
--- a/tinyxml2.cpp
2+
+++ b/tinyxml2.cpp
3+
@@ -471,12 +471,13 @@
4+
{
5+
// Presume an entity, and pull it out.
6+
*length = 0;
7+
+ static const uint32_t MAX_CODE_POINT = 0x10FFFF;
8+
9+
if ( *(p+1) == '#' && *(p+2) ) {
10+
- unsigned long ucs = 0;
11+
+ uint32_t ucs = 0;
12+
TIXMLASSERT( sizeof( ucs ) >= 4 );
13+
ptrdiff_t delta = 0;
14+
- unsigned mult = 1;
15+
+ uint32_t mult = 1;
16+
static const char SEMICOLON = ';';
17+
18+
if ( *(p+2) == 'x' ) {
19+
@@ -497,7 +498,7 @@
20+
--q;
21+
22+
while ( *q != 'x' ) {
23+
- unsigned int digit = 0;
24+
+ uint32_t digit = 0;
25+
26+
if ( *q >= '0' && *q <= '9' ) {
27+
digit = *q - '0';
28+
@@ -512,12 +513,12 @@
29+
return 0;
30+
}
31+
TIXMLASSERT( digit < 16 );
32+
- TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
33+
- const unsigned int digitScaled = mult * digit;
34+
- TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
35+
- ucs += digitScaled;
36+
- TIXMLASSERT( mult <= UINT_MAX / 16 );
37+
- mult *= 16;
38+
+ const uint32_t digitScaled = mult * digit;
39+
+ ucs += digitScaled;
40+
+ if (ucs > MAX_CODE_POINT) {
41+
+ return 0;
42+
+ }
43+
+ mult *= 16;
44+
--q;
45+
}
46+
}
47+
@@ -540,22 +541,23 @@
48+
49+
while ( *q != '#' ) {
50+
if ( *q >= '0' && *q <= '9' ) {
51+
- const unsigned int digit = *q - '0';
52+
+ const uint32_t digit = *q - '0';
53+
TIXMLASSERT( digit < 10 );
54+
- TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
55+
- const unsigned int digitScaled = mult * digit;
56+
- TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
57+
- ucs += digitScaled;
58+
+ const uint32_t digitScaled = mult * digit;
59+
+ ucs += digitScaled;
60+
+ if (ucs > MAX_CODE_POINT) {
61+
+ return 0;
62+
+ }
63+
}
64+
else {
65+
return 0;
66+
}
67+
- TIXMLASSERT( mult <= UINT_MAX / 10 );
68+
- mult *= 10;
69+
+ mult *= 10;
70+
--q;
71+
}
72+
}
73+
// convert the UCS to UTF-8
74+
+ TIXMLASSERT(ucs <= MAX_CODE_POINT);
75+
ConvertUTF32ToUTF8( ucs, value, length );
76+
return p + delta + 1;
77+
}

tinyxml2.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -471,12 +471,13 @@ const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
471471
{
472472
// Presume an entity, and pull it out.
473473
*length = 0;
474+
static const uint32_t MAX_CODE_POINT = 0x10FFFF;
474475

475476
if ( *(p+1) == '#' && *(p+2) ) {
476-
unsigned long ucs = 0;
477+
uint32_t ucs = 0;
477478
TIXMLASSERT( sizeof( ucs ) >= 4 );
478479
ptrdiff_t delta = 0;
479-
unsigned mult = 1;
480+
uint32_t mult = 1;
480481
static const char SEMICOLON = ';';
481482

482483
if ( *(p+2) == 'x' ) {
@@ -497,7 +498,7 @@ const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
497498
--q;
498499

499500
while ( *q != 'x' ) {
500-
unsigned int digit = 0;
501+
uint32_t digit = 0;
501502

502503
if ( *q >= '0' && *q <= '9' ) {
503504
digit = *q - '0';
@@ -512,12 +513,12 @@ const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
512513
return 0;
513514
}
514515
TIXMLASSERT( digit < 16 );
515-
TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
516-
const unsigned int digitScaled = mult * digit;
517-
TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
518-
ucs += digitScaled;
519-
TIXMLASSERT( mult <= UINT_MAX / 16 );
520-
mult *= 16;
516+
const uint32_t digitScaled = mult * digit;
517+
ucs += digitScaled;
518+
if (ucs > MAX_CODE_POINT) {
519+
return 0;
520+
}
521+
mult *= 16;
521522
--q;
522523
}
523524
}
@@ -540,22 +541,23 @@ const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
540541

541542
while ( *q != '#' ) {
542543
if ( *q >= '0' && *q <= '9' ) {
543-
const unsigned int digit = *q - '0';
544+
const uint32_t digit = *q - '0';
544545
TIXMLASSERT( digit < 10 );
545-
TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
546-
const unsigned int digitScaled = mult * digit;
547-
TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
548-
ucs += digitScaled;
546+
const uint32_t digitScaled = mult * digit;
547+
ucs += digitScaled;
548+
if (ucs > MAX_CODE_POINT) {
549+
return 0;
550+
}
549551
}
550552
else {
551553
return 0;
552554
}
553-
TIXMLASSERT( mult <= UINT_MAX / 10 );
554-
mult *= 10;
555+
mult *= 10;
555556
--q;
556557
}
557558
}
558559
// convert the UCS to UTF-8
560+
TIXMLASSERT(ucs <= MAX_CODE_POINT);
559561
ConvertUTF32ToUTF8( ucs, value, length );
560562
return p + delta + 1;
561563
}

0 commit comments

Comments
 (0)