expat/backport-008-CVE-2024-8176.patch

230 lines
8.7 KiB
Diff
Raw Normal View History

2025-03-29 17:01:17 +08:00
From 16a3b9d3566a95c4e502bfd008d05a0d015013ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Berkay=20Eren=20=C3=9Cr=C3=BCn?= <berkay.ueruen@siemens.com>
Date: Wed, 9 Oct 2024 15:51:05 +0200
Subject: [PATCH 1/3] Merge entity processors
Reference: https://github.com/libexpat/libexpat/pull/973/commits/16a3b9d3566a95c4e502bfd008d05a0d015013ac
Conflict: adapt epilogProcessor
---
lib/xmlparse.c | 135 +++++++++++++++++++------------------------------
1 file changed, 51 insertions(+), 84 deletions(-)
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
index 6c81713..9d8099e 100644
--- a/lib/xmlparse.c
+++ b/lib/xmlparse.c
@@ -389,6 +389,12 @@ typedef struct {
int *scaffIndex;
} DTD;
+enum EntityType {
+ ENTITY_INTERNAL,
+ ENTITY_ATTRIBUTE,
+ ENTITY_VALUE,
+};
+
typedef struct open_internal_entity {
const char *internalEventPtr;
const char *internalEventEndPtr;
@@ -396,6 +402,7 @@ typedef struct open_internal_entity {
ENTITY *entity;
int startTagLevel;
XML_Bool betweenDecl; /* WFC: PE Between Declarations */
+ enum EntityType type;
} OPEN_INTERNAL_ENTITY;
enum XML_Account {
@@ -455,14 +462,8 @@ static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
const char *next, const char **nextPtr,
XML_Bool haveMore, XML_Bool allowClosingDoctype,
enum XML_Account account);
-static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
- XML_Bool betweenDecl);
-static enum XML_Error processAttributeEntity(XML_Parser parser, ENTITY *entity,
- XML_Bool betweenDecl);
-#ifdef XML_DTD
-static enum XML_Error processValueEntity(XML_Parser parser, ENTITY *entity,
- XML_Bool betweenDecl);
-#endif /* XML_DTD */
+static enum XML_Error processEntity(XML_Parser parser, ENTITY *entity,
+ XML_Bool betweenDecl, enum EntityType type);
static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
const ENCODING *enc, const char *start,
const char *end, const char **endPtr,
@@ -3033,7 +3034,7 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
reportDefault(parser, enc, s, next);
break;
}
- result = processInternalEntity(parser, entity, XML_FALSE);
+ result = processEntity(parser, entity, XML_FALSE, ENTITY_INTERNAL);
if (result != XML_ERROR_NONE)
return result;
} else if (parser->m_externalEntityRefHandler) {
@@ -5627,7 +5628,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
enum XML_Error result;
XML_Bool betweenDecl
= (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
- result = processInternalEntity(parser, entity, betweenDecl);
+ result = processEntity(parser, entity, betweenDecl, ENTITY_INTERNAL);
if (result != XML_ERROR_NONE)
return result;
handleDefault = XML_FALSE;
@@ -5923,48 +5924,40 @@ epilogProcessor(XML_Parser parser, const char *s, const char *end,
}
}
-/* KEEP IN SYNC with processAttributeEntity */
static enum XML_Error
-processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
- OPEN_INTERNAL_ENTITY *openEntity;
-
- if (parser->m_freeInternalEntities) {
- openEntity = parser->m_freeInternalEntities;
- parser->m_freeInternalEntities = openEntity->next;
- } else {
- openEntity
- = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
- if (! openEntity)
- return XML_ERROR_NO_MEMORY;
+processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl,
+ enum EntityType type) {
+ OPEN_INTERNAL_ENTITY *openEntity, **openEntityList, **freeEntityList;
+ switch (type) {
+ 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 */
}
- entity->open = XML_TRUE;
-#if defined(XML_DTD) || XML_GE == 1
- entityTrackingOnOpen(parser, entity, __LINE__);
-#endif
- entity->processed = 0;
- parser->m_processor = internalEntityProcessor;
- openEntity->next = parser->m_openInternalEntities;
- parser->m_openInternalEntities = openEntity;
- openEntity->entity = entity;
- openEntity->startTagLevel = parser->m_tagLevel;
- openEntity->betweenDecl = betweenDecl;
- openEntity->internalEventPtr = NULL;
- openEntity->internalEventEndPtr = NULL;
-
- triggerReenter(parser);
- return XML_ERROR_NONE;
-}
-
-/* KEEP IN SYNC with processInternalEntity */
-static enum XML_Error
-processAttributeEntity(XML_Parser parser, ENTITY *entity,
- XML_Bool betweenDecl) {
- OPEN_INTERNAL_ENTITY *openEntity;
- if (parser->m_freeAttributeEntities) {
- openEntity = parser->m_freeAttributeEntities;
- parser->m_freeAttributeEntities = openEntity->next;
- } else {
+ if (*freeEntityList) {
+ openEntity = *freeEntityList;
+ *freeEntityList = openEntity->next;
+ } else {
openEntity
= (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
if (! openEntity)
@@ -5975,48 +5968,22 @@ processAttributeEntity(XML_Parser parser, ENTITY *entity,
entityTrackingOnOpen(parser, entity, __LINE__);
#endif
entity->processed = 0;
- openEntity->next = parser->m_openAttributeEntities;
- parser->m_openAttributeEntities = openEntity;
+ openEntity->next = *openEntityList;
+ *openEntityList = openEntity;
openEntity->entity = entity;
+ openEntity->type = type;
openEntity->startTagLevel = parser->m_tagLevel;
openEntity->betweenDecl = betweenDecl;
openEntity->internalEventPtr = NULL;
openEntity->internalEventEndPtr = NULL;
- return XML_ERROR_NONE;
-}
-
-/* KEEP IN SYNC with processInternalEntity */
-#ifdef XML_DTD
-static enum XML_Error
-processValueEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
- OPEN_INTERNAL_ENTITY *openEntity;
-
- if (parser->m_freeValueEntities) {
- openEntity = parser->m_freeValueEntities;
- parser->m_freeValueEntities = openEntity->next;
- } else {
- openEntity
- = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
- if (! openEntity)
- return XML_ERROR_NO_MEMORY;
+ // Only internal entities make use of the reenter flag
+ // therefore no need to set it for other entity types
+ if (type == ENTITY_INTERNAL) {
+ triggerReenter(parser);
}
- entity->open = XML_TRUE;
-# if XML_GE == 1
- entityTrackingOnOpen(parser, entity, __LINE__);
-# endif
- entity->processed = 0;
- openEntity->next = parser->m_openValueEntities;
- parser->m_openValueEntities = openEntity;
- openEntity->entity = entity;
- openEntity->startTagLevel = parser->m_tagLevel;
- openEntity->betweenDecl = betweenDecl;
- openEntity->internalEventPtr = NULL;
- openEntity->internalEventEndPtr = NULL;
-
return XML_ERROR_NONE;
}
-#endif /* XML_DTD */
static enum XML_Error PTRCALL
internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
@@ -6356,7 +6323,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
} else {
enum XML_Error result;
- result = processAttributeEntity(parser, entity, XML_FALSE);
+ result = processEntity(parser, entity, XML_FALSE, ENTITY_ATTRIBUTE);
if (nextPtr) {
*nextPtr = next;
}
@@ -6476,7 +6443,7 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
} else
dtd->keepProcessing = dtd->standalone;
} else {
- result = processValueEntity(parser, entity, XML_FALSE);
+ result = processEntity(parser, entity, XML_FALSE, ENTITY_VALUE);
goto endEntityValue;
}
break;
--
2.33.0