Merge pull request #296 from Dmitry-Me/assertForImpossibleCase
Assert for impossible case
diff --git a/tinyxml2.cpp b/tinyxml2.cpp
index 5b32f40..6d8573b 100755
--- a/tinyxml2.cpp
+++ b/tinyxml2.cpp
@@ -228,11 +228,19 @@
const int buflen = 10;
char buf[buflen] = { 0 };
int len = 0;
- p = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) );
- TIXMLASSERT( 0 <= len && len <= buflen );
- TIXMLASSERT( q + len <= p );
- memcpy( q, buf, len );
- q += len;
+ char* adjusted = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) );
+ if ( adjusted == 0 ) {
+ *q = *p;
+ ++p;
+ ++q;
+ }
+ else {
+ TIXMLASSERT( 0 <= len && len <= buflen );
+ TIXMLASSERT( q + len <= adjusted );
+ p = adjusted;
+ memcpy( q, buf, len );
+ q += len;
+ }
}
else {
int i=0;
@@ -375,18 +383,25 @@
--q;
while ( *q != 'x' ) {
+ unsigned int digit = 0;
+
if ( *q >= '0' && *q <= '9' ) {
- ucs += mult * (*q - '0');
+ digit = *q - '0';
}
else if ( *q >= 'a' && *q <= 'f' ) {
- ucs += mult * (*q - 'a' + 10);
+ digit = *q - 'a' + 10;
}
else if ( *q >= 'A' && *q <= 'F' ) {
- ucs += mult * (*q - 'A' + 10 );
+ digit = *q - 'A' + 10;
}
else {
return 0;
}
+ TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
+ TIXMLASSERT( digit >= 0 && digit < 16);
+ const unsigned int digitScaled = mult * digit;
+ TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
+ ucs += digitScaled;
TIXMLASSERT( mult <= UINT_MAX / 16 );
mult *= 16;
--q;
@@ -411,7 +426,11 @@
while ( *q != '#' ) {
if ( *q >= '0' && *q <= '9' ) {
- ucs += mult * (*q - '0');
+ const unsigned int digit = *q - '0';
+ TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
+ const unsigned int digitScaled = mult * digit;
+ TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
+ ucs += digitScaled;
}
else {
return 0;
diff --git a/xmltest.cpp b/xmltest.cpp
index c231024..243628c 100644
--- a/xmltest.cpp
+++ b/xmltest.cpp
@@ -1416,6 +1416,16 @@
XMLPrinter printer;
}
+ {
+ // Issue 291. Should not crash
+ const char* xml = "�</a>";
+ XMLDocument doc;
+ doc.Parse( xml );
+
+ XMLPrinter printer;
+ doc.Print( &printer );
+ }
+
// ----------- Performance tracking --------------
{
#if defined( _MSC_VER )