@ -1,4 +1,4 @@
/* c5625880f4bf417c1463deee4eb92d86ff413f802048621c57e25fe483eb59e4 (2.6.4 +)
/* 7d6840a33c250b74adb0ba295d6ec818dccebebaffc8c3ed27d0b29c28adbeb3 (2.7.0 +)
__ __ _
__ __ _
___ \ \ / / _ __ __ _ | | _
___ \ \ / / _ __ __ _ | | _
/ _ \ \ / | ' _ \ / _ ` | __ |
/ _ \ \ / | ' _ \ / _ ` | __ |
@ -13,7 +13,7 @@
Copyright ( c ) 2002 - 2016 Karl Waclawek < karl @ waclawek . net >
Copyright ( c ) 2002 - 2016 Karl Waclawek < karl @ waclawek . net >
Copyright ( c ) 2005 - 2009 Steven Solie < steven @ solie . ca >
Copyright ( c ) 2005 - 2009 Steven Solie < steven @ solie . ca >
Copyright ( c ) 2016 Eric Rahm < erahm @ mozilla . com >
Copyright ( c ) 2016 Eric Rahm < erahm @ mozilla . com >
Copyright ( c ) 2016 - 202 4 Sebastian Pipping < sebastian @ pipping . org >
Copyright ( c ) 2016 - 202 5 Sebastian Pipping < sebastian @ pipping . org >
Copyright ( c ) 2016 Gaurav < g . gupta @ samsung . com >
Copyright ( c ) 2016 Gaurav < g . gupta @ samsung . com >
Copyright ( c ) 2016 Thomas Beutlich < tc @ tbeu . de >
Copyright ( c ) 2016 Thomas Beutlich < tc @ tbeu . de >
Copyright ( c ) 2016 Gustavo Grieco < gustavo . grieco @ imag . fr >
Copyright ( c ) 2016 Gustavo Grieco < gustavo . grieco @ imag . fr >
@ -39,7 +39,7 @@
Copyright ( c ) 2022 Sean McBride < sean @ rogue - research . com >
Copyright ( c ) 2022 Sean McBride < sean @ rogue - research . com >
Copyright ( c ) 2023 Owain Davies < owaind @ bath . edu >
Copyright ( c ) 2023 Owain Davies < owaind @ bath . edu >
Copyright ( c ) 2023 - 2024 Sony Corporation / Snild Dolkow < snild @ sony . com >
Copyright ( c ) 2023 - 2024 Sony Corporation / Snild Dolkow < snild @ sony . com >
Copyright ( c ) 2024 Berkay Eren Ü r ü n < berkay . ueruen @ siemens . com >
Copyright ( c ) 2024 - 2025 Berkay Eren Ü r ü n < berkay . ueruen @ siemens . com >
Copyright ( c ) 2024 Hanno B ö ck < hanno @ gentoo . org >
Copyright ( c ) 2024 Hanno B ö ck < hanno @ gentoo . org >
Licensed under the MIT license :
Licensed under the MIT license :
@ -325,6 +325,10 @@ typedef struct {
const XML_Char * publicId ;
const XML_Char * publicId ;
const XML_Char * notation ;
const XML_Char * notation ;
XML_Bool open ;
XML_Bool open ;
XML_Bool hasMore ; /* true if entity has not been completely processed */
/* An entity can be open while being already completely processed (hasMore ==
XML_FALSE ) . The reason is the delayed closing of entities until their inner
entities are processed and closed */
XML_Bool is_param ;
XML_Bool is_param ;
XML_Bool is_internal ; /* true if declared in internal subset outside PE */
XML_Bool is_internal ; /* true if declared in internal subset outside PE */
} ENTITY ;
} ENTITY ;
@ -415,6 +419,12 @@ typedef struct {
int * scaffIndex ;
int * scaffIndex ;
} DTD ;
} DTD ;
enum EntityType {
ENTITY_INTERNAL ,
ENTITY_ATTRIBUTE ,
ENTITY_VALUE ,
} ;
typedef struct open_internal_entity {
typedef struct open_internal_entity {
const char * internalEventPtr ;
const char * internalEventPtr ;
const char * internalEventEndPtr ;
const char * internalEventEndPtr ;
@ -422,6 +432,7 @@ typedef struct open_internal_entity {
ENTITY * entity ;
ENTITY * entity ;
int startTagLevel ;
int startTagLevel ;
XML_Bool betweenDecl ; /* WFC: PE Between Declarations */
XML_Bool betweenDecl ; /* WFC: PE Between Declarations */
enum EntityType type ;
} OPEN_INTERNAL_ENTITY ;
} OPEN_INTERNAL_ENTITY ;
enum XML_Account {
enum XML_Account {
@ -481,8 +492,8 @@ static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
const char * next , const char * * nextPtr ,
const char * next , const char * * nextPtr ,
XML_Bool haveMore , XML_Bool allowClosingDoctype ,
XML_Bool haveMore , XML_Bool allowClosingDoctype ,
enum XML_Account account ) ;
enum XML_Account account ) ;
static enum XML_Error process Internal Entity( XML_Parser parser , ENTITY * entity ,
static enum XML_Error process Entity( XML_Parser parser , ENTITY * entity ,
XML_Bool betweenDecl ) ;
XML_Bool betweenDecl , enum EntityType type ) ;
static enum XML_Error doContent ( XML_Parser parser , int startTagLevel ,
static enum XML_Error doContent ( XML_Parser parser , int startTagLevel ,
const ENCODING * enc , const char * start ,
const ENCODING * enc , const char * start ,
const char * end , const char * * endPtr ,
const char * end , const char * * endPtr ,
@ -513,18 +524,22 @@ static enum XML_Error storeAttributeValue(XML_Parser parser,
const char * ptr , const char * end ,
const char * ptr , const char * end ,
STRING_POOL * pool ,
STRING_POOL * pool ,
enum XML_Account account ) ;
enum XML_Account account ) ;
static enum XML_Error appendAttributeValue ( XML_Parser parser ,
static enum XML_Error
const ENCODING * enc ,
appendAttributeValue ( XML_Parser parser , const ENCODING * enc , XML_Bool isCdata ,
XML_Bool isCdata , const char * ptr ,
const char * ptr , const char * end , STRING_POOL * pool ,
const char * end , STRING_POOL * pool ,
enum XML_Account account , const char * * nextPtr ) ;
enum XML_Account account ) ;
static ATTRIBUTE_ID * getAttributeId ( XML_Parser parser , const ENCODING * enc ,
static ATTRIBUTE_ID * getAttributeId ( XML_Parser parser , const ENCODING * enc ,
const char * start , const char * end ) ;
const char * start , const char * end ) ;
static int setElementTypePrefix ( XML_Parser parser , ELEMENT_TYPE * elementType ) ;
static int setElementTypePrefix ( XML_Parser parser , ELEMENT_TYPE * elementType ) ;
# if XML_GE == 1
# if XML_GE == 1
static enum XML_Error storeEntityValue ( XML_Parser parser , const ENCODING * enc ,
static enum XML_Error storeEntityValue ( XML_Parser parser , const ENCODING * enc ,
const char * start , const char * end ,
const char * start , const char * end ,
enum XML_Account account ) ;
enum XML_Account account ,
const char * * nextPtr ) ;
static enum XML_Error callStoreEntityValue ( XML_Parser parser ,
const ENCODING * enc ,
const char * start , const char * end ,
enum XML_Account account ) ;
# else
# else
static enum XML_Error storeSelfEntityValue ( XML_Parser parser , ENTITY * entity ) ;
static enum XML_Error storeSelfEntityValue ( XML_Parser parser , ENTITY * entity ) ;
# endif
# endif
@ -709,6 +724,10 @@ struct XML_ParserStruct {
const char * m_positionPtr ;
const char * m_positionPtr ;
OPEN_INTERNAL_ENTITY * m_openInternalEntities ;
OPEN_INTERNAL_ENTITY * m_openInternalEntities ;
OPEN_INTERNAL_ENTITY * m_freeInternalEntities ;
OPEN_INTERNAL_ENTITY * m_freeInternalEntities ;
OPEN_INTERNAL_ENTITY * m_openAttributeEntities ;
OPEN_INTERNAL_ENTITY * m_freeAttributeEntities ;
OPEN_INTERNAL_ENTITY * m_openValueEntities ;
OPEN_INTERNAL_ENTITY * m_freeValueEntities ;
XML_Bool m_defaultExpandInternalEntities ;
XML_Bool m_defaultExpandInternalEntities ;
int m_tagLevel ;
int m_tagLevel ;
ENTITY * m_declEntity ;
ENTITY * m_declEntity ;
@ -756,6 +775,7 @@ struct XML_ParserStruct {
ACCOUNTING m_accounting ;
ACCOUNTING m_accounting ;
ENTITY_STATS m_entity_stats ;
ENTITY_STATS m_entity_stats ;
# endif
# endif
XML_Bool m_reenter ;
} ;
} ;
# define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
# define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
@ -1028,7 +1048,29 @@ callProcessor(XML_Parser parser, const char *start, const char *end,
# if defined(XML_TESTING)
# if defined(XML_TESTING)
g_bytesScanned + = ( unsigned ) have_now ;
g_bytesScanned + = ( unsigned ) have_now ;
# endif
# endif
const enum XML_Error ret = parser - > m_processor ( parser , start , end , endPtr ) ;
// Run in a loop to eliminate dangerous recursion depths
enum XML_Error ret ;
* endPtr = start ;
while ( 1 ) {
// Use endPtr as the new start in each iteration, since it will
// be set to the next start point by m_processor.
ret = parser - > m_processor ( parser , * endPtr , end , endPtr ) ;
// Make parsing status (and in particular XML_SUSPENDED) take
// precedence over re-enter flag when they disagree
if ( parser - > m_parsingStatus . parsing ! = XML_PARSING ) {
parser - > m_reenter = XML_FALSE ;
}
if ( ! parser - > m_reenter ) {
break ;
}
parser - > m_reenter = XML_FALSE ;
if ( ret ! = XML_ERROR_NONE )
return ret ;
}
if ( ret = = XML_ERROR_NONE ) {
if ( ret = = XML_ERROR_NONE ) {
// if we consumed nothing, remember what we had on this parse attempt.
// if we consumed nothing, remember what we had on this parse attempt.
if ( * endPtr = = start ) {
if ( * endPtr = = start ) {
@ -1139,6 +1181,8 @@ parserCreate(const XML_Char *encodingName,
parser - > m_freeBindingList = NULL ;
parser - > m_freeBindingList = NULL ;
parser - > m_freeTagList = NULL ;
parser - > m_freeTagList = NULL ;
parser - > m_freeInternalEntities = NULL ;
parser - > m_freeInternalEntities = NULL ;
parser - > m_freeAttributeEntities = NULL ;
parser - > m_freeValueEntities = NULL ;
parser - > m_groupSize = 0 ;
parser - > m_groupSize = 0 ;
parser - > m_groupConnector = NULL ;
parser - > m_groupConnector = NULL ;
@ -1241,6 +1285,8 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
parser - > m_eventEndPtr = NULL ;
parser - > m_eventEndPtr = NULL ;
parser - > m_positionPtr = NULL ;
parser - > m_positionPtr = NULL ;
parser - > m_openInternalEntities = NULL ;
parser - > m_openInternalEntities = NULL ;
parser - > m_openAttributeEntities = NULL ;
parser - > m_openValueEntities = NULL ;
parser - > m_defaultExpandInternalEntities = XML_TRUE ;
parser - > m_defaultExpandInternalEntities = XML_TRUE ;
parser - > m_tagLevel = 0 ;
parser - > m_tagLevel = 0 ;
parser - > m_tagStack = NULL ;
parser - > m_tagStack = NULL ;
@ -1251,6 +1297,8 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
parser - > m_unknownEncodingData = NULL ;
parser - > m_unknownEncodingData = NULL ;
parser - > m_parentParser = NULL ;
parser - > m_parentParser = NULL ;
parser - > m_parsingStatus . parsing = XML_INITIALIZED ;
parser - > m_parsingStatus . parsing = XML_INITIALIZED ;
// Reentry can only be triggered inside m_processor calls
parser - > m_reenter = XML_FALSE ;
# ifdef XML_DTD
# ifdef XML_DTD
parser - > m_isParamEntity = XML_FALSE ;
parser - > m_isParamEntity = XML_FALSE ;
parser - > m_useForeignDTD = XML_FALSE ;
parser - > m_useForeignDTD = XML_FALSE ;
@ -1310,6 +1358,24 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
openEntity - > next = parser - > m_freeInternalEntities ;
openEntity - > next = parser - > m_freeInternalEntities ;
parser - > m_freeInternalEntities = openEntity ;
parser - > m_freeInternalEntities = openEntity ;
}
}
/* move m_openAttributeEntities to m_freeAttributeEntities (i.e. same task but
* for attributes ) */
openEntityList = parser - > m_openAttributeEntities ;
while ( openEntityList ) {
OPEN_INTERNAL_ENTITY * openEntity = openEntityList ;
openEntityList = openEntity - > next ;
openEntity - > next = parser - > m_freeAttributeEntities ;
parser - > m_freeAttributeEntities = openEntity ;
}
/* move m_openValueEntities to m_freeValueEntities (i.e. same task but
* for value entities ) */
openEntityList = parser - > m_openValueEntities ;
while ( openEntityList ) {
OPEN_INTERNAL_ENTITY * openEntity = openEntityList ;
openEntityList = openEntity - > next ;
openEntity - > next = parser - > m_freeValueEntities ;
parser - > m_freeValueEntities = openEntity ;
}
moveToFreeBindingList ( parser , parser - > m_inheritedBindings ) ;
moveToFreeBindingList ( parser , parser - > m_inheritedBindings ) ;
FREE ( parser , parser - > m_unknownEncodingMem ) ;
FREE ( parser , parser - > m_unknownEncodingMem ) ;
if ( parser - > m_unknownEncodingRelease )
if ( parser - > m_unknownEncodingRelease )
@ -1323,6 +1389,19 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
return XML_TRUE ;
return XML_TRUE ;
}
}
static XML_Bool
parserBusy ( XML_Parser parser ) {
switch ( parser - > m_parsingStatus . parsing ) {
case XML_PARSING :
case XML_SUSPENDED :
return XML_TRUE ;
case XML_INITIALIZED :
case XML_FINISHED :
default :
return XML_FALSE ;
}
}
enum XML_Status XMLCALL
enum XML_Status XMLCALL
XML_SetEncoding ( XML_Parser parser , const XML_Char * encodingName ) {
XML_SetEncoding ( XML_Parser parser , const XML_Char * encodingName ) {
if ( parser = = NULL )
if ( parser = = NULL )
@ -1331,8 +1410,7 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
XXX There ' s no way for the caller to determine which of the
XXX There ' s no way for the caller to determine which of the
XXX possible error cases caused the XML_STATUS_ERROR return .
XXX possible error cases caused the XML_STATUS_ERROR return .
*/
*/
if ( parser - > m_parsingStatus . parsing = = XML_PARSING
if ( parserBusy ( parser ) )
| | parser - > m_parsingStatus . parsing = = XML_SUSPENDED )
return XML_STATUS_ERROR ;
return XML_STATUS_ERROR ;
/* Get rid of any previous encoding name */
/* Get rid of any previous encoding name */
@ -1569,7 +1647,34 @@ XML_ParserFree(XML_Parser parser) {
entityList = entityList - > next ;
entityList = entityList - > next ;
FREE ( parser , openEntity ) ;
FREE ( parser , openEntity ) ;
}
}
/* free m_openAttributeEntities and m_freeAttributeEntities */
entityList = parser - > m_openAttributeEntities ;
for ( ; ; ) {
OPEN_INTERNAL_ENTITY * openEntity ;
if ( entityList = = NULL ) {
if ( parser - > m_freeAttributeEntities = = NULL )
break ;
entityList = parser - > m_freeAttributeEntities ;
parser - > m_freeAttributeEntities = NULL ;
}
openEntity = entityList ;
entityList = entityList - > next ;
FREE ( parser , openEntity ) ;
}
/* free m_openValueEntities and m_freeValueEntities */
entityList = parser - > m_openValueEntities ;
for ( ; ; ) {
OPEN_INTERNAL_ENTITY * openEntity ;
if ( entityList = = NULL ) {
if ( parser - > m_freeValueEntities = = NULL )
break ;
entityList = parser - > m_freeValueEntities ;
parser - > m_freeValueEntities = NULL ;
}
openEntity = entityList ;
entityList = entityList - > next ;
FREE ( parser , openEntity ) ;
}
destroyBindings ( parser - > m_freeBindingList , parser ) ;
destroyBindings ( parser - > m_freeBindingList , parser ) ;
destroyBindings ( parser - > m_inheritedBindings , parser ) ;
destroyBindings ( parser - > m_inheritedBindings , parser ) ;
poolDestroy ( & parser - > m_tempPool ) ;
poolDestroy ( & parser - > m_tempPool ) ;
@ -1611,8 +1716,7 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
return XML_ERROR_INVALID_ARGUMENT ;
return XML_ERROR_INVALID_ARGUMENT ;
# ifdef XML_DTD
# ifdef XML_DTD
/* block after XML_Parse()/XML_ParseBuffer() has been called */
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if ( parser - > m_parsingStatus . parsing = = XML_PARSING
if ( parserBusy ( parser ) )
| | parser - > m_parsingStatus . parsing = = XML_SUSPENDED )
return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING ;
return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING ;
parser - > m_useForeignDTD = useDTD ;
parser - > m_useForeignDTD = useDTD ;
return XML_ERROR_NONE ;
return XML_ERROR_NONE ;
@ -1627,8 +1731,7 @@ XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
if ( parser = = NULL )
if ( parser = = NULL )
return ;
return ;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if ( parser - > m_parsingStatus . parsing = = XML_PARSING
if ( parserBusy ( parser ) )
| | parser - > m_parsingStatus . parsing = = XML_SUSPENDED )
return ;
return ;
parser - > m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE ;
parser - > m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE ;
}
}
@ -1897,8 +2000,7 @@ XML_SetParamEntityParsing(XML_Parser parser,
if ( parser = = NULL )
if ( parser = = NULL )
return 0 ;
return 0 ;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if ( parser - > m_parsingStatus . parsing = = XML_PARSING
if ( parserBusy ( parser ) )
| | parser - > m_parsingStatus . parsing = = XML_SUSPENDED )
return 0 ;
return 0 ;
# ifdef XML_DTD
# ifdef XML_DTD
parser - > m_paramEntityParsing = peParsing ;
parser - > m_paramEntityParsing = peParsing ;
@ -1915,8 +2017,7 @@ XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
if ( parser - > m_parentParser )
if ( parser - > m_parentParser )
return XML_SetHashSalt ( parser - > m_parentParser , hash_salt ) ;
return XML_SetHashSalt ( parser - > m_parentParser , hash_salt ) ;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if ( parser - > m_parsingStatus . parsing = = XML_PARSING
if ( parserBusy ( parser ) )
| | parser - > m_parsingStatus . parsing = = XML_SUSPENDED )
return 0 ;
return 0 ;
parser - > m_hash_secret_salt = hash_salt ;
parser - > m_hash_secret_salt = hash_salt ;
return 1 ;
return 1 ;
@ -2230,6 +2331,11 @@ XML_GetBuffer(XML_Parser parser, int len) {
return parser - > m_bufferEnd ;
return parser - > m_bufferEnd ;
}
}
static void
triggerReenter ( XML_Parser parser ) {
parser - > m_reenter = XML_TRUE ;
}
enum XML_Status XMLCALL
enum XML_Status XMLCALL
XML_StopParser ( XML_Parser parser , XML_Bool resumable ) {
XML_StopParser ( XML_Parser parser , XML_Bool resumable ) {
if ( parser = = NULL )
if ( parser = = NULL )
@ -2704,8 +2810,9 @@ static enum XML_Error PTRCALL
contentProcessor ( XML_Parser parser , const char * start , const char * end ,
contentProcessor ( XML_Parser parser , const char * start , const char * end ,
const char * * endPtr ) {
const char * * endPtr ) {
enum XML_Error result = doContent (
enum XML_Error result = doContent (
parser , 0 , parser - > m_encoding , start , end , endPtr ,
parser , parser - > m_parentParser ? 1 : 0 , parser - > m_encoding , start , end ,
( XML_Bool ) ! parser - > m_parsingStatus . finalBuffer , XML_ACCOUNT_DIRECT ) ;
endPtr , ( XML_Bool ) ! parser - > m_parsingStatus . finalBuffer ,
XML_ACCOUNT_DIRECT ) ;
if ( result = = XML_ERROR_NONE ) {
if ( result = = XML_ERROR_NONE ) {
if ( ! storeRawNames ( parser ) )
if ( ! storeRawNames ( parser ) )
return XML_ERROR_NO_MEMORY ;
return XML_ERROR_NO_MEMORY ;
@ -2793,6 +2900,11 @@ externalEntityInitProcessor3(XML_Parser parser, const char *start,
return XML_ERROR_NONE ;
return XML_ERROR_NONE ;
case XML_FINISHED :
case XML_FINISHED :
return XML_ERROR_ABORTED ;
return XML_ERROR_ABORTED ;
case XML_PARSING :
if ( parser - > m_reenter ) {
return XML_ERROR_UNEXPECTED_STATE ; // LCOV_EXCL_LINE
}
/* Fall through */
default :
default :
start = next ;
start = next ;
}
}
@ -2966,7 +3078,7 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
reportDefault ( parser , enc , s , next ) ;
reportDefault ( parser , enc , s , next ) ;
break ;
break ;
}
}
result = process Internal Entity( parser , entity , XML_FALSE ) ;
result = process Entity( parser , entity , XML_FALSE , ENTITY_INTERNAL ) ;
if ( result ! = XML_ERROR_NONE )
if ( result ! = XML_ERROR_NONE )
return result ;
return result ;
} else if ( parser - > m_externalEntityRefHandler ) {
} else if ( parser - > m_externalEntityRefHandler ) {
@ -3092,7 +3204,9 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
}
}
if ( ( parser - > m_tagLevel = = 0 )
if ( ( parser - > m_tagLevel = = 0 )
& & ( parser - > m_parsingStatus . parsing ! = XML_FINISHED ) ) {
& & ( parser - > m_parsingStatus . parsing ! = XML_FINISHED ) ) {
if ( parser - > m_parsingStatus . parsing = = XML_SUSPENDED )
if ( parser - > m_parsingStatus . parsing = = XML_SUSPENDED
| | ( parser - > m_parsingStatus . parsing = = XML_PARSING
& & parser - > m_reenter ) )
parser - > m_processor = epilogProcessor ;
parser - > m_processor = epilogProcessor ;
else
else
return epilogProcessor ( parser , next , end , nextPtr ) ;
return epilogProcessor ( parser , next , end , nextPtr ) ;
@ -3153,7 +3267,9 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
}
}
if ( ( parser - > m_tagLevel = = 0 )
if ( ( parser - > m_tagLevel = = 0 )
& & ( parser - > m_parsingStatus . parsing ! = XML_FINISHED ) ) {
& & ( parser - > m_parsingStatus . parsing ! = XML_FINISHED ) ) {
if ( parser - > m_parsingStatus . parsing = = XML_SUSPENDED )
if ( parser - > m_parsingStatus . parsing = = XML_SUSPENDED
| | ( parser - > m_parsingStatus . parsing = = XML_PARSING
& & parser - > m_reenter ) )
parser - > m_processor = epilogProcessor ;
parser - > m_processor = epilogProcessor ;
else
else
return epilogProcessor ( parser , next , end , nextPtr ) ;
return epilogProcessor ( parser , next , end , nextPtr ) ;
@ -3293,6 +3409,12 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
return XML_ERROR_NONE ;
return XML_ERROR_NONE ;
case XML_FINISHED :
case XML_FINISHED :
return XML_ERROR_ABORTED ;
return XML_ERROR_ABORTED ;
case XML_PARSING :
if ( parser - > m_reenter ) {
* nextPtr = next ;
return XML_ERROR_NONE ;
}
/* Fall through */
default : ;
default : ;
}
}
}
}
@ -4217,6 +4339,11 @@ doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
return XML_ERROR_NONE ;
return XML_ERROR_NONE ;
case XML_FINISHED :
case XML_FINISHED :
return XML_ERROR_ABORTED ;
return XML_ERROR_ABORTED ;
case XML_PARSING :
if ( parser - > m_reenter ) {
return XML_ERROR_UNEXPECTED_STATE ; // LCOV_EXCL_LINE
}
/* Fall through */
default : ;
default : ;
}
}
}
}
@ -4549,7 +4676,7 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
}
}
/* found end of entity value - can store it now */
/* found end of entity value - can store it now */
return storeEntityValue ( parser , parser - > m_encoding , s , end ,
return storeEntityValue ( parser , parser - > m_encoding , s , end ,
XML_ACCOUNT_DIRECT );
XML_ACCOUNT_DIRECT , NULL );
} else if ( tok = = XML_TOK_XML_DECL ) {
} else if ( tok = = XML_TOK_XML_DECL ) {
enum XML_Error result ;
enum XML_Error result ;
result = processXmlDecl ( parser , 0 , start , next ) ;
result = processXmlDecl ( parser , 0 , start , next ) ;
@ -4676,7 +4803,7 @@ entityValueProcessor(XML_Parser parser, const char *s, const char *end,
break ;
break ;
}
}
/* found end of entity value - can store it now */
/* found end of entity value - can store it now */
return storeEntityValue ( parser , enc , s , end , XML_ACCOUNT_DIRECT );
return storeEntityValue ( parser , enc , s , end , XML_ACCOUNT_DIRECT , NULL );
}
}
start = next ;
start = next ;
}
}
@ -5119,9 +5246,9 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
# if XML_GE == 1
# if XML_GE == 1
// This will store the given replacement text in
// This will store the given replacement text in
// parser->m_declEntity->textPtr.
// parser->m_declEntity->textPtr.
enum XML_Error result
enum XML_Error result = callStoreEntityValue (
= storeEntityValue ( parser , enc , s + enc - > minBytesPerChar ,
parser , enc , s + enc - > minBytesPerChar , next - enc - > minBytesPerChar ,
next - enc - > minBytesPerChar , XML_ACCOUNT_NONE ) ;
XML_ACCOUNT_NONE ) ;
if ( parser - > m_declEntity ) {
if ( parser - > m_declEntity ) {
parser - > m_declEntity - > textPtr = poolStart ( & dtd - > entityValuePool ) ;
parser - > m_declEntity - > textPtr = poolStart ( & dtd - > entityValuePool ) ;
parser - > m_declEntity - > textLen
parser - > m_declEntity - > textLen
@ -5546,7 +5673,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
enum XML_Error result ;
enum XML_Error result ;
XML_Bool betweenDecl
XML_Bool betweenDecl
= ( role = = XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE ) ;
= ( role = = XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE ) ;
result = process Internal Entity( parser , entity , betweenDecl ) ;
result = process Entity( parser , entity , betweenDecl , ENTITY_INTERNAL ) ;
if ( result ! = XML_ERROR_NONE )
if ( result ! = XML_ERROR_NONE )
return result ;
return result ;
handleDefault = XML_FALSE ;
handleDefault = XML_FALSE ;
@ -5751,6 +5878,12 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
return XML_ERROR_NONE ;
return XML_ERROR_NONE ;
case XML_FINISHED :
case XML_FINISHED :
return XML_ERROR_ABORTED ;
return XML_ERROR_ABORTED ;
case XML_PARSING :
if ( parser - > m_reenter ) {
* nextPtr = next ;
return XML_ERROR_NONE ;
}
/* Fall through */
default :
default :
s = next ;
s = next ;
tok = XmlPrologTok ( enc , s , end , & next ) ;
tok = XmlPrologTok ( enc , s , end , & next ) ;
@ -5825,21 +5958,49 @@ epilogProcessor(XML_Parser parser, const char *s, const char *end,
return XML_ERROR_NONE ;
return XML_ERROR_NONE ;
case XML_FINISHED :
case XML_FINISHED :
return XML_ERROR_ABORTED ;
return XML_ERROR_ABORTED ;
case XML_PARSING :
if ( parser - > m_reenter ) {
return XML_ERROR_UNEXPECTED_STATE ; // LCOV_EXCL_LINE
}
/* Fall through */
default : ;
default : ;
}
}
}
}
}
}
static enum XML_Error
static enum XML_Error
processInternalEntity ( XML_Parser parser , ENTITY * entity , XML_Bool betweenDecl ) {
processEntity ( XML_Parser parser , ENTITY * entity , XML_Bool betweenDecl ,
const char * textStart , * textEnd ;
enum EntityType type ) {
const char * next ;
OPEN_INTERNAL_ENTITY * openEntity , * * openEntityList , * * freeEntityList ;
enum XML_Error result ;
switch ( type ) {
OPEN_INTERNAL_ENTITY * openEntity ;
case ENTITY_INTERNAL :
parser - > m_processor = internalEntityProcessor ;
openEntityList = & parser - > m_openInternalEntities ;
freeEntityList = & parser - > m_freeInternalEntities ;
break ;
case ENTITY_ATTRIBUTE :
openEntityList = & parser - > m_openAttributeEntities ;
freeEntityList = & parser - > m_freeAttributeEntities ;
break ;
case ENTITY_VALUE :
openEntityList = & parser - > m_openValueEntities ;
freeEntityList = & parser - > m_freeValueEntities ;
break ;
/* default case serves merely as a safety net in case of a
* wrong entityType . Therefore we exclude the following lines
* from the test coverage .
*
* LCOV_EXCL_START
*/
default :
// Should not reach here
assert ( 0 ) ;
/* LCOV_EXCL_STOP */
}
if ( parser - > m_freeInternalEntities ) {
if ( * freeEntityList ) {
openEntity = parser - > m_freeInternalEntities ;
openEntity = * freeEntityList ;
parser - > m_freeInternalEntities = openEntity - > next ;
* freeEntityList = openEntity - > next ;
} else {
} else {
openEntity
openEntity
= ( OPEN_INTERNAL_ENTITY * ) MALLOC ( parser , sizeof ( OPEN_INTERNAL_ENTITY ) ) ;
= ( OPEN_INTERNAL_ENTITY * ) MALLOC ( parser , sizeof ( OPEN_INTERNAL_ENTITY ) ) ;
@ -5847,55 +6008,34 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
return XML_ERROR_NO_MEMORY ;
return XML_ERROR_NO_MEMORY ;
}
}
entity - > open = XML_TRUE ;
entity - > open = XML_TRUE ;
entity - > hasMore = XML_TRUE ;
# if XML_GE == 1
# if XML_GE == 1
entityTrackingOnOpen ( parser , entity , __LINE__ ) ;
entityTrackingOnOpen ( parser , entity , __LINE__ ) ;
# endif
# endif
entity - > processed = 0 ;
entity - > processed = 0 ;
openEntity - > next = parser - > m_openInternalEntities ;
openEntity - > next = * openEntityList ;
parser - > m_openInternalEntities = openEntity ;
* openEntityList = openEntity ;
openEntity - > entity = entity ;
openEntity - > entity = entity ;
openEntity - > type = type ;
openEntity - > startTagLevel = parser - > m_tagLevel ;
openEntity - > startTagLevel = parser - > m_tagLevel ;
openEntity - > betweenDecl = betweenDecl ;
openEntity - > betweenDecl = betweenDecl ;
openEntity - > internalEventPtr = NULL ;
openEntity - > internalEventPtr = NULL ;
openEntity - > internalEventEndPtr = NULL ;
openEntity - > internalEventEndPtr = NULL ;
textStart = ( const char * ) entity - > textPtr ;
textEnd = ( const char * ) ( entity - > textPtr + entity - > textLen ) ;
/* Set a safe default value in case 'next' does not get set */
next = textStart ;
if ( entity - > is_param ) {
int tok
= XmlPrologTok ( parser - > m_internalEncoding , textStart , textEnd , & next ) ;
result = doProlog ( parser , parser - > m_internalEncoding , textStart , textEnd ,
tok , next , & next , XML_FALSE , XML_FALSE ,
XML_ACCOUNT_ENTITY_EXPANSION ) ;
} else {
result = doContent ( parser , parser - > m_tagLevel , parser - > m_internalEncoding ,
textStart , textEnd , & next , XML_FALSE ,
XML_ACCOUNT_ENTITY_EXPANSION ) ;
}
if ( result = = XML_ERROR_NONE ) {
// Only internal entities make use of the reenter flag
if ( textEnd ! = next & & parser - > m_parsingStatus . parsing = = XML_SUSPENDED ) {
// therefore no need to set it for other entity types
entity - > processed = ( int ) ( next - textStart ) ;
if ( type = = ENTITY_INTERNAL ) {
parser - > m_processor = internalEntityProcessor ;
triggerReenter ( parser ) ;
} else if ( parser - > m_openInternalEntities - > entity = = entity ) {
# if XML_GE == 1
entityTrackingOnClose ( parser , entity , __LINE__ ) ;
# endif /* XML_GE == 1 */
entity - > open = XML_FALSE ;
parser - > m_openInternalEntities = openEntity - > next ;
/* put openEntity back in list of free instances */
openEntity - > next = parser - > m_freeInternalEntities ;
parser - > m_freeInternalEntities = openEntity ;
}
}
}
return result ;
return XML_ERROR_NONE ;
}
}
static enum XML_Error PTRCALL
static enum XML_Error PTRCALL
internalEntityProcessor ( XML_Parser parser , const char * s , const char * end ,
internalEntityProcessor ( XML_Parser parser , const char * s , const char * end ,
const char * * nextPtr ) {
const char * * nextPtr ) {
UNUSED_P ( s ) ;
UNUSED_P ( end ) ;
UNUSED_P ( nextPtr ) ;
ENTITY * entity ;
ENTITY * entity ;
const char * textStart , * textEnd ;
const char * textStart , * textEnd ;
const char * next ;
const char * next ;
@ -5905,68 +6045,67 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
return XML_ERROR_UNEXPECTED_STATE ;
return XML_ERROR_UNEXPECTED_STATE ;
entity = openEntity - > entity ;
entity = openEntity - > entity ;
textStart = ( ( const char * ) entity - > textPtr ) + entity - > processed ;
textEnd = ( const char * ) ( entity - > textPtr + entity - > textLen ) ;
/* Set a safe default value in case 'next' does not get set */
next = textStart ;
if ( entity - > is_param ) {
int tok
= XmlPrologTok ( parser - > m_internalEncoding , textStart , textEnd , & next ) ;
result = doProlog ( parser , parser - > m_internalEncoding , textStart , textEnd ,
tok , next , & next , XML_FALSE , XML_TRUE ,
XML_ACCOUNT_ENTITY_EXPANSION ) ;
} else {
result = doContent ( parser , openEntity - > startTagLevel ,
parser - > m_internalEncoding , textStart , textEnd , & next ,
XML_FALSE , XML_ACCOUNT_ENTITY_EXPANSION ) ;
}
if ( result ! = XML_ERROR_NONE )
// This will return early
return result ;
if ( entity - > hasMore ) {
textStart = ( ( const char * ) entity - > textPtr ) + entity - > processed ;
textEnd = ( const char * ) ( entity - > textPtr + entity - > textLen ) ;
/* Set a safe default value in case 'next' does not get set */
next = textStart ;
if ( entity - > is_param ) {
int tok
= XmlPrologTok ( parser - > m_internalEncoding , textStart , textEnd , & next ) ;
result = doProlog ( parser , parser - > m_internalEncoding , textStart , textEnd ,
tok , next , & next , XML_FALSE , XML_FALSE ,
XML_ACCOUNT_ENTITY_EXPANSION ) ;
} else {
result = doContent ( parser , openEntity - > startTagLevel ,
parser - > m_internalEncoding , textStart , textEnd , & next ,
XML_FALSE , XML_ACCOUNT_ENTITY_EXPANSION ) ;
}
if ( result ! = XML_ERROR_NONE )
return result ;
// Check if entity is complete, if not, mark down how much of it is
// processed
if ( textEnd ! = next
& & ( parser - > m_parsingStatus . parsing = = XML_SUSPENDED
| | ( parser - > m_parsingStatus . parsing = = XML_PARSING
& & parser - > m_reenter ) ) ) {
entity - > processed = ( int ) ( next - ( const char * ) entity - > textPtr ) ;
return result ;
}
if ( textEnd ! = next & & parser - > m_parsingStatus . parsing = = XML_SUSPENDED ) {
// Entity is complete. We cannot close it here since we need to first
entity - > processed = ( int ) ( next - ( const char * ) entity - > textPtr ) ;
// process its possible inner entities (which are added to the
// m_openInternalEntities during doProlog or doContent calls above)
entity - > hasMore = XML_FALSE ;
triggerReenter ( parser ) ;
return result ;
return result ;
}
} // End of entity processing, "if" block will return here
// Remove fully processed openEntity from open entity list.
# if XML_GE == 1
# if XML_GE == 1
entityTrackingOnClose ( parser , entity , __LINE__ ) ;
entityTrackingOnClose ( parser , entity , __LINE__ ) ;
# endif
# endif
// openEntity is m_openInternalEntities' head, as we set it at the start of
// this function and we skipped doProlog and doContent calls with hasMore set
// to false. This means we can directly remove the head of
// m_openInternalEntities
assert ( parser - > m_openInternalEntities = = openEntity ) ;
entity - > open = XML_FALSE ;
entity - > open = XML_FALSE ;
parser - > m_openInternalEntities = openEntity - > next ;
parser - > m_openInternalEntities = parser - > m_openInternalEntities - > next ;
/* put openEntity back in list of free instances */
/* put openEntity back in list of free instances */
openEntity - > next = parser - > m_freeInternalEntities ;
openEntity - > next = parser - > m_freeInternalEntities ;
parser - > m_freeInternalEntities = openEntity ;
parser - > m_freeInternalEntities = openEntity ;
// If there are more open entities we want to stop right here and have the
if ( parser - > m_openInternalEntities = = NULL ) {
// upcoming call to XML_ResumeParser continue with entity content, or it would
parser - > m_processor = entity - > is_param ? prologProcessor : contentProcessor ;
// be ignored altogether.
if ( parser - > m_openInternalEntities ! = NULL
& & parser - > m_parsingStatus . parsing = = XML_SUSPENDED ) {
return XML_ERROR_NONE ;
}
if ( entity - > is_param ) {
int tok ;
parser - > m_processor = prologProcessor ;
tok = XmlPrologTok ( parser - > m_encoding , s , end , & next ) ;
return doProlog ( parser , parser - > m_encoding , s , end , tok , next , nextPtr ,
( XML_Bool ) ! parser - > m_parsingStatus . finalBuffer , XML_TRUE ,
XML_ACCOUNT_DIRECT ) ;
} else {
parser - > m_processor = contentProcessor ;
/* see externalEntityContentProcessor vs contentProcessor */
result = doContent ( parser , parser - > m_parentParser ? 1 : 0 ,
parser - > m_encoding , s , end , nextPtr ,
( XML_Bool ) ! parser - > m_parsingStatus . finalBuffer ,
XML_ACCOUNT_DIRECT ) ;
if ( result = = XML_ERROR_NONE ) {
if ( ! storeRawNames ( parser ) )
return XML_ERROR_NO_MEMORY ;
}
return result ;
}
}
triggerReenter ( parser ) ;
return XML_ERROR_NONE ;
}
}
static enum XML_Error PTRCALL
static enum XML_Error PTRCALL
@ -5982,8 +6121,70 @@ static enum XML_Error
storeAttributeValue ( XML_Parser parser , const ENCODING * enc , XML_Bool isCdata ,
storeAttributeValue ( XML_Parser parser , const ENCODING * enc , XML_Bool isCdata ,
const char * ptr , const char * end , STRING_POOL * pool ,
const char * ptr , const char * end , STRING_POOL * pool ,
enum XML_Account account ) {
enum XML_Account account ) {
enum XML_Error result
const char * next = ptr ;
= appendAttributeValue ( parser , enc , isCdata , ptr , end , pool , account ) ;
enum XML_Error result = XML_ERROR_NONE ;
while ( 1 ) {
if ( ! parser - > m_openAttributeEntities ) {
result = appendAttributeValue ( parser , enc , isCdata , next , end , pool ,
account , & next ) ;
} else {
OPEN_INTERNAL_ENTITY * const openEntity = parser - > m_openAttributeEntities ;
if ( ! openEntity )
return XML_ERROR_UNEXPECTED_STATE ;
ENTITY * const entity = openEntity - > entity ;
const char * const textStart
= ( ( const char * ) entity - > textPtr ) + entity - > processed ;
const char * const textEnd
= ( const char * ) ( entity - > textPtr + entity - > textLen ) ;
/* Set a safe default value in case 'next' does not get set */
const char * nextInEntity = textStart ;
if ( entity - > hasMore ) {
result = appendAttributeValue (
parser , parser - > m_internalEncoding , isCdata , textStart , textEnd ,
pool , XML_ACCOUNT_ENTITY_EXPANSION , & nextInEntity ) ;
if ( result ! = XML_ERROR_NONE )
break ;
// Check if entity is complete, if not, mark down how much of it is
// processed. A XML_SUSPENDED check here is not required as
// appendAttributeValue will never suspend the parser.
if ( textEnd ! = nextInEntity ) {
entity - > processed
= ( int ) ( nextInEntity - ( const char * ) entity - > textPtr ) ;
continue ;
}
// Entity is complete. We cannot close it here since we need to first
// process its possible inner entities (which are added to the
// m_openAttributeEntities during appendAttributeValue)
entity - > hasMore = XML_FALSE ;
continue ;
} // End of entity processing, "if" block skips the rest
// Remove fully processed openEntity from open entity list.
# if XML_GE == 1
entityTrackingOnClose ( parser , entity , __LINE__ ) ;
# endif
// openEntity is m_openAttributeEntities' head, since we set it at the
// start of this function and because we skipped appendAttributeValue call
// with hasMore set to false. This means we can directly remove the head
// of m_openAttributeEntities
assert ( parser - > m_openAttributeEntities = = openEntity ) ;
entity - > open = XML_FALSE ;
parser - > m_openAttributeEntities = parser - > m_openAttributeEntities - > next ;
/* put openEntity back in list of free instances */
openEntity - > next = parser - > m_freeAttributeEntities ;
parser - > m_freeAttributeEntities = openEntity ;
}
// Break if an error occurred or there is nothing left to process
if ( result | | ( parser - > m_openAttributeEntities = = NULL & & end = = next ) ) {
break ;
}
}
if ( result )
if ( result )
return result ;
return result ;
if ( ! isCdata & & poolLength ( pool ) & & poolLastChar ( pool ) = = 0x20 )
if ( ! isCdata & & poolLength ( pool ) & & poolLastChar ( pool ) = = 0x20 )
@ -5996,7 +6197,7 @@ storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
static enum XML_Error
static enum XML_Error
appendAttributeValue ( XML_Parser parser , const ENCODING * enc , XML_Bool isCdata ,
appendAttributeValue ( XML_Parser parser , const ENCODING * enc , XML_Bool isCdata ,
const char * ptr , const char * end , STRING_POOL * pool ,
const char * ptr , const char * end , STRING_POOL * pool ,
enum XML_Account account ) {
enum XML_Account account , const char * * nextPtr ) {
DTD * const dtd = parser - > m_dtd ; /* save one level of indirection */
DTD * const dtd = parser - > m_dtd ; /* save one level of indirection */
# ifndef XML_DTD
# ifndef XML_DTD
UNUSED_P ( account ) ;
UNUSED_P ( account ) ;
@ -6014,6 +6215,9 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
# endif
# endif
switch ( tok ) {
switch ( tok ) {
case XML_TOK_NONE :
case XML_TOK_NONE :
if ( nextPtr ) {
* nextPtr = next ;
}
return XML_ERROR_NONE ;
return XML_ERROR_NONE ;
case XML_TOK_INVALID :
case XML_TOK_INVALID :
if ( enc = = parser - > m_encoding )
if ( enc = = parser - > m_encoding )
@ -6154,21 +6358,11 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF ;
return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF ;
} else {
} else {
enum XML_Error result ;
enum XML_Error result ;
const XML_Char * textEnd = entity - > textPtr + entity - > textLen ;
result = processEntity ( parser , entity , XML_FALSE , ENTITY_ATTRIBUTE ) ;
entity - > open = XML_TRUE ;
if ( ( result = = XML_ERROR_NONE ) & & ( nextPtr ! = NULL ) ) {
# if XML_GE == 1
* nextPtr = next ;
entityTrackingOnOpen ( parser , entity , __LINE__ ) ;
}
# endif
return result ;
result = appendAttributeValue ( parser , parser - > m_internalEncoding ,
isCdata , ( const char * ) entity - > textPtr ,
( const char * ) textEnd , pool ,
XML_ACCOUNT_ENTITY_EXPANSION ) ;
# if XML_GE == 1
entityTrackingOnClose ( parser , entity , __LINE__ ) ;
# endif
entity - > open = XML_FALSE ;
if ( result )
return result ;
}
}
} break ;
} break ;
default :
default :
@ -6197,7 +6391,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
static enum XML_Error
static enum XML_Error
storeEntityValue ( XML_Parser parser , const ENCODING * enc ,
storeEntityValue ( XML_Parser parser , const ENCODING * enc ,
const char * entityTextPtr , const char * entityTextEnd ,
const char * entityTextPtr , const char * entityTextEnd ,
enum XML_Account account ) {
enum XML_Account account , const char * * nextPtr ) {
DTD * const dtd = parser - > m_dtd ; /* save one level of indirection */
DTD * const dtd = parser - > m_dtd ; /* save one level of indirection */
STRING_POOL * pool = & ( dtd - > entityValuePool ) ;
STRING_POOL * pool = & ( dtd - > entityValuePool ) ;
enum XML_Error result = XML_ERROR_NONE ;
enum XML_Error result = XML_ERROR_NONE ;
@ -6215,8 +6409,9 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
return XML_ERROR_NO_MEMORY ;
return XML_ERROR_NO_MEMORY ;
}
}
const char * next ;
for ( ; ; ) {
for ( ; ; ) {
const char * next
next
= entityTextPtr ; /* XmlEntityValueTok doesn't always set the last arg */
= entityTextPtr ; /* XmlEntityValueTok doesn't always set the last arg */
int tok = XmlEntityValueTok ( enc , entityTextPtr , entityTextEnd , & next ) ;
int tok = XmlEntityValueTok ( enc , entityTextPtr , entityTextEnd , & next ) ;
@ -6278,16 +6473,8 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
} else
} else
dtd - > keepProcessing = dtd - > standalone ;
dtd - > keepProcessing = dtd - > standalone ;
} else {
} else {
entity - > open = XML_TRUE ;
result = processEntity ( parser , entity , XML_FALSE , ENTITY_VALUE ) ;
entityTrackingOnOpen ( parser , entity , __LINE__ ) ;
goto endEntityValue ;
result = storeEntityValue (
parser , parser - > m_internalEncoding , ( const char * ) entity - > textPtr ,
( const char * ) ( entity - > textPtr + entity - > textLen ) ,
XML_ACCOUNT_ENTITY_EXPANSION ) ;
entityTrackingOnClose ( parser , entity , __LINE__ ) ;
entity - > open = XML_FALSE ;
if ( result )
goto endEntityValue ;
}
}
break ;
break ;
}
}
@ -6375,6 +6562,81 @@ endEntityValue:
# ifdef XML_DTD
# ifdef XML_DTD
parser - > m_prologState . inEntityValue = oldInEntityValue ;
parser - > m_prologState . inEntityValue = oldInEntityValue ;
# endif /* XML_DTD */
# endif /* XML_DTD */
// If 'nextPtr' is given, it should be updated during the processing
if ( nextPtr ! = NULL ) {
* nextPtr = next ;
}
return result ;
}
static enum XML_Error
callStoreEntityValue ( XML_Parser parser , const ENCODING * enc ,
const char * entityTextPtr , const char * entityTextEnd ,
enum XML_Account account ) {
const char * next = entityTextPtr ;
enum XML_Error result = XML_ERROR_NONE ;
while ( 1 ) {
if ( ! parser - > m_openValueEntities ) {
result
= storeEntityValue ( parser , enc , next , entityTextEnd , account , & next ) ;
} else {
OPEN_INTERNAL_ENTITY * const openEntity = parser - > m_openValueEntities ;
if ( ! openEntity )
return XML_ERROR_UNEXPECTED_STATE ;
ENTITY * const entity = openEntity - > entity ;
const char * const textStart
= ( ( const char * ) entity - > textPtr ) + entity - > processed ;
const char * const textEnd
= ( const char * ) ( entity - > textPtr + entity - > textLen ) ;
/* Set a safe default value in case 'next' does not get set */
const char * nextInEntity = textStart ;
if ( entity - > hasMore ) {
result = storeEntityValue ( parser , parser - > m_internalEncoding , textStart ,
textEnd , XML_ACCOUNT_ENTITY_EXPANSION ,
& nextInEntity ) ;
if ( result ! = XML_ERROR_NONE )
break ;
// Check if entity is complete, if not, mark down how much of it is
// processed. A XML_SUSPENDED check here is not required as
// appendAttributeValue will never suspend the parser.
if ( textEnd ! = nextInEntity ) {
entity - > processed
= ( int ) ( nextInEntity - ( const char * ) entity - > textPtr ) ;
continue ;
}
// Entity is complete. We cannot close it here since we need to first
// process its possible inner entities (which are added to the
// m_openValueEntities during storeEntityValue)
entity - > hasMore = XML_FALSE ;
continue ;
} // End of entity processing, "if" block skips the rest
// Remove fully processed openEntity from open entity list.
# if XML_GE == 1
entityTrackingOnClose ( parser , entity , __LINE__ ) ;
# endif
// openEntity is m_openValueEntities' head, since we set it at the
// start of this function and because we skipped storeEntityValue call
// with hasMore set to false. This means we can directly remove the head
// of m_openValueEntities
assert ( parser - > m_openValueEntities = = openEntity ) ;
entity - > open = XML_FALSE ;
parser - > m_openValueEntities = parser - > m_openValueEntities - > next ;
/* put openEntity back in list of free instances */
openEntity - > next = parser - > m_freeValueEntities ;
parser - > m_freeValueEntities = openEntity ;
}
// Break if an error occurred or there is nothing left to process
if ( result
| | ( parser - > m_openValueEntities = = NULL & & entityTextEnd = = next ) ) {
break ;
}
}
return result ;
return result ;
}
}
@ -8542,11 +8804,13 @@ unsignedCharToPrintable(unsigned char c) {
return " \\ xFE " ;
return " \\ xFE " ;
case 255 :
case 255 :
return " \\ xFF " ;
return " \\ xFF " ;
// LCOV_EXCL_START
default :
default :
assert ( 0 ) ; /* never gets here */
assert ( 0 ) ; /* never gets here */
return " dead code " ;
return " dead code " ;
}
}
assert ( 0 ) ; /* never gets here */
assert ( 0 ) ; /* never gets here */
// LCOV_EXCL_STOP
}
}
# endif /* XML_GE == 1 */
# endif /* XML_GE == 1 */