File expat-CVE-2023-52425-backport-parser-changes.patch of Package expat.35320
From: Simon Lees <sflees@suse.de>
Date: Fri, Mar 1 10:42:13
Subject: CVE-2023-52425 Additional parser fixes
In order for the backport of CVE-2023-52425 to pass the testsuite
some additional changes needed to be backported to xmlparse.c
===
Index: expat-2.4.4/lib/xmlparse.c
===================================================================
--- expat-2.4.4.orig/lib/xmlparse.c
+++ expat-2.4.4/lib/xmlparse.c
@@ -30,6 +30,10 @@
#include <expat_config.h>
#endif /* ndef COMPILED_FROM_DSP */
+#if ! defined(XML_CONTEXT_BYTES) || (1 - XML_CONTEXT_BYTES - 1 == 2) \
+ || (XML_CONTEXT_BYTES + 0 < 0)
+# error XML_CONTEXT_BYTES must be defined, non-empty and >=0 (0 to disable, >=1 to enable; 1024 is a common default)
+#endif
#include "ascii.h"
#include "expat.h"
@@ -2617,9 +2621,6 @@ doContent(XML_Parser parser, int startTa
int len;
const char *rawName;
TAG *tag = tagStack;
- tagStack = tag->parent;
- tag->parent = freeTagList;
- freeTagList = tag;
rawName = s + enc->minBytesPerChar*2;
len = XmlNameLength(enc, rawName);
if (len != tag->rawNameLength
@@ -2627,6 +2628,9 @@ doContent(XML_Parser parser, int startTa
*eventPP = rawName;
return XML_ERROR_TAG_MISMATCH;
}
+ tagStack = tag->parent;
+ tag->parent = freeTagList;
+ freeTagList = tag;
--tagLevel;
if (endElementHandler) {
const XML_Char *localPart;
@@ -4016,9 +4020,9 @@ entityValueInitProcessor(XML_Parser pars
then, when this routine is entered the next time, XmlPrologTok will
return XML_TOK_INVALID, since the BOM is still in the buffer
*/
- else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
+ else if (tok == XML_TOK_BOM) {
*nextPtr = next;
- return XML_ERROR_NONE;
+ s = next;
}
/* If we get this token, we have the start of what might be a
normal tag, but not a declaration (i.e. it doesn't begin with
@@ -4494,10 +4498,10 @@ doProlog(XML_Parser parser, const ENCODI
attlistDeclHandler(handlerArg, declElementType->name,
declAttributeId->name, declAttributeType,
0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
- poolClear(&tempPool);
handleDefault = XML_FALSE;
}
}
+ poolClear(&tempPool);
break;
case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
@@ -4487,6 +4491,9 @@ doProlog(XML_Parser parser, const ENCODI
break;
case XML_ROLE_ENTITY_VALUE:
if (dtd->keepProcessing) {
+#ifdef XML_DTD
+ // This will store the given replacement text in
+ // parser->m_declEntity->textPtr.
enum XML_Error result = storeEntityValue(parser, enc,
s + enc->minBytesPerChar,
next - enc->minBytesPerChar);
@@ -4554,6 +4561,25 @@ doProlog(XML_Parser parser, const ENCODI
poolDiscard(&dtd->entityValuePool);
if (result != XML_ERROR_NONE)
return result;
+#else
+ // This will store "&entity123;" in parser->m_declEntity->textPtr
+ // to end up as "&entity123;" in the handler.
+ if (parser->m_declEntity != NULL) {
+ const enum XML_Error result
+ = storeSelfEntityValue(parser, parser->m_declEntity);
+ if (result != XML_ERROR_NONE)
+ return result;
+
+ if (parser->m_entityDeclHandler) {
+ *eventEndPP = s;
+ parser->m_entityDeclHandler(
+ parser->m_handlerArg, parser->m_declEntity->name,
+ parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
+ parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
+ handleDefault = XML_FALSE;
+ }
+ }
+#endif
}
break;
case XML_ROLE_DOCTYPE_SYSTEM_ID:
@@ -4611,6 +4637,16 @@ doProlog(XML_Parser parser, const ENCODI
}
break;
case XML_ROLE_ENTITY_COMPLETE:
+#ifndef XML_DTD
+ // This will store "&entity123;" in entity->textPtr
+ // to end up as "&entity123;" in the handler.
+ if (parser->m_declEntity != NULL) {
+ const enum XML_Error result
+ = storeSelfEntityValue(parser, parser->m_declEntity);
+ if (result != XML_ERROR_NONE)
+ return result;
+ }
+#endif
if (dtd->keepProcessing && declEntity && entityDeclHandler) {
*eventEndPP = s;
entityDeclHandler(handlerArg,
@@ -5304,6 +5340,14 @@ internalEntityProcessor(XML_Parser parse
/* put openEntity back in list of free instances */
openEntity->next = freeInternalEntities;
freeInternalEntities = openEntity;
+
+ }
+ // If 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 (parser->m_openInternalEntities != NULL
+ && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
+ return XML_ERROR_NONE;
}
#ifdef XML_DTD
@@ -6000,6 +6043,10 @@ getContext(XML_Parser parser) {
static XML_Bool
setContext(XML_Parser parser, const XML_Char *context)
{
+ if (context == NULL) {
+ return XML_FALSE;
+ }
+
DTD * const dtd = _dtd; /* save one level of indirection */
const XML_Char *s = context;