Fixed a crash when opening broken xml file

This commit is contained in:
Deve 2018-11-22 22:09:05 +01:00
parent 7a2ae14d7c
commit cdb3d2cae5

View File

@ -225,7 +225,7 @@ private:
char_type* start = P; char_type* start = P;
// more forward until '<' found // more forward until '<' found
while(*P != L'<' && *P) while(*P && *P != L'<')
++P; ++P;
// not a node, so return false // not a node, so return false
@ -239,6 +239,7 @@ private:
return true; return true;
} }
if (*P)
++P; ++P;
// based on current token, parse and report next element // based on current token, parse and report next element
@ -297,9 +298,10 @@ private:
CurrentNodeType = EXN_UNKNOWN; CurrentNodeType = EXN_UNKNOWN;
// move until end marked with '>' reached // move until end marked with '>' reached
while(*P != L'>') while(*P && *P != L'>')
++P; ++P;
if (*P)
++P; ++P;
} }
@ -308,6 +310,7 @@ private:
void parseComment() void parseComment()
{ {
CurrentNodeType = EXN_COMMENT; CurrentNodeType = EXN_COMMENT;
if (*P)
P += 1; P += 1;
char_type *pCommentBegin = P; char_type *pCommentBegin = P;
@ -315,7 +318,7 @@ private:
int count = 1; int count = 1;
// move until end of comment reached // move until end of comment reached
while(count) while(*P && count)
{ {
if (*P == L'>') if (*P == L'>')
--count; --count;
@ -326,10 +329,17 @@ private:
++P; ++P;
} }
if (*P)
{
P -= 3; P -= 3;
NodeName = core::string<char_type>(pCommentBegin+2, (int)(P - pCommentBegin-2)); NodeName = core::string<char_type>(pCommentBegin+2, (int)(P - pCommentBegin-2));
P += 3; P += 3;
} }
else
{
NodeName = "";
}
}
//! parses an opening xml element and reads attributes //! parses an opening xml element and reads attributes
@ -343,13 +353,13 @@ private:
const char_type* startName = P; const char_type* startName = P;
// find end of element // find end of element
while(*P != L'>' && !isWhiteSpace(*P)) while(*P && *P != L'>' && !isWhiteSpace(*P))
++P; ++P;
const char_type* endName = P; const char_type* endName = P;
// find Attributes // find Attributes
while(*P != L'>') while(*P && *P != L'>')
{ {
if (isWhiteSpace(*P)) if (isWhiteSpace(*P))
++P; ++P;
@ -362,15 +372,16 @@ private:
// read the attribute names // read the attribute names
const char_type* attributeNameBegin = P; const char_type* attributeNameBegin = P;
while(!isWhiteSpace(*P) && *P != L'=') while(*P && !isWhiteSpace(*P) && *P != L'=')
++P; ++P;
const char_type* attributeNameEnd = P; const char_type* attributeNameEnd = P;
if (*P)
++P; ++P;
// read the attribute value // read the attribute value
// check for quotes and single quotes, thx to murphy // check for quotes and single quotes, thx to murphy
while( (*P != L'\"') && (*P != L'\'') && *P) while(*P && (*P != L'\"') && (*P != L'\''))
++P; ++P;
if (!*P) // malformatted xml file if (!*P) // malformatted xml file
@ -378,16 +389,18 @@ private:
const char_type attributeQuoteChar = *P; const char_type attributeQuoteChar = *P;
if (*P)
++P; ++P;
const char_type* attributeValueBegin = P; const char_type* attributeValueBegin = P;
while(*P != attributeQuoteChar && *P) while(*P && *P != attributeQuoteChar)
++P; ++P;
if (!*P) // malformatted xml file if (!*P) // malformatted xml file
return; return;
const char_type* attributeValueEnd = P; const char_type* attributeValueEnd = P;
if (*P)
++P; ++P;
SAttribute attr; SAttribute attr;
@ -403,6 +416,7 @@ private:
else else
{ {
// tag is closed directly // tag is closed directly
if (*P)
++P; ++P;
IsEmptyElement = true; IsEmptyElement = true;
break; break;
@ -420,6 +434,7 @@ private:
NodeName = core::string<char_type>(startName, (int)(endName - startName)); NodeName = core::string<char_type>(startName, (int)(endName - startName));
if (*P)
++P; ++P;
} }
@ -431,20 +446,23 @@ private:
IsEmptyElement = false; IsEmptyElement = false;
Attributes.clear(); Attributes.clear();
if (*P)
++P; ++P;
const char_type* pBeginClose = P; const char_type* pBeginClose = P;
while(*P != L'>') while(*P && *P != L'>')
++P; ++P;
NodeName = core::string<char_type>(pBeginClose, (int)(P - pBeginClose)); NodeName = core::string<char_type>(pBeginClose, (int)(P - pBeginClose));
if (*P)
++P; ++P;
} }
//! parses a possible CDATA section, returns false if begin was not a CDATA section //! parses a possible CDATA section, returns false if begin was not a CDATA section
bool parseCDATA() bool parseCDATA()
{ {
if (*(P+1) != L'[') if (!*P || !*(P+1) || *(P+1) != L'[')
return false; return false;
CurrentNodeType = EXN_CDATA; CurrentNodeType = EXN_CDATA;