200 lines
9.0 KiB
Diff
200 lines
9.0 KiB
Diff
From 08ff7591ffe9519f627e246f841427c6f10edc2a Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Berkay=20Eren=20=C3=9Cr=C3=BCn?= <berkay.ueruen@siemens.com>
|
|
Date: Tue, 15 Oct 2024 11:37:09 +0200
|
|
Subject: [PATCH] Fix entity debug order
|
|
|
|
The fix for entity processing changes the order of opening and closing
|
|
of entities. The reason is the new iterative approach that closes
|
|
and removes entities as soon as they are fully processed, unlike
|
|
the recursive approach that, as a side effect of the recursion, waits
|
|
the inner entities before closing and removal.
|
|
|
|
This commit delays the removal and the call to entityTrackingOnClose
|
|
until the current entities inner entities are processed, which in turn
|
|
allows us to have the correct debug order again.
|
|
|
|
Reference: https://github.com/libexpat/libexpat/pull/973/commits/c20ce3aaa3a114e7d671d11625a63d75de904e31
|
|
Conflict: adapt internalEntityProcessor
|
|
---
|
|
lib/xmlparse.c | 121 ++++++++++++++++++++++++++-----------------------
|
|
1 file changed, 64 insertions(+), 57 deletions(-)
|
|
|
|
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
|
|
index 9dda309..325d5e7 100644
|
|
--- a/lib/xmlparse.c
|
|
+++ b/lib/xmlparse.c
|
|
@@ -6004,38 +6004,46 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
|
|
return XML_ERROR_UNEXPECTED_STATE;
|
|
|
|
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->open) {
|
|
+ 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;
|
|
|
|
#ifdef XML_DTD
|
|
- 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
|
|
+ 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 {
|
|
#endif /* XML_DTD */
|
|
- result = doContent(parser, openEntity->startTagLevel,
|
|
- parser->m_internalEncoding, textStart, textEnd, &next,
|
|
- XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
|
|
+ result = doContent(parser, openEntity->startTagLevel,
|
|
+ parser->m_internalEncoding, textStart, textEnd, &next,
|
|
+ XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
|
|
+ }
|
|
|
|
- if (result != XML_ERROR_NONE)
|
|
- return result;
|
|
- 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);
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ entity->open = XML_FALSE;
|
|
+ triggerReenter(parser);
|
|
return result;
|
|
}
|
|
|
|
#if defined(XML_DTD) || XML_GE == 1
|
|
entityTrackingOnClose(parser, entity, __LINE__);
|
|
#endif
|
|
- entity->open = XML_FALSE;
|
|
// Remove fully processed openEntity from open entity list. doContent call can
|
|
// add maximum one new entity to m_openInternalEntities since when a new
|
|
// entity is detected, parser will go into REENTER state and return. Therefore
|
|
@@ -6053,19 +6061,6 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
|
|
openEntity->next = parser->m_freeInternalEntities;
|
|
parser->m_freeInternalEntities = openEntity;
|
|
|
|
- // If the state is XML_SUSPENDED and there are more open entities we want to
|
|
- // stop right here and have the upcoming call to XML_ResumeParser continue
|
|
- // with entity content, or it would be ignored altogether.
|
|
- // If the state is XML_PARSING, m_reenter is set, and there are more open
|
|
- // entities, we want to return and reenter to internalEntityProcessor to
|
|
- // process the next entity in the list
|
|
- if (parser->m_openInternalEntities != NULL
|
|
- && (parser->m_parsingStatus.parsing == XML_SUSPENDED
|
|
- || (parser->m_parsingStatus.parsing == XML_PARSING
|
|
- && parser->m_reenter))) {
|
|
- return XML_ERROR_NONE;
|
|
- }
|
|
-
|
|
if (parser->m_openInternalEntities == NULL) {
|
|
parser->m_processor = entity->is_param ? prologProcessor : contentProcessor;
|
|
// internalEntityProcessor is called from callProcessor's while(1) loop,
|
|
@@ -6113,23 +6108,29 @@ storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
|
|
= (const char *)(entity->textPtr + entity->textLen);
|
|
/* Set a safe default value in case 'next' does not get set */
|
|
const char *nextInEntity = textStart;
|
|
- 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);
|
|
+ if (entity->open) {
|
|
+ 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->open = XML_FALSE;
|
|
+ triggerReenter(parser);
|
|
continue;
|
|
}
|
|
|
|
#if XML_GE == 1
|
|
entityTrackingOnClose(parser, entity, __LINE__);
|
|
#endif
|
|
- entity->open = XML_FALSE;
|
|
// Remove fully processed openEntity from open entity list.
|
|
// appendAttributeValue call can add maximum one new entity to
|
|
// m_openAttributeEntities since when a new entity is detected, parser
|
|
@@ -6566,23 +6567,29 @@ callStoreEntityValue(XML_Parser parser, const ENCODING *enc,
|
|
= (const char *)(entity->textPtr + entity->textLen);
|
|
/* Set a safe default value in case 'next' does not get set */
|
|
const char *nextInEntity = textStart;
|
|
- 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);
|
|
+ if (entity->open) {
|
|
+ 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->open = XML_FALSE;
|
|
+ triggerReenter(parser);
|
|
continue;
|
|
}
|
|
|
|
# if XML_GE == 1
|
|
entityTrackingOnClose(parser, entity, __LINE__);
|
|
# endif
|
|
- entity->open = XML_FALSE;
|
|
// Remove fully processed openEntity from open entity list.
|
|
// appendAttributeValue call can add maximum one new entity to
|
|
// m_openValueEntities since when a new entity is detected, parser
|
|
--
|
|
2.33.0
|
|
|