!182 [sync] PR-179: backport upstream patches

From: @openeuler-sync-bot 
Reviewed-by: @hubin95 
Signed-off-by: @hubin95
This commit is contained in:
openeuler-ci-bot 2023-06-27 03:09:46 +00:00 committed by Gitee
commit d325924f5c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
170 changed files with 9957 additions and 11 deletions

View File

@ -0,0 +1,105 @@
From 966b0f21c15de0c959f4db88d658ba66bda41575 Mon Sep 17 00:00:00 2001
From: Damjan Jovanovic <damjan.jov@gmail.com>
Date: Thu, 19 Aug 2021 02:46:32 +0200
Subject: [PATCH] Add whitespace folding for some atomic data types that it's
missing on.
XSD validation fails when some atomic types contain surrounding whitespace
even though XML Schema Part 2: Datatypes Second Edition, section 4.3.6
says they should be collapsed. Fix this.
(I am not sure whether the test is correct.)
Issue: #278
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/libxml2/-/commit/966b0f21c15de0c959f4db88d658ba66bda41575
---
test/xsdtest/xsdtest.xml | 5 +++++
xmlschemastypes.c | 8 ++++++++
2 files changed, 13 insertions(+)
diff --git a/test/xsdtest/xsdtest.xml b/test/xsdtest/xsdtest.xml
index b8a6de9..2807d26 100644
--- a/test/xsdtest/xsdtest.xml
+++ b/test/xsdtest/xsdtest.xml
@@ -657,6 +657,7 @@ B EEF </value>
</datatype>
<datatype name="byte">
<valid>1</valid>
+<valid> 1 </valid>
<valid>127</valid>
<valid>-128</valid>
<invalid>128</invalid>
@@ -665,6 +666,7 @@ B EEF </value>
<datatype name="unsignedLong">
<valid>1</valid>
<valid>+1</valid>
+<valid> 1 </valid>
<invalid>-1</invalid>
<valid>0</valid>
<valid>18446744073709551615</valid>
@@ -674,6 +676,7 @@ B EEF </value>
<datatype name="unsignedInt">
<valid>1</valid>
<valid>+1</valid>
+<valid> 1 </valid>
<valid>0</valid>
<valid>4294967295</valid>
<invalid>4294967296</invalid>
@@ -682,6 +685,7 @@ B EEF </value>
<datatype name="unsignedShort">
<valid>1</valid>
<valid>+1</valid>
+<valid> 1 </valid>
<valid>0</valid>
<valid>65535</valid>
<invalid>65536</invalid>
@@ -689,6 +693,7 @@ B EEF </value>
</datatype>
<datatype name="unsignedByte">
<valid>1</valid>
+<valid> 1 </valid>
<valid>+1</valid>
<valid>0</valid>
<valid>255</valid>
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index af31be5..ebb0219 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -3308,6 +3308,8 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
if (cur == NULL)
goto return1;
+ if (normOnTheFly)
+ while IS_WSP_BLANK_CH(*cur) cur++;
if (*cur == '-') {
sign = 1;
cur++;
@@ -3316,6 +3318,8 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
if (ret < 0)
goto return1;
+ if (normOnTheFly)
+ while IS_WSP_BLANK_CH(*cur) cur++;
if (*cur != 0)
goto return1;
if (type->builtInType == XML_SCHEMAS_LONG) {
@@ -3380,9 +3384,13 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
if (cur == NULL)
goto return1;
+ if (normOnTheFly)
+ while IS_WSP_BLANK_CH(*cur) cur++;
ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
if (ret < 0)
goto return1;
+ if (normOnTheFly)
+ while IS_WSP_BLANK_CH(*cur) cur++;
if (*cur != 0)
goto return1;
if (type->builtInType == XML_SCHEMAS_ULONG) {
--
2.27.0

View File

@ -0,0 +1,104 @@
From 4951c462eae68562df335ff6d611f4352ea9931d Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 6 Mar 2022 02:29:00 +0100
Subject: [PATCH] Avoid arithmetic on freed pointers
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/libxml2/-/commit/4951c462eae68562df335ff6d611f4352ea9931d
---
parserInternals.c | 45 +++++++++------------------------------------
1 file changed, 9 insertions(+), 36 deletions(-)
diff --git a/parserInternals.c b/parserInternals.c
index c5c0b16..d68592f 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -300,7 +300,6 @@ int
xmlParserInputGrow(xmlParserInputPtr in, int len) {
int ret;
size_t indx;
- const xmlChar *content;
if ((in == NULL) || (len < 0)) return(-1);
#ifdef DEBUG_INPUT
@@ -325,22 +324,8 @@ xmlParserInputGrow(xmlParserInputPtr in, int len) {
} else
return(0);
- /*
- * NOTE : in->base may be a "dangling" i.e. freed pointer in this
- * block, but we use it really as an integer to do some
- * pointer arithmetic. Insure will raise it as a bug but in
- * that specific case, that's not !
- */
-
- content = xmlBufContent(in->buf->buffer);
- if (in->base != content) {
- /*
- * the buffer has been reallocated
- */
- indx = in->cur - in->base;
- in->base = content;
- in->cur = &content[indx];
- }
+ in->base = xmlBufContent(in->buf->buffer);
+ in->cur = in->base + indx;
in->end = xmlBufEnd(in->buf->buffer);
CHECK_BUFFER(in);
@@ -358,8 +343,6 @@ void
xmlParserInputShrink(xmlParserInputPtr in) {
size_t used;
size_t ret;
- size_t indx;
- const xmlChar *content;
#ifdef DEBUG_INPUT
xmlGenericError(xmlGenericErrorContext, "Shrink\n");
@@ -372,7 +355,7 @@ xmlParserInputShrink(xmlParserInputPtr in) {
CHECK_BUFFER(in);
- used = in->cur - xmlBufContent(in->buf->buffer);
+ used = in->cur - in->base;
/*
* Do not shrink on large buffers whose only a tiny fraction
* was consumed
@@ -380,27 +363,17 @@ xmlParserInputShrink(xmlParserInputPtr in) {
if (used > INPUT_CHUNK) {
ret = xmlBufShrink(in->buf->buffer, used - LINE_LEN);
if (ret > 0) {
- in->cur -= ret;
+ used -= ret;
in->consumed += ret;
}
- in->end = xmlBufEnd(in->buf->buffer);
}
- CHECK_BUFFER(in);
-
- if (xmlBufUse(in->buf->buffer) > INPUT_CHUNK) {
- return;
- }
- xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
- content = xmlBufContent(in->buf->buffer);
- if (in->base != content) {
- /*
- * the buffer has been reallocated
- */
- indx = in->cur - in->base;
- in->base = content;
- in->cur = &content[indx];
+ if (xmlBufUse(in->buf->buffer) <= INPUT_CHUNK) {
+ xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
}
+
+ in->base = xmlBufContent(in->buf->buffer);
+ in->cur = in->base + used;
in->end = xmlBufEnd(in->buf->buffer);
CHECK_BUFFER(in);
--
2.27.0

View File

@ -0,0 +1,33 @@
From d58bff6125f066689a872113123152fdcfe693cc Mon Sep 17 00:00:00 2001
From: Alex Richardson <Alexander.Richardson@cl.cam.ac.uk>
Date: Thu, 1 Dec 2022 12:53:15 +0000
Subject: [PATCH 27/28] Avoid creating an out-of-bounds pointer by rewriting a
check
Creating more than one-past-the-end pointers is undefined behaviour in C
and while this code is unlikely to be miscompiled, I discovered that an
out-of-bounds pointer is being created using UBSan on a CHERI-enabled
system.
Reference: https://github.com/GNOME/libxml2/commit/c715ded0861af956ba584f566bc7db6717f519d0
Conflict: NA
---
HTMLparser.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index 746edf6..60dea30 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -2333,7 +2333,7 @@ htmlEncodeEntities(unsigned char* out, int *outlen,
else
cp = ent->name;
len = strlen(cp);
- if (out + 2 + len > outend)
+ if (outend - out < len + 2)
break;
*out++ = '&';
memcpy(out, cp, len);
--
2.27.0

View File

@ -0,0 +1,32 @@
From ecba4cbd4335b31aa7a815701971ed09cfffea9b Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 28 Jun 2022 19:22:31 +0200
Subject: [PATCH] Avoid double-free if malloc fails in inputPush
It's the caller's responsibility to free the input stream if this
function fails.
Reference:https://github.com/GNOME/libxml2/commit/ecba4cbd4335b31aa7a815701971ed09cfffea9b
Conflict:NA
---
parser.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/parser.c b/parser.c
index 0d5bcc1..d8225bd 100644
--- a/parser.c
+++ b/parser.c
@@ -1763,9 +1763,7 @@ inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
sizeof(ctxt->inputTab[0]));
if (ctxt->inputTab == NULL) {
xmlErrMemory(ctxt, NULL);
- xmlFreeInputStream(value);
ctxt->inputMax /= 2;
- value = NULL;
return (-1);
}
}
--
2.27.0

View File

@ -1,4 +1,4 @@
From 647e072ea0a2f12687fa05c172f4c4713fdb0c4f Mon Sep 17 00:00:00 2001
From e4f85f1bd2eb34d9b49da9154a4cc3a1bc284f68 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 7 Apr 2023 11:46:35 +0200
Subject: [PATCH] [CVE-2023-28484] Fix null deref in xmlSchemaFixupComplexType
@ -8,6 +8,10 @@ Fix a null pointer dereference when parsing (invalid) XML schemas.
Thanks to Robby Simpson for the report!
Fixes #491.
Reference:https://github.com/GNOME/libxml2/commit/e4f85f1bd2eb34d9b49da9154a4cc3a1bc284f68
Conflict:NA
---
result/schemas/issue491_0_0.err | 1 +
test/schemas/issue491_0.xml | 1 +
@ -20,21 +24,21 @@ Fixes #491.
diff --git a/result/schemas/issue491_0_0.err b/result/schemas/issue491_0_0.err
new file mode 100644
index 00000000..9b2bb969
index 0000000..9b2bb96
--- /dev/null
+++ b/result/schemas/issue491_0_0.err
@@ -0,0 +1 @@
+./test/schemas/issue491_0.xsd:8: element complexType: Schemas parser error : complex type 'ChildType': The content type of both, the type and its base type, must either 'mixed' or 'element-only'.
diff --git a/test/schemas/issue491_0.xml b/test/schemas/issue491_0.xml
new file mode 100644
index 00000000..e2b2fc2e
index 0000000..e2b2fc2
--- /dev/null
+++ b/test/schemas/issue491_0.xml
@@ -0,0 +1 @@
+<Child xmlns="http://www.test.com">5</Child>
diff --git a/test/schemas/issue491_0.xsd b/test/schemas/issue491_0.xsd
new file mode 100644
index 00000000..81702649
index 0000000..8170264
--- /dev/null
+++ b/test/schemas/issue491_0.xsd
@@ -0,0 +1,18 @@
@ -57,10 +61,10 @@ index 00000000..81702649
+ <xs:element name="Child" type="ChildType" />
+</xs:schema>
diff --git a/xmlschemas.c b/xmlschemas.c
index 17aa6dfa..36cd6730 100644
index 4dbee37..7199d23 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -18563,7 +18563,7 @@ xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
@@ -18640,7 +18640,7 @@ xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
"allowed to appear inside other model groups",
NULL, NULL);

View File

@ -1,4 +1,4 @@
From 09a2dd453007f9c7205274623acdd73747c22d64 Mon Sep 17 00:00:00 2001
From 547edbf1cbdccd46b2e8ff322a456eaa5931c5df Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 7 Apr 2023 11:49:27 +0200
Subject: [PATCH] [CVE-2023-29469] Hashing of empty dict strings isn't
@ -14,12 +14,16 @@ have an impact on security.
Found by OSS-Fuzz.
Fixes #510.
Reference:https://github.com/GNOME/libxml2/commit/547edbf1cbdccd46b2e8ff322a456eaa5931c5df
Conflict:NA
---
dict.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dict.c b/dict.c
index 26ce516d..57b76fae 100644
index 90e4d81..e39e8a4 100644
--- a/dict.c
+++ b/dict.c
@@ -451,7 +451,8 @@ static unsigned long

View File

@ -0,0 +1,42 @@
From d038d7177668030f0c54fa1772d3f174cf6527f1 Mon Sep 17 00:00:00 2001
From: Alex Richardson <Alexander.Richardson@cl.cam.ac.uk>
Date: Thu, 1 Dec 2022 12:58:11 +0000
Subject: [PATCH 26/28] Correctly relocate internal pointers after realloc()
Adding an offset to a deallocated pointer and assuming that it can be
dereferenced is undefined behaviour. When running libxml2 on CHERI-enabled
systems such as Arm Morello this results in the creation of an out-of-bounds
pointer that cannot be dereferenced and therefore crashes at runtime.
The effect of this UB is not just limited to architectures such as CHERI,
incorrect relocation of pointers after realloc can in fact cause
FORTIFY_SOURCE errors with recent GCC:
https://developers.redhat.com/articles/2022/09/17/gccs-new-fortification-level
Reference: https://github.com/GNOME/libxml2/commit/c62c0d82ccacc2000c45f211166f008687fb97a0
Conflict: NA
---
parser.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/parser.c b/parser.c
index 9d50138..adc449c 100644
--- a/parser.c
+++ b/parser.c
@@ -9514,10 +9514,10 @@ next_attr:
* Arithmetic on dangling pointers is technically undefined
* behavior, but well...
*/
- ptrdiff_t offset = ctxt->input->base - atts[i+2];
+ const xmlChar *old = atts[i+2];
atts[i+2] = NULL; /* Reset repurposed namespace URI */
- atts[i+3] += offset; /* value */
- atts[i+4] += offset; /* valuend */
+ atts[i+3] = ctxt->input->base + (atts[i+3] - old); /* value */
+ atts[i+4] = ctxt->input->base + (atts[i+4] - old); /* valuend */
}
}
--
2.27.0

View File

@ -0,0 +1,56 @@
From b1b654171e44dba90bbc6836ca05dd4e1161b4b0 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 20 Aug 2022 15:15:04 +0200
Subject: [PATCH] Create stream with buffer in xmlNewStringInputStream
Create an input stream with a buffer in xmlNewStringInputStream.
Otherwise, switching encodings won't work.
See #34.
Reference:https://github.com/GNOME/libxml2/commit/b1b654171e44dba90bbc6836ca05dd4e1161b4b0
Conflict:NA
---
parserInternals.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/parserInternals.c b/parserInternals.c
index d68592f..6ef7671 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -1465,6 +1465,7 @@ xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
xmlParserInputPtr
xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
xmlParserInputPtr input;
+ xmlParserInputBufferPtr buf;
if (buffer == NULL) {
xmlErrInternal(ctxt, "xmlNewStringInputStream string = NULL\n",
@@ -1474,15 +1475,21 @@ xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
if (xmlParserDebugEntities)
xmlGenericError(xmlGenericErrorContext,
"new fixed input: %.30s\n", buffer);
+ buf = xmlParserInputBufferCreateMem((const char *) buffer,
+ strlen((const char *) buffer),
+ XML_CHAR_ENCODING_NONE);
+ if (buf == NULL) {
+ xmlErrMemory(ctxt, NULL);
+ return(NULL);
+ }
input = xmlNewInputStream(ctxt);
if (input == NULL) {
xmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
+ xmlFreeParserInputBuffer(buf);
return(NULL);
}
- input->base = buffer;
- input->cur = buffer;
- input->length = xmlStrlen(buffer);
- input->end = &buffer[input->length];
+ input->buf = buf;
+ xmlBufResetInput(input->buf->buffer, input);
return(input);
}
--
2.27.0

View File

@ -0,0 +1,30 @@
From 80bd34c3c650bd68e3c9c3e2308ac1988067ad50 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 22 Aug 2022 14:06:37 +0200
Subject: [PATCH] Don't initialize SAX handler in htmlReadMemory
The SAX handler is already initialized when creating the parser
context.
Reference:https://github.com/GNOME/libxml2/commit/80bd34c3c650bd68e3c9c3e2308ac1988067ad50
Conflict:NA
---
HTMLparser.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index c6b2183..e95d86b 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -6980,9 +6980,6 @@ htmlReadMemory(const char *buffer, int size, const char *URL, const char *encodi
ctxt = htmlCreateMemoryParserCtxt(buffer, size);
if (ctxt == NULL)
return (NULL);
- htmlDefaultSAXHandlerInit();
- if (ctxt->sax != NULL)
- memcpy(ctxt->sax, &htmlDefaultSAXHandler, sizeof(xmlSAXHandlerV1));
return (htmlDoRead(ctxt, URL, encoding, options, 0));
}
--
2.27.0

View File

@ -0,0 +1,45 @@
From a17a1f564eaac42d6db561c639b5d2461884e829 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 18 May 2022 02:17:31 +0200
Subject: [PATCH] Don't reset nsDef when changing node content
nsDef is only used for element nodes.
Reference:https://github.com/GNOME/libxml2/commit/a17a1f564eaac42d6db561c639b5d2461884e829
Conflict:NA
---
tree.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/tree.c b/tree.c
index fe6f54a..84da156 100644
--- a/tree.c
+++ b/tree.c
@@ -5721,7 +5721,6 @@ xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
} else
cur->content = NULL;
cur->properties = NULL;
- cur->nsDef = NULL;
break;
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
@@ -5799,7 +5798,6 @@ xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
} else
cur->content = NULL;
cur->properties = NULL;
- cur->nsDef = NULL;
break;
case XML_DOCUMENT_NODE:
case XML_DTD_NODE:
@@ -5878,7 +5876,6 @@ xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
xmlDictOwns(cur->doc->dict, cur->content))) {
cur->content = xmlStrncatNew(cur->content, content, len);
cur->properties = NULL;
- cur->nsDef = NULL;
} else {
cur->content = xmlStrncat(cur->content, content, len);
}
--
2.27.0

View File

@ -0,0 +1,55 @@
From 38f04779f7afd758db6210123ec0b64c489595c5 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 22 Aug 2022 13:33:35 +0200
Subject: [PATCH] Fix HTML parser with threads and --without-legacy
If the legacy functions are disabled, the default "V1" HTML SAX handler
isn't initialized in threads other than the main thread.
htmlInitParserCtxt would later use the empty V1 SAX handler, resulting
in NULL documents.
Change htmlInitParserCtxt to initialize the HTML SAX handler by calling
xmlSAX2InitHtmlDefaultSAXHandler. This removes the ability to change the
default handler but is more in line with the XML parser which
initializes the SAX handler by calling xmlSAXVersion, ignoring the V1
default handler.
Fixes #399.
Reference:https://github.com/GNOME/libxml2/commit/38f04779f7afd758db6210123ec0b64c489595c5
Conflict:NA
---
HTMLparser.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index e95d86b..98d73f3 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -5039,8 +5039,7 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
return(-1);
}
- else
- memset(sax, 0, sizeof(htmlSAXHandler));
+ memset(sax, 0, sizeof(htmlSAXHandler));
/* Allocate the Input stack */
ctxt->inputTab = (htmlParserInputPtr *)
@@ -5099,11 +5098,9 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
ctxt->nodeInfoNr = 0;
ctxt->nodeInfoMax = 0;
- if (sax == NULL) ctxt->sax = (xmlSAXHandlerPtr) &htmlDefaultSAXHandler;
- else {
- ctxt->sax = sax;
- memcpy(sax, &htmlDefaultSAXHandler, sizeof(xmlSAXHandlerV1));
- }
+ ctxt->sax = sax;
+ xmlSAX2InitHtmlDefaultSAXHandler(sax);
+
ctxt->userData = ctxt;
ctxt->myDoc = NULL;
ctxt->wellFormed = 1;
--
2.27.0

View File

@ -0,0 +1,28 @@
From 37cedc0b1563e5e312a924ac07168722a4e768d8 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 22 Aug 2022 14:04:07 +0200
Subject: [PATCH] Fix htmlReadMemory mixing up XML and HTML functions
Also see fe6890e2.
Reference:https://github.com/GNOME/libxml2/commit/37cedc0b1563e5e312a924ac07168722a4e768d8
Conflict:NA
---
HTMLparser.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index e720bb2..c6b2183 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -6977,7 +6977,7 @@ htmlReadMemory(const char *buffer, int size, const char *URL, const char *encodi
htmlParserCtxtPtr ctxt;
xmlInitParser();
- ctxt = xmlCreateMemoryParserCtxt(buffer, size);
+ ctxt = htmlCreateMemoryParserCtxt(buffer, size);
if (ctxt == NULL)
return (NULL);
htmlDefaultSAXHandlerInit();
--
2.27.0

View File

@ -0,0 +1,41 @@
From a6df42e649acacb55be832222d1f3f50c66720ff Mon Sep 17 00:00:00 2001
From: David Kilzer <ddkilzer@apple.com>
Date: Sat, 28 May 2022 08:08:29 -0700
Subject: [PATCH 296/300] Fix integer overflow in xmlBufferDump()
* tree.c:
(xmlBufferDump):
- Cap the return value to INT_MAX.
Reference:https://github.com/GNOME/libxml2/commit/a6df42e649acacb55be832222d1f3f50c66720ff
Conflict:NA
---
tree.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tree.c b/tree.c
index 0cf2483..3dff195 100644
--- a/tree.c
+++ b/tree.c
@@ -7380,7 +7380,7 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
*/
int
xmlBufferDump(FILE *file, xmlBufferPtr buf) {
- int ret;
+ size_t ret;
if (buf == NULL) {
#ifdef DEBUG_BUFFER
@@ -7399,7 +7399,7 @@ xmlBufferDump(FILE *file, xmlBufferPtr buf) {
if (file == NULL)
file = stdout;
ret = fwrite(buf->content, sizeof(xmlChar), buf->use, file);
- return(ret);
+ return(ret > INT_MAX ? INT_MAX : (int)ret);
}
/**
--
2.27.0

View File

@ -0,0 +1,33 @@
From ca2c91f139426f63646292da58a15a1511dccc0f Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 28 Jun 2022 19:24:14 +0200
Subject: [PATCH] Fix memory leak in xmlLoadEntityContent error path
Free the input stream if pushing it fails.
Found by OSS-Fuzz.
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=43743
Reference:https://github.com/GNOME/libxml2/commit/ca2c91f139426f63646292da58a15a1511dccc0f
Conflict:NA
---
parser.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/parser.c b/parser.c
index d8225bd..dd507c0 100644
--- a/parser.c
+++ b/parser.c
@@ -8102,6 +8102,7 @@ xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
*/
if (xmlPushInput(ctxt, input) < 0) {
xmlBufferFree(buf);
+ xmlFreeInputStream(input);
return(-1);
}
--
2.27.0

View File

@ -0,0 +1,63 @@
From a09c89545d3ed5b56701abcc5d638faa01c5c903 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 15 Aug 2022 12:19:25 +0200
Subject: [PATCH] Fix memory leak with invalid XSD
xmlSchemaClearElemInfo can add new items to the "matcher" cache, so the
cache must be cleared after calling this function, not before. This
only seems to affect invalid XSDs.
Fixes #390.
Reference:https://github.com/GNOME/libxml2/commit/a09c89545d3ed5b56701abcc5d638faa01c5c903
Conflict:NA
---
xmlschemas.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/xmlschemas.c b/xmlschemas.c
index 9da4cd1..9aa6acf 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -27830,17 +27830,6 @@ xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
} while (cur != NULL);
vctxt->aidcs = NULL;
}
- if (vctxt->idcMatcherCache != NULL) {
- xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
-
- while (matcher) {
- tmp = matcher;
- matcher = matcher->nextCached;
- xmlSchemaIDCFreeMatcherList(tmp);
- }
- vctxt->idcMatcherCache = NULL;
- }
-
if (vctxt->idcNodes != NULL) {
int i;
@@ -27907,6 +27896,21 @@ xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
xmlFree(vctxt->filename);
vctxt->filename = NULL;
}
+
+ /*
+ * Note that some cleanup functions can move items to the cache,
+ * so the cache shouldn't be freed too early.
+ */
+ if (vctxt->idcMatcherCache != NULL) {
+ xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
+
+ while (matcher) {
+ tmp = matcher;
+ matcher = matcher->nextCached;
+ xmlSchemaIDCFreeMatcherList(tmp);
+ }
+ vctxt->idcMatcherCache = NULL;
+ }
}
/**
--
2.27.0

View File

@ -0,0 +1,84 @@
From 4ce2abf6f656b3e78ad40e33191a8b42561c10b0 Mon Sep 17 00:00:00 2001
From: David Kilzer <ddkilzer@apple.com>
Date: Sun, 29 May 2022 09:46:00 -0700
Subject: [PATCH 299/300] Fix missing NUL terminators in xmlBuf and xmlBuffer
functions
* buf.c:
(xmlBufAddLen):
- Change check for remaining space to account for the NUL
terminator. When adding a length exactly equal to the number
of unused bytes, a NUL terminator was not written.
(xmlBufResize):
- Set `buf->use` and NUL terminator when allocating a new
buffer.
* tree.c:
(xmlBufferResize):
- Set `buf->use` and NUL terminator when allocating a new
buffer.
(xmlBufferAddHead):
- Set NUL terminator before returning early when shifting
contents.
Reference:https://github.com/GNOME/libxml2/commit/4ce2abf6f656b3e78ad40e33191a8b42561c10b0
Conflict:NA
---
buf.c | 9 ++++-----
tree.c | 3 +++
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/buf.c b/buf.c
index f896826..da765f6 100644
--- a/buf.c
+++ b/buf.c
@@ -613,14 +613,11 @@ xmlBufAddLen(xmlBufPtr buf, size_t len) {
if ((buf == NULL) || (buf->error))
return(-1);
CHECK_COMPAT(buf)
- if (len > (buf->size - buf->use))
+ if (len >= (buf->size - buf->use))
return(-1);
buf->use += len;
+ buf->content[buf->use] = 0;
UPDATE_COMPAT(buf)
- if (buf->size > buf->use)
- buf->content[buf->use] = 0;
- else
- return(-1);
return(0);
}
@@ -821,6 +818,8 @@ xmlBufResize(xmlBufPtr buf, size_t size)
} else {
if (buf->content == NULL) {
rebuf = (xmlChar *) xmlMallocAtomic(newSize);
+ buf->use = 0;
+ rebuf[buf->use] = 0;
} else if (buf->size - buf->use < 100) {
rebuf = (xmlChar *) xmlRealloc(buf->content, newSize);
} else {
diff --git a/tree.c b/tree.c
index 3dff195..e275671 100644
--- a/tree.c
+++ b/tree.c
@@ -7529,6 +7529,8 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
} else {
if (buf->content == NULL) {
rebuf = (xmlChar *) xmlMallocAtomic(newSize);
+ buf->use = 0;
+ rebuf[buf->use] = 0;
} else if (buf->size - buf->use < 100) {
rebuf = (xmlChar *) xmlRealloc(buf->content, newSize);
} else {
@@ -7657,6 +7659,7 @@ xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
memmove(&buf->content[0], str, len);
buf->use += len;
buf->size += len;
+ buf->content[buf->use] = 0;
return(0);
}
}
--
2.27.0

View File

@ -0,0 +1,63 @@
From f5b31e49bcababb8da09c2697e24d0ba80a261b6 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 1 Sep 2022 02:33:16 +0200
Subject: [PATCH] Fix overflow check in SAX2.c
Reference:https://github.com/GNOME/libxml2/commit/aeb69fd3575a33eb2ffded18a444d8945bcbd741
Conflict:SAX2.c
---
SAX2.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/SAX2.c b/SAX2.c
index 0319246..9801393 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -28,11 +28,6 @@
#include <libxml/HTMLtree.h>
#include <libxml/globals.h>
-/* Define SIZE_T_MAX unless defined through <limits.h>. */
-#ifndef SIZE_T_MAX
-# define SIZE_T_MAX ((size_t)-1)
-#endif /* !SIZE_T_MAX */
-
/* #define DEBUG_SAX2 */
/* #define DEBUG_SAX2_TREE */
@@ -2576,22 +2571,23 @@ xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL");
return;
}
- if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) &&
+ if (ctxt->nodelen > INT_MAX - len) {
+ xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented");
+ return;
+ }
+ if ((ctxt->nodelen + len > XML_MAX_TEXT_LENGTH) &&
((ctxt->options & XML_PARSE_HUGE) == 0)) {
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
return;
}
- if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len ||
- (size_t)ctxt->nodemem + (size_t)len > SIZE_T_MAX / 2) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented");
- return;
- }
if (ctxt->nodelen + len >= ctxt->nodemem) {
xmlChar *newbuf;
- size_t size;
+ int size;
- size = ctxt->nodemem + len;
- size *= 2;
+ size = ctxt->nodemem > INT_MAX - len ?
+ INT_MAX :
+ ctxt->nodemem + len;
+ size = size > INT_MAX / 2 ? INT_MAX : size * 2;
newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
if (newbuf == NULL) {
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
--
2.27.0

View File

@ -0,0 +1,34 @@
From 2464652537fa5f3b89e71c31eed777b42fa64708 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 18 May 2022 02:16:34 +0200
Subject: [PATCH] Fix unintended fall-through in xmlNodeAddContentLen
Reference:https://github.com/GNOME/libxml2/commit/2464652537fa5f3b89e71c31eed777b42fa64708
Conflict:NA
---
tree.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tree.c b/tree.c
index ed0a838..fe6f54a 100644
--- a/tree.c
+++ b/tree.c
@@ -5879,10 +5879,11 @@ xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
cur->content = xmlStrncatNew(cur->content, content, len);
cur->properties = NULL;
cur->nsDef = NULL;
- break;
- }
- cur->content = xmlStrncat(cur->content, content, len);
+ } else {
+ cur->content = xmlStrncat(cur->content, content, len);
+ }
}
+ break;
case XML_DOCUMENT_NODE:
case XML_DTD_NODE:
case XML_HTML_DOCUMENT_NODE:
--
2.27.0

View File

@ -0,0 +1,115 @@
From c50196c13d348025a4843305902bb37df64bae36 Mon Sep 17 00:00:00 2001
From: David Kilzer <ddkilzer@apple.com>
Date: Sun, 10 Apr 2022 20:02:47 -0700
Subject: [PATCH 289/300] Fix use-after-free bugs when calling
xmlTextReaderClose() before xmlFreeTextReader() on post-validating parser
When creating an xmlTextReaderPtr using xmlReaderForMemory(),
there are two optional API functions that can be used:
- xmlTextReaderClose() may be called prior to calling
xmlFreeTextReader() to free parsing resources and close the
xmlTextReaderPtr without freeing it.
- xmlTextReaderCurrentDoc() may be called to return an
xmlDocPtr that's owned by the caller, and must be free using
xmlFreeDoc() after calling xmlFreeTextReader().
The use-after-free issues occur when calling
xmlTextReaderClose() before xmlFreeTextReader(), with different
issues occurring depending on whether xmlTextReaderCurrentDoc()
is also called.
* xmlreader.c:
(xmlFreeTextReader):
- Move code to xmlTextReaderClose(), remove duplicate code, and
call xmlTextReaderClose() if it hasn't been called yet.
(xmlTextReaderClose):
- Move call to xmlFreeNode(reader->faketext) from
xmlFreeTextReader() to fix a use-after-free bug when calling
xmlTextReaderClose() before xmlFreeTextReader(), but not when
using xmlTextReaderCurrentDoc(). The bug was introduced in
2002 by commit beb70bd39. In 2009 commit f4653dcd8 fixed the
use-after-free that occurred every time xmlFreeTextReader()
was called, but not the case where xmlTextReaderClose() was
called first.
- Move post-parsing validation code from xmlFreeTextReader() to
fix a second use-after-free when calling xmlTextReaderClose()
before xmlFreeTextReader(). This regressed in v2.9.10 with
commit 57a3af56f.
Reference:https://github.com/GNOME/libxml2/commit/c50196c13d348025a4843305902bb37df64bae36
Conflict:NA
---
xmlreader.c | 40 ++++++++++++++++++----------------------
1 file changed, 18 insertions(+), 22 deletions(-)
diff --git a/xmlreader.c b/xmlreader.c
index 72e40b0..989b7c1 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -2319,36 +2319,16 @@ xmlFreeTextReader(xmlTextReaderPtr reader) {
xmlFree(reader->patternTab);
}
#endif
- if (reader->faketext != NULL) {
- xmlFreeNode(reader->faketext);
- }
+ if (reader->mode != XML_TEXTREADER_MODE_CLOSED)
+ xmlTextReaderClose(reader);
if (reader->ctxt != NULL) {
if (reader->dict == reader->ctxt->dict)
reader->dict = NULL;
-#ifdef LIBXML_VALID_ENABLED
- if ((reader->ctxt->vctxt.vstateTab != NULL) &&
- (reader->ctxt->vctxt.vstateMax > 0)){
-#ifdef LIBXML_REGEXP_ENABLED
- while (reader->ctxt->vctxt.vstateNr > 0)
- xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL);
-#endif /* LIBXML_REGEXP_ENABLED */
- xmlFree(reader->ctxt->vctxt.vstateTab);
- reader->ctxt->vctxt.vstateTab = NULL;
- reader->ctxt->vctxt.vstateMax = 0;
- }
-#endif /* LIBXML_VALID_ENABLED */
- if (reader->ctxt->myDoc != NULL) {
- if (reader->preserve == 0)
- xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
- reader->ctxt->myDoc = NULL;
- }
if (reader->allocs & XML_TEXTREADER_CTXT)
xmlFreeParserCtxt(reader->ctxt);
}
if (reader->sax != NULL)
xmlFree(reader->sax);
- if ((reader->input != NULL) && (reader->allocs & XML_TEXTREADER_INPUT))
- xmlFreeParserInputBuffer(reader->input);
if (reader->buffer != NULL)
xmlBufFree(reader->buffer);
if (reader->entTab != NULL)
@@ -2379,7 +2359,23 @@ xmlTextReaderClose(xmlTextReaderPtr reader) {
reader->node = NULL;
reader->curnode = NULL;
reader->mode = XML_TEXTREADER_MODE_CLOSED;
+ if (reader->faketext != NULL) {
+ xmlFreeNode(reader->faketext);
+ reader->faketext = NULL;
+ }
if (reader->ctxt != NULL) {
+#ifdef LIBXML_VALID_ENABLED
+ if ((reader->ctxt->vctxt.vstateTab != NULL) &&
+ (reader->ctxt->vctxt.vstateMax > 0)){
+#ifdef LIBXML_REGEXP_ENABLED
+ while (reader->ctxt->vctxt.vstateNr > 0)
+ xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL);
+#endif /* LIBXML_REGEXP_ENABLED */
+ xmlFree(reader->ctxt->vctxt.vstateTab);
+ reader->ctxt->vctxt.vstateTab = NULL;
+ reader->ctxt->vctxt.vstateMax = 0;
+ }
+#endif /* LIBXML_VALID_ENABLED */
xmlStopParser(reader->ctxt);
if (reader->ctxt->myDoc != NULL) {
if (reader->preserve == 0)
--
2.27.0

View File

@ -0,0 +1,37 @@
From 86105c0493f19ef8e1dd21ab5099613159224b4d Mon Sep 17 00:00:00 2001
From: David Kilzer <ddkilzer@apple.com>
Date: Sat, 15 Apr 2023 18:04:03 -0700
Subject: [PATCH] Fix use-after-free in xmlParseContentInternal()
* parser.c:
(xmlParseCharData):
- Check if the parser has stopped before advancing
`ctxt->input->cur`. This only occurs if a custom SAX error
handler calls xmlStopParser() on fatal errors.
Fixes #518.
Reference:https://github.com/GNOME/libxml2/commit/86105c0493f19ef8e1dd21ab5099613159224b4d
Conflict:parser.c
---
parser.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/parser.c b/parser.c
index f9b4012..ccddf07 100644
--- a/parser.c
+++ b/parser.c
@@ -4504,7 +4504,8 @@ get_more:
if (*in == ']') {
if ((in[1] == ']') && (in[2] == '>')) {
xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
- ctxt->input->cur = in + 1;
+ if (ctxt->instate != XML_PARSER_EOF)
+ ctxt->input->cur = in + 1;
return;
}
in++;
--
2.27.0

View File

@ -0,0 +1,87 @@
From 4ad71c2d72beef0d10cf75aa417db10d77846f75 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 20 Aug 2022 16:19:34 +0200
Subject: [PATCH] Fix xmlCtxtReadDoc with encoding
xmlCtxtReadDoc used to create an input stream involving
xmlNewStringInputStream. This would create a stream without an input
buffer, causing problems with encodings (see #34).
After commit aab584dc3, an error was returned even with UTF-8 encodings
which happened to work before.
Make xmlCtxtReadDoc call xmlCtxtReadMemory which doesn't suffer from
these issues. Also fix htmlCtxtReadDoc.
Fixes #397.
Reference:https://github.com/GNOME/libxml2/commit/4ad71c2d72beef0d10cf75aa417db10d77846f75
Conflict:NA
---
HTMLparser.c | 17 ++++-------------
parser.c | 16 +++-------------
2 files changed, 7 insertions(+), 26 deletions(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index 98d73f3..a4168f3 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -7087,22 +7087,13 @@ htmlDocPtr
htmlCtxtReadDoc(htmlParserCtxtPtr ctxt, const xmlChar * cur,
const char *URL, const char *encoding, int options)
{
- xmlParserInputPtr stream;
+ const char *buf;
if (cur == NULL)
return (NULL);
- if (ctxt == NULL)
- return (NULL);
- xmlInitParser();
-
- htmlCtxtReset(ctxt);
-
- stream = xmlNewStringInputStream(ctxt, cur);
- if (stream == NULL) {
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (htmlDoRead(ctxt, URL, encoding, options, 1));
+ buf = (const char *) cur;
+ return (htmlCtxtReadMemory(ctxt, buf, strlen(buf), URL, encoding,
+ options));
}
/**
diff --git a/parser.c b/parser.c
index 6b04bbf..fbeb7af 100644
--- a/parser.c
+++ b/parser.c
@@ -15374,22 +15374,12 @@ xmlDocPtr
xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
const char *URL, const char *encoding, int options)
{
- xmlParserInputPtr stream;
+ const char *buf;
if (cur == NULL)
return (NULL);
- if (ctxt == NULL)
- return (NULL);
- xmlInitParser();
-
- xmlCtxtReset(ctxt);
-
- stream = xmlNewStringInputStream(ctxt, cur);
- if (stream == NULL) {
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (xmlDoRead(ctxt, URL, encoding, options, 1));
+ buf = (const char *) cur;
+ return (xmlCtxtReadMemory(ctxt, buf, strlen(buf), URL, encoding, options));
}
/**
--
2.27.0

View File

@ -0,0 +1,115 @@
From 677a42645ef22b5a50741bad5facf9d8a8bc6d21 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 28 Jul 2022 20:21:24 +0200
Subject: [PATCH] Make XPath depth check work with recursive invocations
EXSLT functions like dyn:map or dyn:evaluate invoke xmlXPathRunEval
recursively. Don't set depth to zero but keep and restore the original
value to avoid stack overflows when abusing these functions.
Reference:https://github.com/GNOME/libxml2/commit/677a42645ef22b5a50741bad5facf9d8a8bc6d21
Conflict:NA
---
xpath.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/xpath.c b/xpath.c
index e79dcec..85d7919 100644
--- a/xpath.c
+++ b/xpath.c
@@ -13883,12 +13883,11 @@ static int
xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
{
xmlXPathCompExprPtr comp;
+ int oldDepth;
if ((ctxt == NULL) || (ctxt->comp == NULL))
return(-1);
- ctxt->context->depth = 0;
-
if (ctxt->valueTab == NULL) {
/* Allocate the value stack */
ctxt->valueTab = (xmlXPathObjectPtr *)
@@ -13942,11 +13941,13 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
"xmlXPathRunEval: last is less than zero\n");
return(-1);
}
+ oldDepth = ctxt->context->depth;
if (toBool)
return(xmlXPathCompOpEvalToBoolean(ctxt,
&comp->steps[comp->last], 0));
else
xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]);
+ ctxt->context->depth = oldDepth;
return(0);
}
@@ -14217,6 +14218,7 @@ xmlXPathCompExprPtr
xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
xmlXPathParserContextPtr pctxt;
xmlXPathCompExprPtr comp;
+ int oldDepth = 0;
#ifdef XPATH_STREAMING
comp = xmlXPathTryStreamCompile(ctxt, str);
@@ -14230,8 +14232,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
if (pctxt == NULL)
return NULL;
if (ctxt != NULL)
- ctxt->depth = 0;
+ oldDepth = ctxt->depth;
xmlXPathCompileExpr(pctxt, 1);
+ if (ctxt != NULL)
+ ctxt->depth = oldDepth;
if( pctxt->error != XPATH_EXPRESSION_OK )
{
@@ -14252,8 +14256,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
comp = pctxt->comp;
if ((comp->nbStep > 1) && (comp->last >= 0)) {
if (ctxt != NULL)
- ctxt->depth = 0;
+ oldDepth = ctxt->depth;
xmlXPathOptimizeExpression(pctxt, &comp->steps[comp->last]);
+ if (ctxt != NULL)
+ ctxt->depth = oldDepth;
}
pctxt->comp = NULL;
}
@@ -14409,6 +14415,7 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
#ifdef XPATH_STREAMING
xmlXPathCompExprPtr comp;
#endif
+ int oldDepth = 0;
if (ctxt == NULL) return;
@@ -14422,8 +14429,10 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
#endif
{
if (ctxt->context != NULL)
- ctxt->context->depth = 0;
+ oldDepth = ctxt->context->depth;
xmlXPathCompileExpr(ctxt, 1);
+ if (ctxt->context != NULL)
+ ctxt->context->depth = oldDepth;
CHECK_ERROR;
/* Check for trailing characters. */
@@ -14432,9 +14441,11 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
if ((ctxt->comp->nbStep > 1) && (ctxt->comp->last >= 0)) {
if (ctxt->context != NULL)
- ctxt->context->depth = 0;
+ oldDepth = ctxt->context->depth;
xmlXPathOptimizeExpression(ctxt,
&ctxt->comp->steps[ctxt->comp->last]);
+ if (ctxt->context != NULL)
+ ctxt->context->depth = oldDepth;
}
}
--
2.27.0

View File

@ -0,0 +1,44 @@
From 2fe372a0aa2cdeb5cf518cf430defba36647c502 Mon Sep 17 00:00:00 2001
From: Damjan Jovanovic <damjan.jov@gmail.com>
Date: Sat, 21 Aug 2021 07:21:50 +0200
Subject: [PATCH] Properly fold whitespace around the QName value when
validating an XSD schema.
(May also need fixing in other places.)
Issue: 239
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/libxml2/-/commit/2fe372a0aa2cdeb5cf518cf430defba36647c502
---
xmlschemas.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/xmlschemas.c b/xmlschemas.c
index 2da962b..9da4cd1 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -24645,6 +24645,7 @@ xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
int valNeeded)
{
int ret;
+ xmlChar *stripped;
const xmlChar *nsName;
xmlChar *local, *prefix = NULL;
@@ -24661,7 +24662,10 @@ xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
* NOTE: xmlSplitQName2 will always return a duplicated
* strings.
*/
- local = xmlSplitQName2(value, &prefix);
+ /* TODO: Export and use xmlSchemaStrip instead */
+ stripped = xmlSchemaCollapseString(value);
+ local = xmlSplitQName2(stripped ? stripped : value, &prefix);
+ xmlFree(stripped);
if (local == NULL)
local = xmlStrdup(value);
/*
--
2.27.0

View File

@ -0,0 +1,153 @@
From 6ef16dee7ac8af32b8a0dd793445b1148e240364 Mon Sep 17 00:00:00 2001
From: David Kilzer <ddkilzer@apple.com>
Date: Fri, 13 May 2022 14:43:33 -0700
Subject: [PATCH 300/300] Reserve byte for NUL terminator and report errors
consistently in xmlBuf and xmlBuffer
This is a follow-up to commit 6c283d83.
* buf.c:
(xmlBufGrowInternal):
- Call xmlBufMemoryError() when the buffer size would overflow.
- Account for NUL terminator byte when using XML_MAX_TEXT_LENGTH.
- Do not include NUL terminator byte when returning length.
(xmlBufAdd):
- Call xmlBufMemoryError() when the buffer size would overflow.
* tree.c:
(xmlBufferGrow):
- Call xmlTreeErrMemory() when the buffer size would overflow.
- Do not include NUL terminator byte when returning length.
(xmlBufferResize):
- Update error message in xmlTreeErrMemory() to be consistent
with other similar messages.
(xmlBufferAdd):
- Call xmlTreeErrMemory() when the buffer size would overflow.
(xmlBufferAddHead):
- Add overflow checks similar to those in xmlBufferAdd().
Reference:https://github.com/GNOME/libxml2/commit/6ef16dee7ac8af32b8a0dd793445b1148e240364
Conflict:NA
---
buf.c | 15 ++++++++++-----
tree.c | 22 ++++++++++++++++------
2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/buf.c b/buf.c
index da765f6..e851364 100644
--- a/buf.c
+++ b/buf.c
@@ -440,9 +440,11 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
if (len < buf->size - buf->use)
- return(buf->size - buf->use);
- if (len > SIZE_MAX - buf->use)
+ return(buf->size - buf->use - 1);
+ if (len >= SIZE_MAX - buf->use) {
+ xmlBufMemoryError(buf, "growing buffer past SIZE_MAX");
return(0);
+ }
if (buf->size > (size_t) len) {
size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2;
@@ -455,7 +457,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
/*
* Used to provide parsing limits
*/
- if ((buf->use + len >= XML_MAX_TEXT_LENGTH) ||
+ if ((buf->use + len + 1 >= XML_MAX_TEXT_LENGTH) ||
(buf->size >= XML_MAX_TEXT_LENGTH)) {
xmlBufMemoryError(buf, "buffer error: text too long\n");
return(0);
@@ -483,7 +485,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
}
buf->size = size;
UPDATE_COMPAT(buf)
- return(buf->size - buf->use);
+ return(buf->size - buf->use - 1);
}
/**
@@ -883,9 +885,12 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
if (len < 0) return -1;
if (len == 0) return 0;
+ /* Note that both buf->size and buf->use can be zero here. */
if ((size_t) len >= buf->size - buf->use) {
- if ((size_t) len >= SIZE_MAX - buf->use)
+ if ((size_t) len >= SIZE_MAX - buf->use) {
+ xmlBufMemoryError(buf, "growing buffer past SIZE_MAX");
return(-1);
+ }
needSize = buf->use + len + 1;
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
/*
diff --git a/tree.c b/tree.c
index e275671..ed0a838 100644
--- a/tree.c
+++ b/tree.c
@@ -7338,8 +7338,10 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
if (len < buf->size - buf->use)
return(0);
- if (len > UINT_MAX - buf->use)
+ if (len >= UINT_MAX - buf->use) {
+ xmlTreeErrMemory("growing buffer past UINT_MAX");
return(-1);
+ }
if (buf->size > (size_t) len) {
size = buf->size > UINT_MAX / 2 ? UINT_MAX : buf->size * 2;
@@ -7367,7 +7369,7 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
buf->content = newbuf;
}
buf->size = size;
- return(buf->size - buf->use);
+ return(buf->size - buf->use - 1);
}
/**
@@ -7464,7 +7466,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
return 1;
if (size > UINT_MAX - 10) {
- xmlTreeErrMemory("growing buffer");
+ xmlTreeErrMemory("growing buffer past UINT_MAX");
return 0;
}
@@ -7592,9 +7594,12 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
if (len < 0) return -1;
if (len == 0) return 0;
+ /* Note that both buf->size and buf->use can be zero here. */
if ((unsigned) len >= buf->size - buf->use) {
- if ((unsigned) len >= UINT_MAX - buf->use)
+ if ((unsigned) len >= UINT_MAX - buf->use) {
+ xmlTreeErrMemory("growing buffer past UINT_MAX");
return XML_ERR_NO_MEMORY;
+ }
needSize = buf->use + len + 1;
if (!xmlBufferResize(buf, needSize)){
xmlTreeErrMemory("growing buffer");
@@ -7663,8 +7668,13 @@ xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
return(0);
}
}
- needSize = buf->use + len + 2;
- if (needSize > buf->size){
+ /* Note that both buf->size and buf->use can be zero here. */
+ if ((unsigned) len >= buf->size - buf->use) {
+ if ((unsigned) len >= UINT_MAX - buf->use) {
+ xmlTreeErrMemory("growing buffer past UINT_MAX");
+ return(-1);
+ }
+ needSize = buf->use + len + 1;
if (!xmlBufferResize(buf, needSize)){
xmlTreeErrMemory("growing buffer");
return XML_ERR_NO_MEMORY;
--
2.27.0

View File

@ -0,0 +1,28 @@
From 5930fe01963136ab92125feec0c6204d9c9225dc Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 18 Jul 2022 20:59:45 +0200
Subject: [PATCH] Reset nsNr in xmlCtxtReset
Reference:https://github.com/GNOME/libxml2/commit/5930fe01963136ab92125feec0c6204d9c9225dc
Conflict:NA
---
parser.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/parser.c b/parser.c
index dd507c0..6b04bbf 100644
--- a/parser.c
+++ b/parser.c
@@ -14835,6 +14835,8 @@ xmlCtxtReset(xmlParserCtxtPtr ctxt)
ctxt->nameNr = 0;
ctxt->name = NULL;
+ ctxt->nsNr = 0;
+
DICT_FREE(ctxt->version);
ctxt->version = NULL;
DICT_FREE(ctxt->encoding);
--
2.27.0

View File

@ -0,0 +1,42 @@
From 054e46b097524d3808fdc0815b64e14beb2baaf9 Mon Sep 17 00:00:00 2001
From: David Kilzer <ddkilzer@apple.com>
Date: Sat, 14 May 2022 08:48:01 -0700
Subject: [PATCH 288/300] Restore behavior of htmlDocContentDumpFormatOutput()
Patch by J Pascoe of Apple.
* HTMLtree.c:
(htmlDocContentDumpFormatOutput):
- Prior to commit b79ab6e6d92, xmlDoc.type was set to
XML_HTML_DOCUMENT_NODE before dumping the HTML output, then
restored before returning.
Reference:https://github.com/GNOME/libxml2/commit/054e46b097524d3808fdc0815b64e14beb2baaf9
Conflict:NA
---
HTMLtree.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/HTMLtree.c b/HTMLtree.c
index 7a2b855..2e9fc57 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -992,7 +992,14 @@ void
htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
const char *encoding ATTRIBUTE_UNUSED,
int format) {
+ int type = 0;
+ if (cur) {
+ type = cur->type;
+ cur->type = XML_HTML_DOCUMENT_NODE;
+ }
htmlNodeDumpFormatOutput(buf, cur, (xmlNodePtr) cur, NULL, format);
+ if (cur)
+ cur->type = (xmlElementType) type;
}
/**
--
2.27.0

View File

@ -0,0 +1,31 @@
From 8ed40c621b33b44c26e90505b9de1c92080c4a8e Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 13 Dec 2022 00:51:33 +0100
Subject: [PATCH] Revert "uri: Allow port without host"
This reverts commit f30adb54f55e4e765d58195163f2a21f7ac759fb.
Fixes #460.
Reference:https://github.com/GNOME/libxml2/commit/8ed40c621b33b44c26e90505b9de1c92080c4a8e
Conflict:NA
---
uri.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/uri.c b/uri.c
index 79dc48b..ccc26aa 100644
--- a/uri.c
+++ b/uri.c
@@ -768,6 +768,8 @@ xmlParse3986HierPart(xmlURIPtr uri, const char **str)
cur += 2;
ret = xmlParse3986Authority(uri, &cur);
if (ret != 0) return(ret);
+ if (uri->server == NULL)
+ uri->port = -1;
ret = xmlParse3986PathAbEmpty(uri, &cur);
if (ret != 0) return(ret);
*str = cur;
--
2.27.0

View File

@ -0,0 +1,92 @@
From a15f2abef1463c20bc62a455e983e34b2278f279 Mon Sep 17 00:00:00 2001
From: David Kilzer <ddkilzer@webkit.org>
Date: Fri, 8 Apr 2022 12:16:51 -0700
Subject: [PATCH 260/300] Use UPDATE_COMPAT() consistently in buf.c
* buf.c:
(xmlBufCreate):
(xmlBufCreateSize):
(xmlBufDetach):
(xmlBufCreateStatic):
(xmlBufFromBuffer):
Reference:https://github.com/GNOME/libxml2/commit/a15f2abef1463c20bc62a455e983e34b2278f279
Conflict:Context adaptation
---
buf.c | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/buf.c b/buf.c
index 40a5ee0..d341750 100644
--- a/buf.c
+++ b/buf.c
@@ -131,12 +131,11 @@ xmlBufCreate(void) {
xmlBufMemoryError(NULL, "creating buffer");
return(NULL);
}
- ret->compat_use = 0;
ret->use = 0;
ret->error = 0;
ret->buffer = NULL;
ret->size = xmlDefaultBufferSize;
- ret->compat_size = xmlDefaultBufferSize;
+ UPDATE_COMPAT(ret);
ret->alloc = xmlBufferAllocScheme;
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
if (ret->content == NULL) {
@@ -167,13 +166,12 @@ xmlBufCreateSize(size_t size) {
xmlBufMemoryError(NULL, "creating buffer");
return(NULL);
}
- ret->compat_use = 0;
ret->use = 0;
ret->error = 0;
ret->buffer = NULL;
ret->alloc = xmlBufferAllocScheme;
ret->size = (size ? size + 1 : 0); /* +1 for ending null */
- ret->compat_size = (ret->size > INT_MAX ? INT_MAX : ret->size);
+ UPDATE_COMPAT(ret);
if (ret->size){
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
if (ret->content == NULL) {
@@ -215,8 +213,7 @@ xmlBufDetach(xmlBufPtr buf) {
buf->content = NULL;
buf->size = 0;
buf->use = 0;
- buf->compat_use = 0;
- buf->compat_size = 0;
+ UPDATE_COMPAT(buf);
return ret;
}
@@ -245,15 +242,9 @@ xmlBufCreateStatic(void *mem, size_t size) {
xmlBufMemoryError(NULL, "creating buffer");
return(NULL);
}
- if (size < INT_MAX) {
- ret->compat_use = size;
- ret->compat_size = size;
- } else {
- ret->compat_use = INT_MAX;
- ret->compat_size = INT_MAX;
- }
ret->use = size;
ret->size = size;
+ UPDATE_COMPAT(ret);
ret->alloc = XML_BUFFER_ALLOC_IMMUTABLE;
ret->content = (xmlChar *) mem;
ret->error = 0;
@@ -1159,8 +1150,7 @@ xmlBufFromBuffer(xmlBufferPtr buffer) {
}
ret->use = buffer->use;
ret->size = buffer->size;
- ret->compat_use = buffer->use;
- ret->compat_size = buffer->size;
+ UPDATE_COMPAT(ret);
ret->error = 0;
ret->buffer = buffer;
ret->alloc = buffer->alloc;
--
2.27.0

View File

@ -0,0 +1,60 @@
From 0aa8652e596a20e95ed334ac65cf15e6e9ec4b3b Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 20 May 2022 14:54:49 +0200
Subject: [PATCH 291/300] Use xmlNewDocText in xmlXIncludeCopyRange
Otherwise, the initial node of the copy could be a text node with a
NULL document. This results in the NULL document being propagated to
copies of other nodes, losing information about the dictionary in which
node data is stored, and freeing a dict-allocated string.
See discussion in !175.
Reference:https://github.com/GNOME/libxml2/commit/0aa8652e596a20e95ed334ac65cf15e6e9ec4b3b
Conflict:NA
---
xinclude.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/xinclude.c b/xinclude.c
index e5fdf0f..8c14a68 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -987,7 +987,7 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
int len;
if (content == NULL) {
- tmp = xmlNewTextLen(NULL, 0);
+ tmp = xmlNewDocTextLen(target, NULL, 0);
} else {
len = index2;
if ((cur == start) && (index1 > 1)) {
@@ -996,7 +996,7 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
} else {
len = index2;
}
- tmp = xmlNewTextLen(content, len);
+ tmp = xmlNewDocTextLen(target, content, len);
}
/* single sub text node selection */
if (list == NULL)
@@ -1047,13 +1047,13 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
const xmlChar *content = cur->content;
if (content == NULL) {
- tmp = xmlNewTextLen(NULL, 0);
+ tmp = xmlNewDocTextLen(target, NULL, 0);
} else {
if (index1 > 1) {
content += (index1 - 1);
index1 = 0;
}
- tmp = xmlNewText(content);
+ tmp = xmlNewDocText(target, content);
}
last = list = tmp;
listParent = cur->parent;
--
2.27.0

View File

@ -0,0 +1,56 @@
From 5b2d07a72670513e41b481a9d922c983a64027ca Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 20 Aug 2022 17:00:50 +0200
Subject: [PATCH] Use xmlStrlen in *CtxtReadDoc
xmlStrlen handles buffers larger than INT_MAX more gracefully.
Reference:https://github.com/GNOME/libxml2/commit/5b2d07a72670513e41b481a9d922c983a64027ca
Conflict:NA
---
HTMLparser.c | 7 ++-----
parser.c | 6 ++----
2 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index a4168f3..e0b32fe 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -7087,13 +7087,10 @@ htmlDocPtr
htmlCtxtReadDoc(htmlParserCtxtPtr ctxt, const xmlChar * cur,
const char *URL, const char *encoding, int options)
{
- const char *buf;
-
if (cur == NULL)
return (NULL);
- buf = (const char *) cur;
- return (htmlCtxtReadMemory(ctxt, buf, strlen(buf), URL, encoding,
- options));
+ return (htmlCtxtReadMemory(ctxt, (const char *) cur, xmlStrlen(cur), URL,
+ encoding, options));
}
/**
diff --git a/parser.c b/parser.c
index fbeb7af..23b031d 100644
--- a/parser.c
+++ b/parser.c
@@ -15374,12 +15374,10 @@ xmlDocPtr
xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
const char *URL, const char *encoding, int options)
{
- const char *buf;
-
if (cur == NULL)
return (NULL);
- buf = (const char *) cur;
- return (xmlCtxtReadMemory(ctxt, buf, strlen(buf), URL, encoding, options));
+ return (xmlCtxtReadMemory(ctxt, (const char *) cur, xmlStrlen(cur), URL,
+ encoding, options));
}
/**
--
2.27.0

View File

@ -0,0 +1,29 @@
From c21e9cd5d955e4d8afa514e1f7736ce6a9bb8f2e Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 20 Aug 2022 17:02:02 +0200
Subject: [PATCH] Use xmlStrlen in xmlNewStringInputStream
xmlStrlen handles buffers larger than INT_MAX more gracefully.
Reference:https://github.com/GNOME/libxml2/commit/c21e9cd5d955e4d8afa514e1f7736ce6a9bb8f2e
Conflict:NA
---
parserInternals.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/parserInternals.c b/parserInternals.c
index 6ef7671..2b05dac 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -1476,7 +1476,7 @@ xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
xmlGenericError(xmlGenericErrorContext,
"new fixed input: %.30s\n", buffer);
buf = xmlParserInputBufferCreateMem((const char *) buffer,
- strlen((const char *) buffer),
+ xmlStrlen(buffer),
XML_CHAR_ENCODING_NONE);
if (buf == NULL) {
xmlErrMemory(ctxt, NULL);
--
2.27.0

View File

@ -0,0 +1,31 @@
From f8c5e7fb75cd741fb576ddb4de8fcd61f9907549 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 22 Jan 2023 13:49:19 +0100
Subject: [PATCH] buf: Fix return value of xmlBufGetInputBase
Don't return (size_t) -1 in error case.
Found with libFuzzer and -fsanitize=implicit-conversion.
Reference:https://github.com/GNOME/libxml2/commit/f8c5e7fb75cd741fb576ddb4de8fcd61f9907549
Conflict:NA
---
buf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/buf.c b/buf.c
index 69370b7..d8992f7 100644
--- a/buf.c
+++ b/buf.c
@@ -1283,7 +1283,7 @@ xmlBufGetInputBase(xmlBufPtr buf, xmlParserInputPtr input) {
size_t base;
if ((input == NULL) || (buf == NULL) || (buf->error))
- return(-1);
+ return(0);
CHECK_COMPAT(buf)
base = input->base - buf->content;
/*
--
2.27.0

View File

@ -0,0 +1,48 @@
From c9e4c6d416d00968f2e2d7c68a9c0e809265baf2 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 21 Feb 2023 15:22:01 +0100
Subject: [PATCH] catalog: Fix memory leaks
Fixes #377.
Reference:https://github.com/GNOME/libxml2/commit/c9e4c6d416d00968f2e2d7c68a9c0e809265baf2
Conflict:catalog.c xmlcatalog.c
---
catalog.c | 2 +-
xmlcatalog.c | 6 ++----
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/catalog.c b/catalog.c
index b3a97da..4d84a6a 100644
--- a/catalog.c
+++ b/catalog.c
@@ -2983,7 +2983,7 @@ xmlACatalogAdd(xmlCatalogPtr catal, const xmlChar * type,
if (catal->sgml == NULL)
catal->sgml = xmlHashCreate(10);
res = xmlHashAddEntry(catal->sgml, orig, entry);
- if (res)
+ if (res < 0)
xmlFreeCatalogEntry(entry, NULL);
}
}
diff --git a/xmlcatalog.c b/xmlcatalog.c
index 7fe25ac..c7a1dc8 100644
--- a/xmlcatalog.c
+++ b/xmlcatalog.c
@@ -513,10 +513,8 @@ int main(int argc, char **argv) {
}
i += 2;
/* Check for memory leaks */
- if (catal != NULL)
- xmlFreeCatalog(catal);
- if (super != NULL)
- xmlFreeCatalog(super);
+ xmlFreeCatalog(catal);
+ xmlFreeCatalog(super);
} else {
if ((!strcmp(argv[i], "-add")) ||
(!strcmp(argv[i], "--add"))) {
--
2.27.0

View File

@ -0,0 +1,68 @@
From 3cc900f0989908f50d5544f00ede0f0236c4f350 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 Feb 2023 11:50:52 +0100
Subject: [PATCH] encoding: Cast toupper argument to unsigned char
Fixes undefined behavior.
Also cast return value explicitly to fix implicit-integer-sign-change
checks.
Reference:https://github.com/GNOME/libxml2/commit/3cc900f0989908f50d5544f00ede0f0236c4f350
Conflict:NA
---
encoding.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/encoding.c b/encoding.c
index 8b98f7d..d43361a 100644
--- a/encoding.c
+++ b/encoding.c
@@ -1038,7 +1038,7 @@ xmlGetEncodingAlias(const char *alias) {
return(NULL);
for (i = 0;i < 99;i++) {
- upper[i] = toupper(alias[i]);
+ upper[i] = (char) toupper((unsigned char) alias[i]);
if (upper[i] == 0) break;
}
upper[i] = 0;
@@ -1073,7 +1073,7 @@ xmlAddEncodingAlias(const char *name, const char *alias) {
return(-1);
for (i = 0;i < 99;i++) {
- upper[i] = toupper(alias[i]);
+ upper[i] = (char) toupper((unsigned char) alias[i]);
if (upper[i] == 0) break;
}
upper[i] = 0;
@@ -1175,7 +1175,7 @@ xmlParseCharEncoding(const char* name)
name = alias;
for (i = 0;i < 499;i++) {
- upper[i] = toupper(name[i]);
+ upper[i] = (char) toupper((unsigned char) name[i]);
if (upper[i] == 0) break;
}
upper[i] = 0;
@@ -1351,7 +1351,7 @@ xmlNewCharEncodingHandler(const char *name,
return(NULL);
}
for (i = 0;i < 499;i++) {
- upper[i] = toupper(name[i]);
+ upper[i] = (char) toupper((unsigned char) name[i]);
if (upper[i] == 0) break;
}
upper[i] = 0;
@@ -1689,7 +1689,7 @@ xmlFindCharEncodingHandler(const char *name) {
* Check first for directly registered encoding names
*/
for (i = 0;i < 99;i++) {
- upper[i] = toupper(name[i]);
+ upper[i] = (char) toupper((unsigned char) name[i]);
if (upper[i] == 0) break;
}
upper[i] = 0;
--
2.27.0

View File

@ -0,0 +1,32 @@
From a6b9e55a9eb78e96f880afaf03ce8819bcd26a34 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 26 Mar 2023 15:42:02 +0200
Subject: [PATCH] encoding: Fix error code in asciiToUTF8
Use correct error code when invalid ASCII bytes are encountered.
Found by OSS-Fuzz.
Reference:https://github.com/GNOME/libxml2/commit/a6b9e55a9eb78e96f880afaf03ce8819bcd26a34
Conflict:NA
---
encoding.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/encoding.c b/encoding.c
index d43361a..9a7a611 100644
--- a/encoding.c
+++ b/encoding.c
@@ -193,7 +193,7 @@ asciiToUTF8(unsigned char* out, int *outlen,
} else {
*outlen = out - outstart;
*inlen = processed - base;
- return(-1);
+ return(-2);
}
processed = (const unsigned char*) in;
--
2.27.0

View File

@ -0,0 +1,39 @@
From d9a8dab3a3ba980f1efc1366c1b9a3a2434dcabd Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 22 Jan 2023 12:00:59 +0100
Subject: [PATCH] error: Don't move past current position
Make sure that we never move past the current position in
xmlParserPrintFileContextInternal.
Found with libFuzzer and -fsanitize=implicit-conversion.
Reference:https://github.com/GNOME/libxml2/commit/d9a8dab3a3ba980f1efc1366c1b9a3a2434dcabd
Conflict:NA
---
error.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/error.c b/error.c
index fe9a7e2..5eee72a 100644
--- a/error.c
+++ b/error.c
@@ -188,10 +188,12 @@ xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
}
n = 0;
/* search backwards for beginning-of-line (to max buff size) */
- while ((n++ < (sizeof(content)-1)) && (cur > base) &&
- (*(cur) != '\n') && (*(cur) != '\r'))
+ while ((n < sizeof(content) - 1) && (cur > base) &&
+ (*cur != '\n') && (*cur != '\r')) {
cur--;
- if ((*(cur) == '\n') || (*(cur) == '\r')) {
+ n++;
+ }
+ if ((n > 0) && ((*cur == '\n') || (*cur == '\r'))) {
cur++;
} else {
/* skip over continuation bytes */
--
2.27.0

View File

@ -0,0 +1,78 @@
From 9a0aec423d158a9e3d8e5cb6df0d5ce032be3524 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 4 Dec 2022 23:01:00 +0100
Subject: [PATCH 28/28] error: Make sure that error messages are valid UTF-8
This has caused issues with the Python bindings for a long time.
Should fix #64.
Reference: https://github.com/GNOME/libxml2/commit/76c6da420923f2721a2e16adfcef8707a2454a1b
Conflict: result/,runtest.c,test/
---
error.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/error.c b/error.c
index 9ff1c2b..fe9a7e2 100644
--- a/error.c
+++ b/error.c
@@ -163,7 +163,7 @@ xmlParserPrintFileInfo(xmlParserInputPtr input) {
}
/**
- * xmlParserPrintFileContext:
+ * xmlParserPrintFileContextInternal:
* @input: an xmlParserInputPtr input
*
* Displays current context within the input content for error tracking
@@ -172,7 +172,7 @@ xmlParserPrintFileInfo(xmlParserInputPtr input) {
static void
xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
xmlGenericErrorFunc channel, void *data ) {
- const xmlChar *cur, *base;
+ const xmlChar *cur, *base, *start;
unsigned int n, col; /* GCC warns if signed, because compared with sizeof() */
xmlChar content[81]; /* space for 80 chars + line terminator */
xmlChar *ctnt;
@@ -191,19 +191,30 @@ xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
while ((n++ < (sizeof(content)-1)) && (cur > base) &&
(*(cur) != '\n') && (*(cur) != '\r'))
cur--;
- if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
+ if ((*(cur) == '\n') || (*(cur) == '\r')) {
+ cur++;
+ } else {
+ /* skip over continuation bytes */
+ while ((cur < input->cur) && ((*cur & 0xC0) == 0x80))
+ cur++;
+ }
/* calculate the error position in terms of the current position */
col = input->cur - cur;
/* search forward for end-of-line (to max buff size) */
n = 0;
- ctnt = content;
+ start = cur;
/* copy selected text to our buffer */
- while ((*cur != 0) && (*(cur) != '\n') &&
- (*(cur) != '\r') && (n < sizeof(content)-1)) {
- *ctnt++ = *cur++;
- n++;
+ while ((*cur != 0) && (*(cur) != '\n') && (*(cur) != '\r')) {
+ int len = input->end - cur;
+ int c = xmlGetUTF8Char(cur, &len);
+
+ if ((c < 0) || (n + len > sizeof(content)-1))
+ break;
+ cur += len;
+ n += len;
}
- *ctnt = 0;
+ memcpy(content, start, n);
+ content[n] = 0;
/* print out the selected text */
channel(data ,"%s\n", content);
/* create blank line with problem pointer */
--
2.27.0

View File

@ -0,0 +1,29 @@
From 74263eff5f6212afa2196022ecd2fbc39c6d3c36 Mon Sep 17 00:00:00 2001
From: jinsub ahn <jinniahn@gmail.com>
Date: Wed, 30 Mar 2022 06:02:31 +0000
Subject: [PATCH 206/300] fix: xmlXPathParserContext could be double-delete in
OOM case.
Reference:https://github.com/GNOME/libxml2/commit/74263eff5f6212afa2196022ecd2fbc39c6d3c36
Conflict:NA
---
xpath.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xpath.c b/xpath.c
index c2d8458..e79dcec 100644
--- a/xpath.c
+++ b/xpath.c
@@ -13895,7 +13895,7 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
if (ctxt->valueTab == NULL) {
xmlXPathPErrMemory(ctxt, "creating evaluation context\n");
- xmlFree(ctxt);
+ return(-1);
}
ctxt->valueNr = 0;
ctxt->valueMax = 10;
--
2.27.0

View File

@ -0,0 +1,36 @@
From 06a2c251a18d8cc93bcae82270997b27cbc9aaea Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 6 May 2023 15:28:13 +0200
Subject: [PATCH] hash: Fix possible startup crash with old libxslt versions
Call xmlInitParser in xmlHashCreate to make it work if the library
wasn't initialized yet.
Otherwise, exsltRegisterAll from libxslt 1.1.24 or older might cause
a crash.
See #534.
Reference:https://github.com/GNOME/libxml2/commit/06a2c251a18d8cc93bcae82270997b27cbc9aaea
Conflict:NA
---
hash.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hash.c b/hash.c
index 00250ba..ac868ff 100644
--- a/hash.c
+++ b/hash.c
@@ -181,6 +181,8 @@ xmlHashTablePtr
xmlHashCreate(int size) {
xmlHashTablePtr table;
+ xmlInitParser();
+
if (size <= 0)
size = 256;
--
2.27.0

View File

@ -0,0 +1,66 @@
From 63fa7b922a169ed6b86a4c6678140795c28657f5 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 20 Nov 2022 19:54:34 +0100
Subject: [PATCH 20/28] html: Fix check for end of comment in push parser
Make sure to reset checkIndex. Handle case where "--" or "--!" is at the
end of the buffer. Fix "avail" check in htmlParseOrTryFinish.
Reference: https://github.com/GNOME/libxml2/commit/c93679381c565f4c110c7a6110372bd6d0610308
Conflict: HTMLparser.c:<htmlParseLookupCommentEnd>,<htmlParseTryOrFinish>
---
HTMLparser.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index e0b32fe..746edf6 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -5405,14 +5405,22 @@ static int
htmlParseLookupCommentEnd(htmlParserCtxtPtr ctxt)
{
int mark = 0;
+ int offset;
int cur = CUR_PTR - BASE_PTR;
- while (mark >= 0) {
+ while (1) {
mark = htmlParseLookupSequence(ctxt, '-', '-', 0, 0);
- if ((mark < 0) ||
- (NXT(mark+2) == '>') ||
+ if (mark < 0)
+ break;
+ if ((NXT(mark+2) == '>') ||
((NXT(mark+2) == '!') && (NXT(mark+3) == '>'))) {
- return mark;
+ ctxt->checkIndex = 0;
+ break;
+ }
+ offset = (NXT(mark+2) == '!') ? 3 : 2;
+ if (mark + offset >= ctxt->input->end - ctxt->input->cur) {
+ ctxt->checkIndex = mark;
+ return(-1);
}
ctxt->checkIndex = cur + mark + 1;
}
@@ -5949,6 +5957,8 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
break;
}
} else {
+ if ((cur == '<') && (next == '!') && (avail < 4))
+ goto done;
/*
* Sometimes DOCTYPE arrives in the middle of the document
*/
@@ -5984,8 +5994,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
#endif
htmlParsePI(ctxt);
ctxt->instate = XML_PARSER_CONTENT;
- } else if ((cur == '<') && (next == '!') && (avail < 4)) {
- goto done;
} else if ((cur == '<') && (next == '/')) {
ctxt->instate = XML_PARSER_END_TAG;
ctxt->checkIndex = 0;
--
2.27.0

View File

@ -0,0 +1,39 @@
From 4b3452d17123631ec43d532b83dc182c1a638fed Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 15 Mar 2023 16:56:36 +0100
Subject: [PATCH] html: Fix quadratic behavior in htmlParseTryOrFinish
Fix check for end of script content.
Found by OSS-Fuzz.
Reference:https://github.com/GNOME/libxml2/commit/4b3452d17123631ec43d532b83dc182c1a638fed
Conflict:NA
---
HTMLparser.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index b76218c..6c8f180 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -5984,8 +5984,14 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
if (idx < 0)
goto done;
val = in->cur[idx + 2];
- if (val == 0) /* bad cut of input */
+ if (val == 0) { /* bad cut of input */
+ /*
+ * FIXME: htmlParseScript checks for additional
+ * characters after '</'.
+ */
+ ctxt->checkIndex = idx;
goto done;
+ }
}
htmlParseScript(ctxt);
if ((cur == '<') && (next == '/')) {
--
2.27.0

View File

@ -0,0 +1,40 @@
From 9feafbc5c5cce13852062a527d719ecce6b54661 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 13 Nov 2022 16:56:10 +0100
Subject: [PATCH] io: Check for memory buffer early in xmlParserInputGrow
Reference:https://github.com/GNOME/libxml2/commit/9feafbc5c5cce13852062a527d719ecce6b54661
Conflict:NA
---
parserInternals.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/parserInternals.c b/parserInternals.c
index b8eab4b..0ef44fe 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -310,6 +310,9 @@ xmlParserInputGrow(xmlParserInputPtr in, int len) {
if (in->cur == NULL) return(-1);
if (in->buf->buffer == NULL) return(-1);
+ /* Don't grow memory buffers. */
+ if (in->buf->readcallback == NULL) return(0);
+
CHECK_BUFFER(in);
indx = in->cur - in->base;
@@ -319,10 +322,7 @@ xmlParserInputGrow(xmlParserInputPtr in, int len) {
return(0);
}
- if (in->buf->readcallback != NULL) {
- ret = xmlParserInputBufferGrow(in->buf, len);
- } else
- return(0);
+ ret = xmlParserInputBufferGrow(in->buf, len);
in->base = xmlBufContent(in->buf->buffer);
in->cur = in->base + indx;
--
2.27.0

View File

@ -0,0 +1,36 @@
From cc645b439f54040b424bcb6c9b4c2c3f51cf2f9e Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 13 Nov 2022 15:08:44 +0100
Subject: [PATCH 14/28] io: Fix "buffer full" error with certain buffer sizes
Remove a useless check in xmlParserInputBufferGrow that could be
triggered after changing xmlBufAvail in c14cac8b.
Fixes #438.
Reference: https://github.com/GNOME/libxml2/commit/22d879bf0ab3ef14177a6388e28bb264bd36e64b
Conflict: NA
---
xmlIO.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/xmlIO.c b/xmlIO.c
index 3f5307f..0762034 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -3247,12 +3247,6 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
if ((len <= MINLEN) && (len != 4))
len = MINLEN;
- if (xmlBufAvail(in->buffer) <= 0) {
- xmlIOErr(XML_IO_BUFFER_FULL, NULL);
- in->error = XML_IO_BUFFER_FULL;
- return(-1);
- }
-
if (xmlBufGrow(in->buffer, len + 1) < 0) {
xmlIOErrMemory("growing input buffer");
in->error = XML_ERR_NO_MEMORY;
--
2.27.0

View File

@ -0,0 +1,114 @@
From ee6c6084e58ab114bddd06453790d22b08e45d93 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 13 Nov 2022 16:30:46 +0100
Subject: [PATCH] io: Remove xmlInputReadCallbackNop
In some cases, for example when using encoders, the read callback was
set to NULL, in other cases it was set to xmlInputReadCallbackNop.
xmlGROW only tested for xmlInputReadCallbackNop, resulting in errors
when parsing large encoded content from memory.
Always use a NULL callback for memory buffers to avoid ambiguities.
Fixes #262.
Reference:https://github.com/GNOME/libxml2/commit/46cd7d224ed5c4cdbd4f72ec899db24e18d21fe7
Conflict:include/private/io.h
---
parser.c | 2 +-
parserInternals.c | 3 ++-
xmlIO.c | 30 ++++--------------------------
3 files changed, 7 insertions(+), 28 deletions(-)
diff --git a/parser.c b/parser.c
index adc449c..f13287a 100644
--- a/parser.c
+++ b/parser.c
@@ -2134,7 +2134,7 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) {
if (((curEnd > XML_MAX_LOOKUP_LIMIT) ||
(curBase > XML_MAX_LOOKUP_LIMIT)) &&
((ctxt->input->buf) &&
- (ctxt->input->buf->readcallback != xmlInputReadCallbackNop)) &&
+ (ctxt->input->buf->readcallback != NULL)) &&
((ctxt->options & XML_PARSE_HUGE) == 0)) {
xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
xmlHaltParser(ctxt);
diff --git a/parserInternals.c b/parserInternals.c
index 0ef44fe..ef18ccf 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -311,7 +311,8 @@ xmlParserInputGrow(xmlParserInputPtr in, int len) {
if (in->buf->buffer == NULL) return(-1);
/* Don't grow memory buffers. */
- if (in->buf->readcallback == NULL) return(0);
+ if ((in->buf->encoder == NULL) && (in->buf->readcallback == NULL))
+ return(0);
CHECK_BUFFER(in);
diff --git a/xmlIO.c b/xmlIO.c
index 0762034..71c9fbf 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -729,20 +729,6 @@ xmlCheckFilename (const char *path)
return 1;
}
-/**
- * xmlInputReadCallbackNop:
- *
- * No Operation xmlInputReadCallback function, does nothing.
- *
- * Returns zero
- */
-int
-xmlInputReadCallbackNop(void *context ATTRIBUTE_UNUSED,
- char *buffer ATTRIBUTE_UNUSED,
- int len ATTRIBUTE_UNUSED) {
- return(0);
-}
-
/**
* xmlFdRead:
* @context: the I/O context
@@ -2963,7 +2949,7 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
ret = xmlAllocParserInputBuffer(enc);
if (ret != NULL) {
ret->context = (void *) mem;
- ret->readcallback = xmlInputReadCallbackNop;
+ ret->readcallback = NULL;
ret->closecallback = NULL;
errcode = xmlBufAdd(ret->buffer, (const xmlChar *) mem, size);
if (errcode != 0) {
@@ -3261,10 +3247,8 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
res = in->readcallback(in->context, &buffer[0], len);
if (res <= 0)
in->readcallback = endOfInput;
- } else {
- xmlIOErr(XML_IO_NO_INPUT, NULL);
- in->error = XML_IO_NO_INPUT;
- return(-1);
+ } else if (in->encoder == NULL) {
+ return(0);
}
if (res < 0) {
return(-1);
@@ -3331,13 +3315,7 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
*/
int
xmlParserInputBufferRead(xmlParserInputBufferPtr in, int len) {
- if ((in == NULL) || (in->error)) return(-1);
- if (in->readcallback != NULL)
- return(xmlParserInputBufferGrow(in, len));
- else if (xmlBufGetAllocationScheme(in->buffer) == XML_BUFFER_ALLOC_IMMUTABLE)
- return(0);
- else
- return(-1);
+ return(xmlParserInputBufferGrow(in, len));
}
#ifdef LIBXML_OUTPUT_ENABLED
--
2.27.0

View File

@ -0,0 +1,34 @@
From 62f199ed7d1c99999030810495bd12fd5b86fee1 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 17 Mar 2023 12:40:46 +0100
Subject: [PATCH] malloc-fail: Add error check in htmlParseHTMLAttribute
This function must return NULL is an error occurs.
Found by OSS-Fuzz, see #344.
Reference:https://github.com/GNOME/libxml2/commit/62f199ed7d1c99999030810495bd12fd5b86fee1
Conflict:NA
---
HTMLparser.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/HTMLparser.c b/HTMLparser.c
index 3682807..42d1b29 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -2846,6 +2846,10 @@ htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
out = &buffer[indx];
}
c = CUR_CHAR(l);
+ if (ctxt->instate == XML_PARSER_EOF) {
+ xmlFree(buffer);
+ return(NULL);
+ }
if (c < 0x80)
{ *out++ = c; bits= -6; }
else if (c < 0x800)
--
2.27.0

View File

@ -0,0 +1,30 @@
From 08695683dbd78301aa95bf3042871256479bc6a6 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 30 Jan 2023 15:52:00 +0100
Subject: [PATCH] malloc-fail: Add error check in xmlXPathEqualNodeSetFloat
Avoid null deref.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/08695683dbd78301aa95bf3042871256479bc6a6
Conflict:NA
---
xpath.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/xpath.c b/xpath.c
index 6d76e43..77d5434 100644
--- a/xpath.c
+++ b/xpath.c
@@ -6799,6 +6799,7 @@ xmlXPathEqualNodeSetFloat(xmlXPathParserContextPtr ctxt,
xmlFree(str2);
xmlXPathNumberFunction(ctxt, 1);
val = valuePop(ctxt);
+ CHECK_ERROR0;
v = val->floatval;
xmlXPathReleaseObject(ctxt->context, val);
if (!xmlXPathIsNaN(v)) {
--
2.27.0

View File

@ -0,0 +1,38 @@
From 7ec314efcd8b3df1d05d793812e54656bf539af8 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 30 Jan 2023 15:59:55 +0100
Subject: [PATCH] malloc-fail: Add error checks in xmlXPathEqualValuesCommon
Avoid null deref.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/7ec314efcd8b3df1d05d793812e54656bf539af8
Conflict:NA
---
xpath.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/xpath.c b/xpath.c
index fbec21b..6d76e43 100644
--- a/xpath.c
+++ b/xpath.c
@@ -7011,6 +7011,7 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
valuePush(ctxt, arg2);
xmlXPathNumberFunction(ctxt, 1);
arg2 = valuePop(ctxt);
+ CHECK_ERROR0;
/* Falls through. */
case XPATH_NUMBER:
/* Hand check NaN and Infinity equalities */
@@ -7074,6 +7075,7 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
valuePush(ctxt, arg1);
xmlXPathNumberFunction(ctxt, 1);
arg1 = valuePop(ctxt);
+ CHECK_ERROR0;
/* Hand check NaN and Infinity equalities */
if (xmlXPathIsNaN(arg1->floatval) ||
xmlXPathIsNaN(arg2->floatval)) {
--
2.27.0

View File

@ -0,0 +1,59 @@
From c81d0d04bfbdbccea0c5199bced95a6af961885a Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 17 Mar 2023 12:39:35 +0100
Subject: [PATCH] malloc-fail: Add more error checks when parsing names
xmlParseName and similar functions must return NULL if an error occurs.
Found by OSS-Fuzz, see #344.
Reference:https://github.com/GNOME/libxml2/commit/c81d0d04bfbdbccea0c5199bced95a6af961885a
Conflict:NA
---
parser.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/parser.c b/parser.c
index 75bd27f..b872d34 100644
--- a/parser.c
+++ b/parser.c
@@ -3355,6 +3355,8 @@ xmlParseName(xmlParserCtxtPtr ctxt) {
XML_MAX_NAME_LENGTH;
GROW;
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(NULL);
#ifdef DEBUG
nbParseName++;
@@ -3410,6 +3412,8 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
* Handler for more complex cases
*/
GROW;
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(NULL);
startPosition = CUR_PTR - BASE_PTR;
c = CUR_CHAR(l);
if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
@@ -3686,6 +3690,8 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
if (count++ > XML_PARSER_CHUNK_SIZE) {
count = 0;
GROW;
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(NULL);
}
COPY_BUF(l,buf,len,c);
NEXTL(l);
@@ -8791,6 +8797,8 @@ xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
const xmlChar *l, *p;
GROW;
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(NULL);
l = xmlParseNCName(ctxt);
if (l == NULL) {
--
2.27.0

View File

@ -0,0 +1,49 @@
From 1c5e1fc194a661783d4bffbfd4b4424a7d74881f Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 14 Feb 2023 13:56:21 +0100
Subject: [PATCH] malloc-fail: Check for malloc failure in
xmlFindCharEncodingHandler
Don't return encoding handlers with a NULL name.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/1c5e1fc194a661783d4bffbfd4b4424a7d74881f
Conflict:NA
---
encoding.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/encoding.c b/encoding.c
index c073a9c..400e860 100644
--- a/encoding.c
+++ b/encoding.c
@@ -1726,6 +1726,12 @@ xmlFindCharEncodingHandler(const char *name) {
}
memset(enc, 0, sizeof(xmlCharEncodingHandler));
enc->name = xmlMemStrdup(name);
+ if (enc->name == NULL) {
+ xmlFree(enc);
+ iconv_close(icv_in);
+ iconv_close(icv_out);
+ return(NULL);
+ }
enc->input = NULL;
enc->output = NULL;
enc->iconv_in = icv_in;
@@ -1758,6 +1764,12 @@ xmlFindCharEncodingHandler(const char *name) {
}
memset(encu, 0, sizeof(xmlCharEncodingHandler));
encu->name = xmlMemStrdup(name);
+ if (encu->name == NULL) {
+ xmlFree(encu);
+ closeIcuConverter(ucv_in);
+ closeIcuConverter(ucv_out);
+ return(NULL);
+ }
encu->input = NULL;
encu->output = NULL;
encu->uconv_in = ucv_in;
--
2.27.0

View File

@ -0,0 +1,102 @@
From 4499143a8737148b9be4e3c05e71bc60c5b52e4f Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 26 Feb 2023 15:43:50 +0100
Subject: [PATCH] malloc-fail: Check for malloc failure in xmlHashAddEntry
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/4499143a8737148b9be4e3c05e71bc60c5b52e4f
Conflict:NA
---
hash.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 50 insertions(+), 4 deletions(-)
diff --git a/hash.c b/hash.c
index 7b82d2f..00250ba 100644
--- a/hash.c
+++ b/hash.c
@@ -614,8 +614,24 @@ xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
entry->name3 = (xmlChar *) name3;
} else {
entry->name = xmlStrdup(name);
- entry->name2 = xmlStrdup(name2);
- entry->name3 = xmlStrdup(name3);
+ if (entry->name == NULL) {
+ entry->name2 = NULL;
+ goto error;
+ }
+ if (name2 == NULL) {
+ entry->name2 = NULL;
+ } else {
+ entry->name2 = xmlStrdup(name2);
+ if (entry->name2 == NULL)
+ goto error;
+ }
+ if (name3 == NULL) {
+ entry->name3 = NULL;
+ } else {
+ entry->name3 = xmlStrdup(name3);
+ if (entry->name3 == NULL)
+ goto error;
+ }
}
entry->payload = userdata;
entry->next = NULL;
@@ -631,6 +647,13 @@ xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
xmlHashGrow(table, MAX_HASH_LEN * table->size);
return(0);
+
+error:
+ xmlFree(entry->name2);
+ xmlFree(entry->name);
+ if (insert != NULL)
+ xmlFree(entry);
+ return(-1);
}
/**
@@ -744,8 +767,24 @@ xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
entry->name3 = (xmlChar *) name3;
} else {
entry->name = xmlStrdup(name);
- entry->name2 = xmlStrdup(name2);
- entry->name3 = xmlStrdup(name3);
+ if (entry->name == NULL) {
+ entry->name2 = NULL;
+ goto error;
+ }
+ if (name2 == NULL) {
+ entry->name2 = NULL;
+ } else {
+ entry->name2 = xmlStrdup(name2);
+ if (entry->name2 == NULL)
+ goto error;
+ }
+ if (name3 == NULL) {
+ entry->name3 = NULL;
+ } else {
+ entry->name3 = xmlStrdup(name3);
+ if (entry->name3 == NULL)
+ goto error;
+ }
}
entry->payload = userdata;
entry->next = NULL;
@@ -757,6 +796,13 @@ xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
insert->next = entry;
}
return(0);
+
+error:
+ xmlFree(entry->name2);
+ xmlFree(entry->name);
+ if (insert != NULL)
+ xmlFree(entry);
+ return(-1);
}
/**
--
2.27.0

View File

@ -0,0 +1,210 @@
From b1319c902f6e44d08f8cb33f1fc28847f2bc8aeb Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 18 Mar 2023 16:34:01 +0100
Subject: [PATCH] malloc-fail: Check for malloc failures when creating XPath
strings
Prevent null derefs.
Found by OSS-Fuzz, see #344.
Reference:https://github.com/GNOME/libxml2/commit/b1319c902f6e44d08f8cb33f1fc28847f2bc8aeb
Conflict:xpath.c
---
xpath.c | 111 +++++++++++++++++++++-----------------------------------
1 file changed, 42 insertions(+), 69 deletions(-)
diff --git a/xpath.c b/xpath.c
index 005a6a2..2eceb5b 100644
--- a/xpath.c
+++ b/xpath.c
@@ -2476,17 +2476,17 @@ xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
}
/**
- * xmlXPathCacheNewCString:
+ * xmlXPathCacheNewString:
* @ctxt: the XPath context
- * @val: the char * value
+ * @val: the xmlChar * value
*
- * This is the cached version of xmlXPathNewCString().
+ * This is the cached version of xmlXPathNewString().
* Acquire an xmlXPathObjectPtr of type string and of value @val
*
* Returns the created or reused object.
*/
static xmlXPathObjectPtr
-xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
+xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
{
if ((ctxt != NULL) && (ctxt->cache)) {
xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
@@ -2495,12 +2495,20 @@ xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
(cache->stringObjs->number != 0))
{
xmlXPathObjectPtr ret;
+ xmlChar *copy;
+
+ if (val == NULL)
+ val = BAD_CAST "";
+ copy = xmlStrdup(val);
+ if (copy == NULL) {
+ xmlXPathErrMemory(ctxt, NULL);
+ return(NULL);
+ }
ret = (xmlXPathObjectPtr)
cache->stringObjs->items[--cache->stringObjs->number];
-
ret->type = XPATH_STRING;
- ret->stringval = xmlStrdup(BAD_CAST val);
+ ret->stringval = copy;
#ifdef XP_DEBUG_OBJ_USAGE
xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
#endif
@@ -2509,73 +2517,44 @@ xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
(cache->miscObjs->number != 0))
{
xmlXPathObjectPtr ret;
+ xmlChar *copy;
+
+ if (val == NULL)
+ val = BAD_CAST "";
+ copy = xmlStrdup(val);
+ if (copy == NULL) {
+ xmlXPathErrMemory(ctxt, NULL);
+ return(NULL);
+ }
ret = (xmlXPathObjectPtr)
cache->miscObjs->items[--cache->miscObjs->number];
ret->type = XPATH_STRING;
- ret->stringval = xmlStrdup(BAD_CAST val);
+ ret->stringval = copy;
#ifdef XP_DEBUG_OBJ_USAGE
xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
#endif
return(ret);
}
}
- return(xmlXPathNewCString(val));
+ return(xmlXPathNewString(val));
}
/**
- * xmlXPathCacheNewString:
+ * xmlXPathCacheNewCString:
* @ctxt: the XPath context
- * @val: the xmlChar * value
+ * @val: the char * value
*
- * This is the cached version of xmlXPathNewString().
+ * This is the cached version of xmlXPathNewCString().
* Acquire an xmlXPathObjectPtr of type string and of value @val
*
* Returns the created or reused object.
*/
static xmlXPathObjectPtr
-xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
+xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
{
- if ((ctxt != NULL) && (ctxt->cache)) {
- xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
-
- if ((cache->stringObjs != NULL) &&
- (cache->stringObjs->number != 0))
- {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr)
- cache->stringObjs->items[--cache->stringObjs->number];
- ret->type = XPATH_STRING;
- if (val != NULL)
- ret->stringval = xmlStrdup(val);
- else
- ret->stringval = xmlStrdup((const xmlChar *)"");
-#ifdef XP_DEBUG_OBJ_USAGE
- xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
-#endif
- return(ret);
- } else if ((cache->miscObjs != NULL) &&
- (cache->miscObjs->number != 0))
- {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr)
- cache->miscObjs->items[--cache->miscObjs->number];
-
- ret->type = XPATH_STRING;
- if (val != NULL)
- ret->stringval = xmlStrdup(val);
- else
- ret->stringval = xmlStrdup((const xmlChar *)"");
-#ifdef XP_DEBUG_OBJ_USAGE
- xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
-#endif
- return(ret);
- }
- }
- return(xmlXPathNewString(val));
+ return xmlXPathCacheNewString(ctxt, BAD_CAST val);
}
/**
@@ -5291,10 +5270,13 @@ xmlXPathNewString(const xmlChar *val) {
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
ret->type = XPATH_STRING;
- if (val != NULL)
- ret->stringval = xmlStrdup(val);
- else
- ret->stringval = xmlStrdup((const xmlChar *)"");
+ if (val == NULL)
+ val = BAD_CAST "";
+ ret->stringval = xmlStrdup(val);
+ if (ret->stringval == NULL) {
+ xmlFree(ret);
+ return(NULL);
+ }
#ifdef XP_DEBUG_OBJ_USAGE
xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
#endif
@@ -5340,20 +5322,7 @@ xmlXPathWrapString (xmlChar *val) {
*/
xmlXPathObjectPtr
xmlXPathNewCString(const char *val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlXPathErrMemory(NULL, "creating string object\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_STRING;
- ret->stringval = xmlStrdup(BAD_CAST val);
-#ifdef XP_DEBUG_OBJ_USAGE
- xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
-#endif
- return(ret);
+ return(xmlXPathNewString(BAD_CAST val));
}
/**
@@ -5427,6 +5396,10 @@ xmlXPathObjectCopy(xmlXPathObjectPtr val) {
break;
case XPATH_STRING:
ret->stringval = xmlStrdup(val->stringval);
+ if (ret->stringval == NULL) {
+ xmlFree(ret);
+ return(NULL);
+ }
break;
case XPATH_XSLT_TREE:
#if 0
--
2.27.0

View File

@ -0,0 +1,106 @@
From 0e4421e793e52e2025297f9252c4dc76b72674c7 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 30 Jan 2023 15:05:58 +0100
Subject: [PATCH] malloc-fail: Check return value of xmlXPathNodeSetDupNs
Avoid null deref if allocation fails.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/0e4421e793e52e2025297f9252c4dc76b72674c7
Conflict:NA
---
xpath.c | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/xpath.c b/xpath.c
index fe0e1e2..212a4e0 100644
--- a/xpath.c
+++ b/xpath.c
@@ -3588,10 +3588,13 @@ xmlXPathNodeSetCreate(xmlNodePtr val) {
ret->nodeMax = XML_NODESET_DEFAULT;
if (val->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) val;
+ xmlNodePtr nsNode = xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
- /* TODO: Check memory error. */
- ret->nodeTab[ret->nodeNr++] =
- xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+ if (nsNode == NULL) {
+ xmlXPathFreeNodeSet(ret);
+ return(NULL);
+ }
+ ret->nodeTab[ret->nodeNr++] = nsNode;
} else
ret->nodeTab[ret->nodeNr++] = val;
}
@@ -3648,7 +3651,7 @@ xmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) {
int
xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
int i;
-
+ xmlNodePtr nsNode;
if ((cur == NULL) || (ns == NULL) || (node == NULL) ||
(ns->type != XML_NAMESPACE_DECL) ||
@@ -3696,8 +3699,10 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
cur->nodeMax *= 2;
cur->nodeTab = temp;
}
- /* TODO: Check memory error. */
- cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
+ nsNode = xmlXPathNodeSetDupNs(node, ns);
+ if(nsNode == NULL)
+ return(-1);
+ cur->nodeTab[cur->nodeNr++] = nsNode;
return(0);
}
@@ -3754,10 +3759,11 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
}
if (val->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) val;
+ xmlNodePtr nsNode = xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
- /* TODO: Check memory error. */
- cur->nodeTab[cur->nodeNr++] =
- xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+ if (nsNode == NULL)
+ return(-1);
+ cur->nodeTab[cur->nodeNr++] = nsNode;
} else
cur->nodeTab[cur->nodeNr++] = val;
return(0);
@@ -3809,10 +3815,11 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
}
if (val->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) val;
+ xmlNodePtr nsNode = xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
- /* TODO: Check memory error. */
- cur->nodeTab[cur->nodeNr++] =
- xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+ if (nsNode == NULL)
+ return(-1);
+ cur->nodeTab[cur->nodeNr++] = nsNode;
} else
cur->nodeTab[cur->nodeNr++] = val;
return(0);
@@ -3926,10 +3933,11 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
}
if (n2->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) n2;
+ xmlNodePtr nsNode = xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
- /* TODO: Check memory error. */
- val1->nodeTab[val1->nodeNr++] =
- xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+ if (nsNode == NULL)
+ return(NULL);
+ val1->nodeTab[val1->nodeNr++] = nsNode;
} else
val1->nodeTab[val1->nodeNr++] = n2;
}
--
2.27.0

View File

@ -0,0 +1,66 @@
From c7260a47f19e01f4f663b6a56fbdc2dafd8a6e7e Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 23 Jan 2023 10:19:59 +0100
Subject: [PATCH] malloc-fail: Don't call xmlErrMemory in xmlstring.c
Functions like xmlStrdup are called in the error handling code
(__xmlRaiseError) which can cause problems like use-after-free or
infinite loops when invoked recursively.
Calling xmlErrMemory without a context argument isn't helpful anyway.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/c7260a47f19e01f4f663b6a56fbdc2dafd8a6e7e
Conflict:xmlstring.c
---
xmlstring.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/xmlstring.c b/xmlstring.c
index 5a6875f..9709545 100644
--- a/xmlstring.c
+++ b/xmlstring.c
@@ -45,7 +45,6 @@ xmlStrndup(const xmlChar *cur, int len) {
if ((cur == NULL) || (len < 0)) return(NULL);
ret = (xmlChar *) xmlMallocAtomic(((size_t) len + 1) * sizeof(xmlChar));
if (ret == NULL) {
- xmlErrMemory(NULL, NULL);
return(NULL);
}
memcpy(ret, cur, len * sizeof(xmlChar));
@@ -90,7 +89,6 @@ xmlCharStrndup(const char *cur, int len) {
if ((cur == NULL) || (len < 0)) return(NULL);
ret = (xmlChar *) xmlMallocAtomic(((size_t) len + 1) * sizeof(xmlChar));
if (ret == NULL) {
- xmlErrMemory(NULL, NULL);
return(NULL);
}
for (i = 0;i < len;i++) {
@@ -465,7 +463,6 @@ xmlStrncat(xmlChar *cur, const xmlChar *add, int len) {
return(NULL);
ret = (xmlChar *) xmlRealloc(cur, ((size_t) size + len + 1) * sizeof(xmlChar));
if (ret == NULL) {
- xmlErrMemory(NULL, NULL);
return(cur);
}
memcpy(&ret[size], add, len * sizeof(xmlChar));
@@ -505,7 +502,6 @@ xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len) {
return(NULL);
ret = (xmlChar *) xmlMalloc(((size_t) size + len + 1) * sizeof(xmlChar));
if (ret == NULL) {
- xmlErrMemory(NULL, NULL);
return(xmlStrndup(str1, size));
}
memcpy(ret, str1, size * sizeof(xmlChar));
@@ -1034,7 +1030,6 @@ xmlEscapeFormatString(xmlChar **msg)
out-of-memory situations. */
xmlFree(*msg);
*msg = NULL;
- xmlErrMemory(NULL, NULL);
return(NULL);
}
--
2.27.0

View File

@ -0,0 +1,75 @@
From d08fd8306e224c48dedc1a9b549376ae1d4c7f6c Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 17 Feb 2023 15:53:07 +0100
Subject: [PATCH] malloc-fail: Fix OOB read after xmlRegGetCounter
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/1743c4c3fc58cf38ecce68db9de51d0f3651e033
Conflict:xmlregexp.c
---
xmlregexp.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/xmlregexp.c b/xmlregexp.c
index 360916f..e7c48a4 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -1681,6 +1681,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
}
inter = ctxt->state;
counter = xmlRegGetCounter(ctxt);
+ if (counter < 0)
+ return(-1);
ctxt->counters[counter].min = atom->min - 1;
ctxt->counters[counter].max = atom->max - 1;
/* count the number of times we see it again */
@@ -1699,6 +1701,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
* epsilon transition.
*/
counter = xmlRegGetCounter(ctxt);
+ if (counter < 0)
+ return(-1);
ctxt->counters[counter].min = atom->min - 1;
ctxt->counters[counter].max = atom->max - 1;
/* allow a way out based on the count */
@@ -6025,6 +6029,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
* associate a counter to the transition.
*/
counter = xmlRegGetCounter(am);
+ if (counter < 0)
+ goto error;
am->counters[counter].min = min;
am->counters[counter].max = max;
@@ -6099,6 +6105,8 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
* associate a counter to the transition.
*/
counter = xmlRegGetCounter(am);
+ if (counter < 0)
+ goto error;
am->counters[counter].min = min;
am->counters[counter].max = max;
@@ -6191,6 +6199,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
* associate a counter to the transition.
*/
counter = xmlRegGetCounter(am);
+ if (counter < 0)
+ goto error;
am->counters[counter].min = 1;
am->counters[counter].max = 1;
@@ -6256,6 +6266,8 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
* associate a counter to the transition.
*/
counter = xmlRegGetCounter(am);
+ if (counter < 0)
+ goto error;
am->counters[counter].min = 1;
am->counters[counter].max = 1;
--
2.27.0

View File

@ -0,0 +1,32 @@
From 260d6b8d77d11a20a2614eef99e88e68eaca6550 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 5 Mar 2023 14:10:26 +0100
Subject: [PATCH] malloc-fail: Fix another memory leak in xmlSchemaBucketCreate
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/260d6b8d77d11a20a2614eef99e88e68eaca6550
Conflict:NA
---
xmlschemas.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/xmlschemas.c b/xmlschemas.c
index fa9d113..06bf664 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -3742,7 +3742,10 @@ xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
return(NULL);
}
}
- xmlSchemaItemListAdd(mainSchema->includes, ret);
+ if (xmlSchemaItemListAdd(mainSchema->includes, ret) < 0) {
+ xmlSchemaBucketFree(ret);
+ return(NULL);
+ }
}
/*
* Add to list of all buckets; this is used for lookup
--
2.27.0

View File

@ -0,0 +1,37 @@
From 44ecefc8cc299a66ac21ffec141eb261e92638da Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 20 Mar 2023 15:52:38 +0100
Subject: [PATCH] malloc-fail: Fix buffer overread after htmlParseScript
Found by OSS-Fuzz, see #344.
Reference:https://github.com/GNOME/libxml2/commit/44ecefc8cc299a66ac21ffec141eb261e92638da
Conflict:HTMLparser.c
---
HTMLparser.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index 0cc9824..4f1a3d8 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -3137,6 +3137,7 @@ htmlParseScript(htmlParserCtxtPtr ctxt) {
htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
"Invalid char in CDATA 0x%X\n", cur);
}
+ NEXTL(l);
if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
buf[nbchar] = 0;
if (ctxt->sax->cdataBlock!= NULL) {
@@ -3149,7 +3150,6 @@ htmlParseScript(htmlParserCtxtPtr ctxt) {
}
nbchar = 0;
}
- NEXTL(l);
GROW;
cur = CUR_CHAR(l);
}
--
2.27.0

View File

@ -0,0 +1,31 @@
From 8090e5856465c0b8e26e2a080f4b498f37fa83ab Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 17 Mar 2023 12:27:07 +0100
Subject: [PATCH] malloc-fail: Fix buffer overread in htmlParseScript
Found by OSS-Fuzz, see #344.
Reference:https://github.com/GNOME/libxml2/commit/8090e5856465c0b8e26e2a080f4b498f37fa83ab
Conflict:NA
---
HTMLparser.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index 6c8f180..3682807 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -3145,8 +3145,8 @@ htmlParseScript(htmlParserCtxtPtr ctxt) {
}
nbchar = 0;
}
- GROW;
NEXTL(l);
+ GROW;
cur = CUR_CHAR(l);
}
--
2.27.0

View File

@ -0,0 +1,44 @@
From 1061537efdf3874c91fd50d18f98c4b8a3518e52 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 26 Mar 2023 22:40:54 +0200
Subject: [PATCH] malloc-fail: Fix buffer overread with HTML doctype
declarations
Found by OSS-Fuzz, see #344.
Reference:https://github.com/GNOME/libxml2/commit/1061537efdf3874c91fd50d18f98c4b8a3518e52
Conflict:NA
---
HTMLparser.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index 42d1b29..5e4f289 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -3008,9 +3008,9 @@ htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
"Unfinished SystemLiteral\n", NULL, NULL);
} else {
- NEXT;
if (err == 0)
ret = xmlStrndup((BASE_PTR+startPosition), len);
+ NEXT;
}
return(ret);
@@ -3063,9 +3063,9 @@ htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
"Unfinished PubidLiteral\n", NULL, NULL);
} else {
- NEXT;
if (err == 0)
ret = xmlStrndup((BASE_PTR + startPosition), len);
+ NEXT;
}
return(ret);
--
2.27.0

View File

@ -0,0 +1,46 @@
From 621c222efe87946ad8e53f59e28c782979d340c8 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 30 Jan 2023 15:48:11 +0100
Subject: [PATCH] malloc-fail: Fix error check in xmlXPathCompareValues
Avoid null deref.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/621c222efe87946ad8e53f59e28c782979d340c8
Conflict:NA
---
xpath.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/xpath.c b/xpath.c
index 77d5434..fcbc7e3 100644
--- a/xpath.c
+++ b/xpath.c
@@ -7367,21 +7367,13 @@ xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
valuePush(ctxt, arg1);
xmlXPathNumberFunction(ctxt, 1);
arg1 = valuePop(ctxt);
- }
- if (arg1->type != XPATH_NUMBER) {
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- XP_ERROR0(XPATH_INVALID_OPERAND);
+ CHECK_ERROR0;
}
if (arg2->type != XPATH_NUMBER) {
valuePush(ctxt, arg2);
xmlXPathNumberFunction(ctxt, 1);
arg2 = valuePop(ctxt);
- }
- if (arg2->type != XPATH_NUMBER) {
- xmlXPathReleaseObject(ctxt->context, arg1);
- xmlXPathReleaseObject(ctxt->context, arg2);
- XP_ERROR0(XPATH_INVALID_OPERAND);
+ CHECK_ERROR0;
}
/*
* Add tests for infinity and nan
--
2.27.0

View File

@ -0,0 +1,32 @@
From 53d1cc98cf08c789087a92fd57da70811abe7d60 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 Feb 2023 15:09:32 +0100
Subject: [PATCH] malloc-fail: Fix error code in htmlParseChunk
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/53d1cc98cf08c789087a92fd57da70811abe7d60
Conflict:NA
---
HTMLparser.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index 457b2a3..72ede56 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -6276,9 +6276,8 @@ htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
if (res < 0) {
- ctxt->errNo = XML_PARSER_EOF;
- ctxt->disableSAX = 1;
- return (XML_PARSER_EOF);
+ htmlErrMemory(ctxt, NULL);
+ return (ctxt->errNo);
}
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
--
2.27.0

View File

@ -0,0 +1,90 @@
From 04c2955197b53eb106037bc1d422bb80b39abbf6 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 Feb 2023 14:53:29 +0100
Subject: [PATCH] malloc-fail: Fix infinite loop in htmlParseContentInternal
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/04c2955197b53eb106037bc1d422bb80b39abbf6
Conflict:NA
---
HTMLparser.c | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index 5272c25..f90053a 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -4718,8 +4718,16 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
int depth;
const xmlChar *name;
- currentNode = xmlStrdup(ctxt->name);
depth = ctxt->nameNr;
+ if (depth <= 0) {
+ currentNode = NULL;
+ } else {
+ currentNode = xmlStrdup(ctxt->name);
+ if (currentNode == NULL) {
+ htmlErrMemory(ctxt, NULL);
+ return;
+ }
+ }
while (1) {
GROW;
@@ -4735,8 +4743,16 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
if (currentNode != NULL)
xmlFree(currentNode);
- currentNode = xmlStrdup(ctxt->name);
depth = ctxt->nameNr;
+ if (depth <= 0) {
+ currentNode = NULL;
+ } else {
+ currentNode = xmlStrdup(ctxt->name);
+ if (currentNode == NULL) {
+ htmlErrMemory(ctxt, NULL);
+ break;
+ }
+ }
}
continue; /* while */
}
@@ -4758,6 +4774,10 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
xmlFree(currentNode);
currentNode = xmlStrdup(ctxt->name);
+ if (currentNode == NULL) {
+ htmlErrMemory(ctxt, NULL);
+ break;
+ }
depth = ctxt->nameNr;
continue;
}
@@ -4781,6 +4801,10 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
if (currentNode != NULL) xmlFree(currentNode);
currentNode = xmlStrdup(ctxt->name);
+ if (currentNode == NULL) {
+ htmlErrMemory(ctxt, NULL);
+ break;
+ }
depth = ctxt->nameNr;
continue;
}
@@ -4829,6 +4853,10 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
if (currentNode != NULL) xmlFree(currentNode);
currentNode = xmlStrdup(ctxt->name);
+ if (currentNode == NULL) {
+ htmlErrMemory(ctxt, NULL);
+ break;
+ }
depth = ctxt->nameNr;
}
else if (CUR == '<') {
--
2.27.0

View File

@ -0,0 +1,31 @@
From 15b0ed0815d48ac48c7b95a28b8332a298ed7072 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 Feb 2023 15:09:02 +0100
Subject: [PATCH] malloc-fail: Fix infinite loop in htmlParseDocTypeDecl
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/15b0ed0815d48ac48c7b95a28b8332a298ed7072
Conflict:NA
---
HTMLparser.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index e02a142..457b2a3 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -3695,7 +3695,8 @@ htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) {
htmlParseErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED,
"DOCTYPE improperly terminated\n", NULL, NULL);
/* Ignore bogus content */
- while ((CUR != 0) && (CUR != '>'))
+ while ((CUR != 0) && (CUR != '>') &&
+ (ctxt->instate != XML_PARSER_EOF))
NEXT;
}
if (CUR == '>')
--
2.27.0

View File

@ -0,0 +1,51 @@
From 643b4e90ebf619432b0287010b593edd8c0c0f8e Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 Feb 2023 14:45:06 +0100
Subject: [PATCH] malloc-fail: Fix infinite loop in htmlParseStartTag
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/643b4e90ebf619432b0287010b593edd8c0c0f8e
Conflict:NA
---
HTMLparser.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index 60dea30..0ccd6e8 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -2570,6 +2570,7 @@ static const xmlChar * htmlParseNameComplex(xmlParserCtxtPtr ctxt);
static const xmlChar *
htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
+ const xmlChar *ret;
int i = 0;
xmlChar loc[HTML_PARSER_BUFFER_SIZE];
@@ -2587,7 +2588,11 @@ htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
NEXT;
}
- return(xmlDictLookup(ctxt->dict, loc, i));
+ ret = xmlDictLookup(ctxt->dict, loc, i);
+ if (ret == NULL)
+ htmlErrMemory(ctxt, NULL);
+
+ return(ret);
}
@@ -4020,7 +4025,8 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
SKIP_BLANKS;
while ((CUR != 0) &&
(CUR != '>') &&
- ((CUR != '/') || (NXT(1) != '>'))) {
+ ((CUR != '/') || (NXT(1) != '>')) &&
+ (ctxt->instate != XML_PARSER_EOF)) {
GROW;
attname = htmlParseAttribute(ctxt, &attvalue);
if (attname != NULL) {
--
2.27.0

View File

@ -0,0 +1,30 @@
From 0ec9c91064a58ce2932498a55ae63a85f43975f5 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 Feb 2023 14:57:24 +0100
Subject: [PATCH] malloc-fail: Fix infinite loop in htmlParseStartTag
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/0ec9c91064a58ce2932498a55ae63a85f43975f5
Conflict:NA
---
HTMLparser.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index f90053a..ca551d9 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -4087,7 +4087,8 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
* the end of the tag. */
while ((CUR != 0) &&
!(IS_BLANK_CH(CUR)) && (CUR != '>') &&
- ((CUR != '/') || (NXT(1) != '>')))
+ ((CUR != '/') || (NXT(1) != '>')) &&
+ (ctxt->instate != XML_PARSER_EOF))
NEXT;
}
--
2.27.0

View File

@ -0,0 +1,32 @@
From d1b87856931797c5c527cee16d96e482a45b99ed Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 22 Jan 2023 17:42:09 +0100
Subject: [PATCH] malloc-fail: Fix infinite loop in xmlParseTextDecl
Memory errors can set `instate` to `XML_PARSER_EOF` which results in
`NEXT` making no progress.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/d1b87856931797c5c527cee16d96e482a45b99ed
Conflict:NA
---
parser.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/parser.c b/parser.c
index 9127deb..fafae15 100644
--- a/parser.c
+++ b/parser.c
@@ -6957,6 +6957,8 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
* We must have the encoding declaration
*/
encoding = xmlParseEncodingDecl(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return;
if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
/*
* The XML REC instructs us to stop parsing right here
--
2.27.0

View File

@ -0,0 +1,29 @@
From 71e81a4ce7946c43ca61124b142d86066590aeb0 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 2 Nov 2022 16:02:39 +0100
Subject: [PATCH 08/28] malloc-fail: Fix infinite loop in xmlSkipBlankChars
Found with libFuzzer, see #344.
Reference: https://github.com/GNOME/libxml2/commit/e129c1d1a27abdeaab44f4d59eb0cb5052df7c6f
Conflict: NA
---
parser.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/parser.c b/parser.c
index 443a216..780a8b3 100644
--- a/parser.c
+++ b/parser.c
@@ -2220,7 +2220,7 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
} else {
int expandPE = ((ctxt->external != 0) || (ctxt->inputNr != 1));
- while (1) {
+ while (ctxt->instate != XML_PARSER_EOF) {
if (IS_BLANK_CH(CUR)) { /* CHECKED tstblanks.xml */
NEXT;
} else if (CUR == '%') {
--
2.27.0

View File

@ -0,0 +1,31 @@
From d18f9c1102a45b401039dd899ce7069da7a73124 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 14 Feb 2023 13:50:46 +0100
Subject: [PATCH] malloc-fail: Fix leak of xmlCharEncodingHandler
Also free handler if its name is NULL.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/d18f9c1102a45b401039dd899ce7069da7a73124
Conflict:encoding.c
---
encoding.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/encoding.c b/encoding.c
index 400e860..8b98f7d 100644
--- a/encoding.c
+++ b/encoding.c
@@ -2792,7 +2792,6 @@ xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
int i, handler_in_list = 0;
if (handler == NULL) return(-1);
- if (handler->name == NULL) return(-1);
if (handlers != NULL) {
for (i = 0;i < nbCharEncodingHandler; i++) {
if (handler == handlers[i]) {
--
2.27.0

View File

@ -0,0 +1,241 @@
From e64653c0e7975594e27d7de2ed4be062c1e4ad03 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 17 Feb 2023 15:20:33 +0100
Subject: [PATCH] malloc-fail: Fix leak of xmlRegAtom
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/e64653c0e7975594e27d7de2ed4be062c1e4ad03
Conflict:NA
---
xmlregexp.c | 81 ++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 55 insertions(+), 26 deletions(-)
diff --git a/xmlregexp.c b/xmlregexp.c
index 8c2ea81..11c684a 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -1594,9 +1594,6 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
* this is a subexpression handling one should not need to
* create a new node except for XML_REGEXP_QUANT_RANGE.
*/
- if (xmlRegAtomPush(ctxt, atom) < 0) {
- return(-1);
- }
if ((to != NULL) && (atom->stop != to) &&
(atom->quant != XML_REGEXP_QUANT_RANGE)) {
/*
@@ -1678,8 +1675,10 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
copy->max = 0;
if (xmlFAGenerateTransitions(ctxt, atom->start, NULL, copy)
- < 0)
+ < 0) {
+ xmlRegFreeAtom(copy);
return(-1);
+ }
inter = ctxt->state;
counter = xmlRegGetCounter(ctxt);
ctxt->counters[counter].min = atom->min - 1;
@@ -1722,6 +1721,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
default:
break;
}
+ if (xmlRegAtomPush(ctxt, atom) < 0)
+ return(-1);
return(0);
}
if ((atom->min == 0) && (atom->max == 0) &&
@@ -1760,9 +1761,6 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
xmlFAGenerateEpsilonTransition(ctxt, tmp, to);
to = tmp;
}
- if (xmlRegAtomPush(ctxt, atom) < 0) {
- return(-1);
- }
if ((atom->quant == XML_REGEXP_QUANT_RANGE) &&
(atom->min == 0) && (atom->max > 0)) {
nullable = 1;
@@ -1793,6 +1791,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
default:
break;
}
+ if (xmlRegAtomPush(ctxt, atom) < 0)
+ return(-1);
return(0);
}
@@ -5447,8 +5447,12 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) {
xmlFAGenerateEpsilonTransition(ctxt, previous, to);
} else {
if (xmlFAGenerateTransitions(ctxt, previous,
- (CUR=='|' || CUR==')' || CUR==0) ? to : NULL, ctxt->atom) < 0)
+ (CUR=='|' || CUR==')' || CUR==0) ? to : NULL,
+ ctxt->atom) < 0) {
+ xmlRegFreeAtom(ctxt->atom);
+ ctxt->atom = NULL;
return(-1);
+ }
previous = ctxt->state;
ctxt->atom = NULL;
}
@@ -5457,8 +5461,11 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) {
if (ret != 0) {
if (xmlFAGenerateTransitions(ctxt, previous,
(CUR=='|' || CUR==')' || CUR==0) ? to : NULL,
- ctxt->atom) < 0)
- return(-1);
+ ctxt->atom) < 0) {
+ xmlRegFreeAtom(ctxt->atom);
+ ctxt->atom = NULL;
+ return(-1);
+ }
previous = ctxt->state;
ctxt->atom = NULL;
}
@@ -5990,6 +5997,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
return(NULL);
if ((token2 == NULL) || (*token2 == 0)) {
atom->valuep = xmlStrdup(token);
+ if (atom->valuep == NULL)
+ goto error;
} else {
int lenn, lenp;
xmlChar *str;
@@ -5998,10 +6007,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
lenp = strlen((char *) token);
str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
- if (str == NULL) {
- xmlRegFreeAtom(atom);
- return(NULL);
- }
+ if (str == NULL)
+ goto error;
memcpy(&str[0], token, lenp);
str[lenp] = '|';
memcpy(&str[lenp + 1], token2, lenn);
@@ -6027,10 +6034,11 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
if (to == NULL) {
to = xmlRegStatePush(am);
if (to == NULL)
- return(NULL);
+ goto error;
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
- xmlRegAtomPush(am, atom);
+ if (xmlRegAtomPush(am, atom) < 0)
+ goto error;
am->state = to;
if (to == NULL)
@@ -6040,6 +6048,10 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
if (min == 0)
xmlFAGenerateEpsilonTransition(am, from, to);
return(to);
+
+error:
+ xmlRegFreeAtom(atom);
+ return(NULL);
}
/**
@@ -6076,6 +6088,8 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
if (atom == NULL)
return(NULL);
atom->valuep = xmlStrdup(token);
+ if (atom->valuep == NULL)
+ goto error;
atom->data = data;
if (min == 0)
atom->min = 1;
@@ -6094,10 +6108,11 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
if (to == NULL) {
to = xmlRegStatePush(am);
if (to == NULL)
- return(NULL);
+ goto error;
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
- xmlRegAtomPush(am, atom);
+ if (xmlRegAtomPush(am, atom) < 0)
+ goto error;
am->state = to;
if (to == NULL)
@@ -6107,6 +6122,10 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
if (min == 0)
xmlFAGenerateEpsilonTransition(am, from, to);
return(to);
+
+error:
+ xmlRegFreeAtom(atom);
+ return(NULL);
}
/**
@@ -6147,6 +6166,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
return(NULL);
if ((token2 == NULL) || (*token2 == 0)) {
atom->valuep = xmlStrdup(token);
+ if (atom->valuep == NULL)
+ goto error;
} else {
int lenn, lenp;
xmlChar *str;
@@ -6155,10 +6176,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
lenp = strlen((char *) token);
str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
- if (str == NULL) {
- xmlRegFreeAtom(atom);
- return(NULL);
- }
+ if (str == NULL)
+ goto error;
memcpy(&str[0], token, lenp);
str[lenp] = '|';
memcpy(&str[lenp + 1], token2, lenn);
@@ -6181,12 +6200,17 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
if (to == NULL) {
to = xmlRegStatePush(am);
if (to == NULL)
- return(NULL);
+ goto error;
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
- xmlRegAtomPush(am, atom);
+ if (xmlRegAtomPush(am, atom) < 0)
+ goto error;
am->state = to;
return(to);
+
+error:
+ xmlRegFreeAtom(atom);
+ return(NULL);
}
@@ -6241,12 +6265,17 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
if (to == NULL) {
to = xmlRegStatePush(am);
if (to == NULL)
- return(NULL);
+ goto error;
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
- xmlRegAtomPush(am, atom);
+ if (xmlRegAtomPush(am, atom) < 0)
+ goto error;
am->state = to;
return(to);
+
+error:
+ xmlRegFreeAtom(atom);
+ return(NULL);
}
/**
--
2.27.0

View File

@ -0,0 +1,48 @@
From 85bc313e7996c06d52b6f6f5c6a467ff3a148e75 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 15 Feb 2023 13:49:28 +0100
Subject: [PATCH] malloc-fail: Fix memory leak after calling valuePush
Destroy the object in valuePush if the function fails. This is somewhat
dangerous but matches the expectations of users.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/85bc313e7996c06d52b6f6f5c6a467ff3a148e75
Conflict:NA
---
xpath.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/xpath.c b/xpath.c
index 7833870..dc99e63 100644
--- a/xpath.c
+++ b/xpath.c
@@ -2881,6 +2881,8 @@ valuePop(xmlXPathParserContextPtr ctxt)
* a memory error is recorded in the parser context.
*
* Returns the number of items on the value stack, or -1 in case of error.
+ *
+ * The object is destroyed in case of error.
*/
int
valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value)
@@ -2899,6 +2901,7 @@ valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value)
if (ctxt->valueMax >= XPATH_MAX_STACK_DEPTH) {
xmlXPathPErrMemory(ctxt, "XPath stack depth limit reached\n");
+ xmlXPathFreeObject(value);
return (-1);
}
tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab,
@@ -2906,6 +2909,7 @@ valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value)
sizeof(ctxt->valueTab[0]));
if (tmp == NULL) {
xmlXPathPErrMemory(ctxt, "pushing value\n");
+ xmlXPathFreeObject(value);
return (-1);
}
ctxt->valueMax *= 2;
--
2.27.0

View File

@ -0,0 +1,233 @@
From 8d22e065888942b8c1b5be8994c6887b5a687246 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 15 Feb 2023 14:41:11 +0100
Subject: [PATCH] malloc-fail: Fix memory leak after calling
xmlXPathNodeSetMerge
Destroy the first argument in xmlXPathNodeSetMerge if the function
fails. This is somewhat dangerous but matches the expectations of users.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/8d22e065888942b8c1b5be8994c6887b5a687246
Conflict:xpath.c
---
xpath.c | 78 +++++++++++++++++++++++++++------------------------------
1 file changed, 37 insertions(+), 41 deletions(-)
diff --git a/xpath.c b/xpath.c
index 9ead497..5a6d762 100644
--- a/xpath.c
+++ b/xpath.c
@@ -153,6 +153,9 @@
* any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT)
*/
+static void
+xmlXPathNodeSetClear(xmlNodeSetPtr set, int hasNsNodes);
+
#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
/**
* xmlXPathCmpNodesExt:
@@ -3840,6 +3843,8 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
* if @val1 is NULL, a new set is created and copied from @val2
*
* Returns @val1 once extended or NULL in case of error.
+ *
+ * Frees @val1 in case of error.
*/
xmlNodeSetPtr
xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
@@ -3849,35 +3854,8 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
if (val2 == NULL) return(val1);
if (val1 == NULL) {
val1 = xmlXPathNodeSetCreate(NULL);
- if (val1 == NULL)
- return (NULL);
-#if 0
- /*
- * TODO: The optimization won't work in every case, since
- * those nasty namespace nodes need to be added with
- * xmlXPathNodeSetDupNs() to the set; thus a pure
- * memcpy is not possible.
- * If there was a flag on the nodesetval, indicating that
- * some temporary nodes are in, that would be helpful.
- */
- /*
- * Optimization: Create an equally sized node-set
- * and memcpy the content.
- */
- val1 = xmlXPathNodeSetCreateSize(val2->nodeNr);
- if (val1 == NULL)
- return(NULL);
- if (val2->nodeNr != 0) {
- if (val2->nodeNr == 1)
- *(val1->nodeTab) = *(val2->nodeTab);
- else {
- memcpy(val1->nodeTab, val2->nodeTab,
- val2->nodeNr * sizeof(xmlNodePtr));
- }
- val1->nodeNr = val2->nodeNr;
- }
- return(val1);
-#endif
+ if (val1 == NULL)
+ return (NULL);
}
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
@@ -3916,7 +3894,7 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
sizeof(xmlNodePtr));
if (val1->nodeTab == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
- return(NULL);
+ goto error;
}
memset(val1->nodeTab, 0 ,
XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
@@ -3926,13 +3904,13 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
if (val1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
- return(NULL);
+ goto error;
}
temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
- return(NULL);
+ goto error;
}
val1->nodeTab = temp;
val1->nodeMax *= 2;
@@ -3942,13 +3920,17 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
xmlNodePtr nsNode = xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
if (nsNode == NULL)
- return(NULL);
+ goto error;
val1->nodeTab[val1->nodeNr++] = nsNode;
} else
val1->nodeTab[val1->nodeNr++] = n2;
}
return(val1);
+
+error:
+ xmlXPathFreeNodeSet(val1);
+ return(NULL);
}
@@ -3961,6 +3943,8 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
* Checks for duplicate nodes. Clears set2.
*
* Returns @set1 once extended or NULL in case of error.
+ *
+ * Frees @set1 in case of error.
*/
static xmlNodeSetPtr
xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2)
@@ -3989,7 +3973,6 @@ xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2)
/*
* Free the namespace node.
*/
- set2->nodeTab[i] = NULL;
xmlXPathNodeSetFreeNs((xmlNsPtr) n2);
goto skip_node;
}
@@ -4003,7 +3986,7 @@ xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2)
XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
if (set1->nodeTab == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
- return(NULL);
+ goto error;
}
memset(set1->nodeTab, 0,
XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
@@ -4013,24 +3996,29 @@ xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2)
if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
- return(NULL);
+ goto error;
}
temp = (xmlNodePtr *) xmlRealloc(
set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
- return(NULL);
+ goto error;
}
set1->nodeTab = temp;
set1->nodeMax *= 2;
}
set1->nodeTab[set1->nodeNr++] = n2;
skip_node:
- {}
+ set2->nodeTab[i] = NULL;
}
}
set2->nodeNr = 0;
return(set1);
+
+error:
+ xmlXPathFreeNodeSet(set1);
+ xmlXPathNodeSetClear(set2, 1);
+ return(NULL);
}
/**
@@ -4042,6 +4030,8 @@ skip_node:
* Doesn't check for duplicate nodes. Clears set2.
*
* Returns @set1 once extended or NULL in case of error.
+ *
+ * Frees @set1 in case of error.
*/
static xmlNodeSetPtr
xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2)
@@ -4057,7 +4047,7 @@ xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2)
XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
if (set1->nodeTab == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
- return(NULL);
+ goto error;
}
memset(set1->nodeTab, 0,
XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
@@ -4067,22 +4057,28 @@ xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2)
if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
- return(NULL);
+ goto error;
}
temp = (xmlNodePtr *) xmlRealloc(
set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
- return(NULL);
+ goto error;
}
set1->nodeTab = temp;
set1->nodeMax *= 2;
}
set1->nodeTab[set1->nodeNr++] = n2;
+ set2->nodeTab[i] = NULL;
}
}
set2->nodeNr = 0;
return(set1);
+
+error:
+ xmlXPathFreeNodeSet(set1);
+ xmlXPathNodeSetClear(set2, 1);
+ return(NULL);
}
/**
--
2.27.0

View File

@ -0,0 +1,50 @@
From f5e1174933c65556b5d1c0b3a8f13a27f37a1638 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 15 Feb 2023 13:48:18 +0100
Subject: [PATCH] malloc-fail: Fix memory leak after calling
xmlXPathWrapNodeSet
Destroy the node set in xmlXPathWrapNodeSet if the function fails.
This is somewhat dangerous but matches the expectations of users.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/f5e1174933c65556b5d1c0b3a8f13a27f37a1638
Conflict:xpath.c
---
xpath.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/xpath.c b/xpath.c
index dc99e63..9ead497 100644
--- a/xpath.c
+++ b/xpath.c
@@ -2319,6 +2319,8 @@ xmlXPathContextSetCache(xmlXPathContextPtr ctxt,
* Wrap the Nodeset @val in a new xmlXPathObjectPtr
*
* Returns the created or reused object.
+ *
+ * In case of error the node set is destroyed and NULL is returned.
*/
static xmlXPathObjectPtr
xmlXPathCacheWrapNodeSet(xmlXPathContextPtr ctxt, xmlNodeSetPtr val)
@@ -4398,6 +4400,8 @@ xmlXPathNewNodeSetList(xmlNodeSetPtr val)
* Wrap the Nodeset @val in a new xmlXPathObjectPtr
*
* Returns the newly created object.
+ *
+ * In case of error the node set is destroyed and NULL is returned.
*/
xmlXPathObjectPtr
xmlXPathWrapNodeSet(xmlNodeSetPtr val) {
@@ -4406,6 +4410,7 @@ xmlXPathWrapNodeSet(xmlNodeSetPtr val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlXPathErrMemory(NULL, "creating node set object\n");
+ xmlXPathFreeNodeSet(val);
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
--
2.27.0

View File

@ -0,0 +1,41 @@
From d31a0e8e7599bfb691616f7c59ff8d39b982aa55 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 15 Feb 2023 14:47:29 +0100
Subject: [PATCH] malloc-fail: Fix memory leak after calling xmlXPathWrapString
Destroy the string in xmlXPathWrapString if the function fails. This is
somewhat dangerous but matches the expectations of users.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/d31a0e8e7599bfb691616f7c59ff8d39b982aa55
Conflict:xpath.c
---
xpath.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/xpath.c b/xpath.c
index 5a6d762..cf74030 100644
--- a/xpath.c
+++ b/xpath.c
@@ -5289,6 +5289,8 @@ xmlXPathNewString(const xmlChar *val) {
* Wraps the @val string into an XPath object.
*
* Returns the newly created object.
+ *
+ * Frees @val in case of error.
*/
xmlXPathObjectPtr
xmlXPathWrapString (xmlChar *val) {
@@ -5297,6 +5299,7 @@ xmlXPathWrapString (xmlChar *val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlXPathErrMemory(NULL, "creating string object\n");
+ xmlFree(val);
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
--
2.27.0

View File

@ -0,0 +1,331 @@
From e60c9f4c4b76da72772bfb6bb1f705e02fbb5324 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 15 Feb 2023 01:00:03 +0100
Subject: [PATCH] malloc-fail: Fix memory leak after xmlRegNewState
Invoke xmlRegNewState from xmlRegStatePush to simplify error handling.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/e60c9f4c4b76da72772bfb6bb1f705e02fbb5324
Conflict:NA
---
xmlregexp.c | 144 ++++++++++++++++++++++++++--------------------------
1 file changed, 71 insertions(+), 73 deletions(-)
diff --git a/xmlregexp.c b/xmlregexp.c
index 657912e..fb2eadc 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -1455,33 +1455,31 @@ xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
xmlRegStateAddTransTo(ctxt, target, state->no);
}
-static int
-xmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) {
- if (state == NULL) return(-1);
- if (ctxt->maxStates == 0) {
- ctxt->maxStates = 4;
- ctxt->states = (xmlRegStatePtr *) xmlMalloc(ctxt->maxStates *
- sizeof(xmlRegStatePtr));
- if (ctxt->states == NULL) {
- xmlRegexpErrMemory(ctxt, "adding state");
- ctxt->maxStates = 0;
- return(-1);
- }
- } else if (ctxt->nbStates >= ctxt->maxStates) {
+static xmlRegStatePtr
+xmlRegStatePush(xmlRegParserCtxtPtr ctxt) {
+ xmlRegStatePtr state;
+
+ if (ctxt->nbStates >= ctxt->maxStates) {
+ size_t newSize = ctxt->maxStates ? ctxt->maxStates * 2 : 4;
xmlRegStatePtr *tmp;
- ctxt->maxStates *= 2;
- tmp = (xmlRegStatePtr *) xmlRealloc(ctxt->states, ctxt->maxStates *
- sizeof(xmlRegStatePtr));
+
+ tmp = xmlRealloc(ctxt->states, newSize * sizeof(tmp[0]));
if (tmp == NULL) {
xmlRegexpErrMemory(ctxt, "adding state");
- ctxt->maxStates /= 2;
- return(-1);
+ return(NULL);
}
ctxt->states = tmp;
+ ctxt->maxStates = newSize;
}
+
+ state = xmlRegNewState(ctxt);
+ if (state == NULL)
+ return(NULL);
+
state->no = ctxt->nbStates;
ctxt->states[ctxt->nbStates++] = state;
- return(0);
+
+ return(state);
}
/**
@@ -1492,19 +1490,21 @@ xmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) {
* @lax:
*
*/
-static void
+static int
xmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt,
xmlRegStatePtr from, xmlRegStatePtr to,
int lax) {
if (to == NULL) {
- to = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, to);
+ to = xmlRegStatePush(ctxt);
+ if (to == NULL)
+ return(-1);
ctxt->state = to;
}
if (lax)
xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_LAX_COUNTER);
else
xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_COUNTER);
+ return(0);
}
/**
@@ -1514,15 +1514,17 @@ xmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt,
* @to: the target state or NULL for building a new one
*
*/
-static void
+static int
xmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt,
xmlRegStatePtr from, xmlRegStatePtr to) {
if (to == NULL) {
- to = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, to);
+ to = xmlRegStatePush(ctxt);
+ if (to == NULL)
+ return(-1);
ctxt->state = to;
}
xmlRegStateAddTrans(ctxt, from, NULL, to, -1, -1);
+ return(0);
}
/**
@@ -1533,15 +1535,17 @@ xmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt,
* counter: the counter for that transition
*
*/
-static void
+static int
xmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt,
xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
if (to == NULL) {
- to = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, to);
+ to = xmlRegStatePush(ctxt);
+ if (to == NULL)
+ return(-1);
ctxt->state = to;
}
xmlRegStateAddTrans(ctxt, from, NULL, to, counter, -1);
+ return(0);
}
/**
@@ -1552,15 +1556,17 @@ xmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt,
* counter: the counter for that transition
*
*/
-static void
+static int
xmlFAGenerateCountedTransition(xmlRegParserCtxtPtr ctxt,
xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
if (to == NULL) {
- to = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, to);
+ to = xmlRegStatePush(ctxt);
+ if (to == NULL)
+ return(-1);
ctxt->state = to;
}
xmlRegStateAddTrans(ctxt, from, NULL, to, -1, counter);
+ return(0);
}
/**
@@ -1599,8 +1605,9 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
#ifdef DV
} else if ((to == NULL) && (atom->quant != XML_REGEXP_QUANT_RANGE) &&
(atom->quant != XML_REGEXP_QUANT_ONCE)) {
- to = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, to);
+ to = xmlRegStatePush(ctxt, to);
+ if (to == NULL)
+ return(-1);
ctxt->state = to;
xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to);
#endif
@@ -1640,8 +1647,9 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
if (to != NULL) {
newstate = to;
} else {
- newstate = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, newstate);
+ newstate = xmlRegStatePush(ctxt);
+ if (newstate == NULL)
+ return(-1);
}
/*
@@ -1721,12 +1729,9 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
* we can discard the atom and generate an epsilon transition instead
*/
if (to == NULL) {
- to = xmlRegNewState(ctxt);
- if (to != NULL)
- xmlRegStatePush(ctxt, to);
- else {
+ to = xmlRegStatePush(ctxt);
+ if (to == NULL)
return(-1);
- }
}
xmlFAGenerateEpsilonTransition(ctxt, from, to);
ctxt->state = to;
@@ -1734,12 +1739,9 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
return(0);
}
if (to == NULL) {
- to = xmlRegNewState(ctxt);
- if (to != NULL)
- xmlRegStatePush(ctxt, to);
- else {
+ to = xmlRegStatePush(ctxt);
+ if (to == NULL)
return(-1);
- }
}
end = to;
if ((atom->quant == XML_REGEXP_QUANT_MULT) ||
@@ -1751,12 +1753,9 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
*/
xmlRegStatePtr tmp;
- tmp = xmlRegNewState(ctxt);
- if (tmp != NULL)
- xmlRegStatePush(ctxt, tmp);
- else {
+ tmp = xmlRegStatePush(ctxt);
+ if (tmp == NULL)
return(-1);
- }
xmlFAGenerateEpsilonTransition(ctxt, tmp, to);
to = tmp;
}
@@ -5562,9 +5561,11 @@ xmlRegexpCompile(const xmlChar *regexp) {
return(NULL);
/* initialize the parser */
+ ctxt->state = xmlRegStatePush(ctxt);
+ if (ctxt->state == NULL)
+ return(NULL);
+ ctxt->start = ctxt->state;
ctxt->end = NULL;
- ctxt->start = ctxt->state = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, ctxt->start);
/* parse the expression building an automata */
xmlFAParseRegExp(ctxt, 1);
@@ -5712,18 +5713,15 @@ xmlNewAutomata(void) {
return(NULL);
/* initialize the parser */
- ctxt->end = NULL;
- ctxt->start = ctxt->state = xmlRegNewState(ctxt);
- if (ctxt->start == NULL) {
+ ctxt->state = xmlRegStatePush(ctxt);
+ if (ctxt->state == NULL) {
xmlFreeAutomata(ctxt);
return(NULL);
}
+ ctxt->start = ctxt->state;
+ ctxt->end = NULL;
+
ctxt->start->type = XML_REGEXP_START_STATE;
- if (xmlRegStatePush(ctxt, ctxt->start) < 0) {
- xmlRegFreeState(ctxt->start);
- xmlFreeAutomata(ctxt);
- return(NULL);
- }
ctxt->flags = 0;
return(ctxt);
@@ -6021,8 +6019,9 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
/* xmlFAGenerateTransitions(am, from, to, atom); */
if (to == NULL) {
- to = xmlRegNewState(am);
- xmlRegStatePush(am, to);
+ to = xmlRegStatePush(am);
+ if (to == NULL)
+ return(NULL);
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
xmlRegAtomPush(am, atom);
@@ -6087,8 +6086,9 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
/* xmlFAGenerateTransitions(am, from, to, atom); */
if (to == NULL) {
- to = xmlRegNewState(am);
- xmlRegStatePush(am, to);
+ to = xmlRegStatePush(am);
+ if (to == NULL)
+ return(NULL);
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
xmlRegAtomPush(am, atom);
@@ -6173,8 +6173,9 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
/* xmlFAGenerateTransitions(am, from, to, atom); */
if (to == NULL) {
- to = xmlRegNewState(am);
- xmlRegStatePush(am, to);
+ to = xmlRegStatePush(am);
+ if (to == NULL)
+ return(NULL);
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
xmlRegAtomPush(am, atom);
@@ -6232,8 +6233,9 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
/* xmlFAGenerateTransitions(am, from, to, atom); */
if (to == NULL) {
- to = xmlRegNewState(am);
- xmlRegStatePush(am, to);
+ to = xmlRegStatePush(am);
+ if (to == NULL)
+ return(NULL);
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
xmlRegAtomPush(am, atom);
@@ -6251,13 +6253,9 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
*/
xmlAutomataStatePtr
xmlAutomataNewState(xmlAutomataPtr am) {
- xmlAutomataStatePtr to;
-
if (am == NULL)
return(NULL);
- to = xmlRegNewState(am);
- xmlRegStatePush(am, to);
- return(to);
+ return(xmlRegStatePush(am));
}
/**
--
2.27.0

View File

@ -0,0 +1,56 @@
From 9afb6c5fb86a0dca167b6ae60aa05211a25e435f Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 5 Mar 2023 14:09:49 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in WXS_ADD_{LOCAL,GLOBAL}
It's somewhat dangerous to add the cleanup code to a macro, but
otherwise we'd have to fix all the call sites.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/9afb6c5fb86a0dca167b6ae60aa05211a25e435f
Conflict:NA
---
xmlschemas.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/xmlschemas.c b/xmlschemas.c
index 5b93937..724920b 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -305,10 +305,20 @@ static const xmlChar *xmlNamespaceNs = (const xmlChar *)
#define WXS_SCHEMA(ctx) (ctx)->schema
#define WXS_ADD_LOCAL(ctx, item) \
- xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
+ do { \
+ if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) < 0) { \
+ xmlFree(item); \
+ item = NULL; \
+ } \
+ } while (0)
#define WXS_ADD_GLOBAL(ctx, item) \
- xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
+ do { \
+ if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) < 0) { \
+ xmlFree(item); \
+ item = NULL; \
+ } \
+ } while (0)
#define WXS_ADD_PENDING(ctx, item) \
xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
@@ -3764,8 +3774,7 @@ xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
if (*list == NULL)
return(-1);
}
- xmlSchemaItemListAddSize(*list, initialSize, item);
- return(0);
+ return(xmlSchemaItemListAddSize(*list, initialSize, item));
}
/**
--
2.27.0

View File

@ -0,0 +1,31 @@
From fc256953d29698ba5918c32d14fc69ea69d7e64e Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 Feb 2023 14:47:41 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in htmlCreateMemoryParserCtxt
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/fc256953d29698ba5918c32d14fc69ea69d7e64e
Conflict:NA
---
HTMLparser.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index 0ccd6e8..7ea2e62 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -5191,7 +5191,10 @@ htmlCreateMemoryParserCtxt(const char *buffer, int size) {
return(NULL);
buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
- if (buf == NULL) return(NULL);
+ if (buf == NULL) {
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
+ }
input = xmlNewInputStream(ctxt);
if (input == NULL) {
--
2.27.0

View File

@ -0,0 +1,28 @@
From f3e62035d8b80a6dba92639f2470f02258822a0a Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 Feb 2023 14:49:06 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in htmlCreatePushParserCtxt
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/f3e62035d8b80a6dba92639f2470f02258822a0a
Conflict:NA
---
HTMLparser.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index 7ea2e62..5272c25 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -6355,7 +6355,7 @@ htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
inputStream = htmlNewInputStream(ctxt);
if (inputStream == NULL) {
xmlFreeParserCtxt(ctxt);
- xmlFree(buf);
+ xmlFreeParserInputBuffer(buf);
return(NULL);
}
--
2.27.0

View File

@ -0,0 +1,31 @@
From dbc893f5885cf60f9ebed89c363ff810bde3ebb5 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 3 Mar 2023 13:02:11 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlCopyNamespaceList
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/dbc893f5885cf60f9ebed89c363ff810bde3ebb5
Conflict:NA
---
tree.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tree.c b/tree.c
index 4a80e28..14d5247 100644
--- a/tree.c
+++ b/tree.c
@@ -4046,6 +4046,10 @@ xmlCopyNamespaceList(xmlNsPtr cur) {
while (cur != NULL) {
q = xmlCopyNamespace(cur);
+ if (q == NULL) {
+ xmlFreeNsList(ret);
+ return(NULL);
+ }
if (p == NULL) {
ret = p = q;
} else {
--
2.27.0

View File

@ -0,0 +1,32 @@
From bc7740b3c30e1517dcf53a084766c74d25db222f Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 Feb 2023 11:45:58 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlCopyPropList
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/bc7740b3c30e1517dcf53a084766c74d25db222f
Conflict:NA
---
tree.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tree.c b/tree.c
index ac156e1..35bd948 100644
--- a/tree.c
+++ b/tree.c
@@ -4190,8 +4190,10 @@ xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) {
return(NULL);
while (cur != NULL) {
q = xmlCopyProp(target, cur);
- if (q == NULL)
+ if (q == NULL) {
+ xmlFreePropList(ret);
return(NULL);
+ }
if (p == NULL) {
ret = p = q;
} else {
--
2.27.0

View File

@ -0,0 +1,28 @@
From 7de8005c52c1fc4289b737c8d12c0c4efd72b605 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 2 Nov 2022 15:46:11 +0100
Subject: [PATCH 04/28] malloc-fail: Fix memory leak in xmlCreatePushParserCtxt
Found with libFuzzer, see #344.
Reference: https://github.com/GNOME/libxml2/commit/865e142c4188d892705a62f9ce9df896e7b4543d
Conflict: NA
---
parser.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/parser.c b/parser.c
index 23b031d..443a216 100644
--- a/parser.c
+++ b/parser.c
@@ -12508,6 +12508,7 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
inputStream->filename = (char *)
xmlCanonicPath((const xmlChar *) filename);
if (inputStream->filename == NULL) {
+ xmlFreeInputStream(inputStream);
xmlFreeParserCtxt(ctxt);
xmlFreeParserInputBuffer(buf);
return(NULL);
--
2.27.0

View File

@ -0,0 +1,29 @@
From c82701ff0b24bc56c6814e690198599cfc8c273a Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 14 Feb 2023 15:13:06 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlDocDumpFormatMemoryEnc
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/c82701ff0b24bc56c6814e690198599cfc8c273a
Conflict:NA
---
xmlsave.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/xmlsave.c b/xmlsave.c
index 489505f..90e1856 100644
--- a/xmlsave.c
+++ b/xmlsave.c
@@ -2402,6 +2402,7 @@ xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
if ((out_buff = xmlAllocOutputBuffer(conv_hdlr)) == NULL ) {
xmlSaveErrMemory("creating buffer");
+ xmlCharEncCloseFunc(conv_hdlr);
return;
}
--
2.27.0

View File

@ -0,0 +1,93 @@
From 40bc1c699a7999626d3384be43684f2a68dad6c4 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 17 Feb 2023 15:40:32 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlFAParseCharProp
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/40bc1c699a7999626d3384be43684f2a68dad6c4
Conflict:NA
---
xmlregexp.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/xmlregexp.c b/xmlregexp.c
index fb2eadc..8c2ea81 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -1245,7 +1245,7 @@ xmlRegPrintCtxt(FILE *output, xmlRegParserCtxtPtr ctxt) {
* *
************************************************************************/
-static void
+static xmlRegRangePtr
xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
int neg, xmlRegAtomType type, int start, int end,
xmlChar *blockName) {
@@ -1253,11 +1253,11 @@ xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
if (atom == NULL) {
ERROR("add range: atom is NULL");
- return;
+ return(NULL);
}
if (atom->type != XML_REGEXP_RANGES) {
ERROR("add range: atom is not ranges");
- return;
+ return(NULL);
}
if (atom->maxRanges == 0) {
atom->maxRanges = 4;
@@ -1266,7 +1266,7 @@ xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
if (atom->ranges == NULL) {
xmlRegexpErrMemory(ctxt, "adding ranges");
atom->maxRanges = 0;
- return;
+ return(NULL);
}
} else if (atom->nbRanges >= atom->maxRanges) {
xmlRegRangePtr *tmp;
@@ -1276,16 +1276,17 @@ xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
if (tmp == NULL) {
xmlRegexpErrMemory(ctxt, "adding ranges");
atom->maxRanges /= 2;
- return;
+ return(NULL);
}
atom->ranges = tmp;
}
range = xmlRegNewRange(ctxt, neg, type, start, end);
if (range == NULL)
- return;
+ return(NULL);
range->blockName = blockName;
atom->ranges[atom->nbRanges++] = range;
+ return(range);
}
static int
@@ -4899,11 +4900,16 @@ xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) {
}
if (ctxt->atom == NULL) {
ctxt->atom = xmlRegNewAtom(ctxt, type);
- if (ctxt->atom != NULL)
- ctxt->atom->valuep = blockName;
+ if (ctxt->atom == NULL) {
+ xmlFree(blockName);
+ return;
+ }
+ ctxt->atom->valuep = blockName;
} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
- xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
- type, 0, 0, blockName);
+ if (xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
+ type, 0, 0, blockName) == NULL) {
+ xmlFree(blockName);
+ }
}
}
--
2.27.0

View File

@ -0,0 +1,87 @@
From 9fa1b228a5d60fab92a79c6c01c39e37454da1b3 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 14 Feb 2023 16:43:35 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlGetDtdElementDesc2
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/9fa1b228a5d60fab92a79c6c01c39e37454da1b3
Conflict:valid.c
---
valid.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/valid.c b/valid.c
index ed3c850..b7b92fe 100644
--- a/valid.c
+++ b/valid.c
@@ -26,8 +26,9 @@
#include <libxml/list.h>
#include <libxml/globals.h>
-static xmlElementPtr xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name,
- int create);
+static xmlElementPtr
+xmlGetDtdElementDesc2(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
+ int create);
/* #define DEBUG_VALID_ALGO */
/* #define DEBUG_REGEXP_ALGO */
@@ -2135,7 +2136,7 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
* Validity Check:
* Multiple ID per element
*/
- elemDef = xmlGetDtdElementDesc2(dtd, elem, 1);
+ elemDef = xmlGetDtdElementDesc2(ctxt, dtd, elem, 1);
if (elemDef != NULL) {
#ifdef LIBXML_VALID_ENABLED
@@ -3295,7 +3296,8 @@ xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) {
*/
static xmlElementPtr
-xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) {
+xmlGetDtdElementDesc2(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
+ int create) {
xmlElementTablePtr table;
xmlElementPtr cur;
xmlChar *uqname = NULL, *prefix = NULL;
@@ -3318,7 +3320,7 @@ xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) {
dtd->elements = (void *) table;
}
if (table == NULL) {
- xmlVErrMemory(NULL, "element table allocation failed");
+ xmlVErrMemory(ctxt, "element table allocation failed");
return(NULL);
}
}
@@ -3331,8 +3333,8 @@ xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) {
if ((cur == NULL) && (create)) {
cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
if (cur == NULL) {
- xmlVErrMemory(NULL, "malloc failed");
- return(NULL);
+ xmlVErrMemory(ctxt, "malloc failed");
+ goto error;
}
memset(cur, 0, sizeof(xmlElement));
cur->type = XML_ELEMENT_DECL;
@@ -3344,8 +3346,13 @@ xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) {
cur->prefix = xmlStrdup(prefix);
cur->etype = XML_ELEMENT_TYPE_UNDEFINED;
- xmlHashAddEntry2(table, name, prefix, cur);
+ if (xmlHashAddEntry2(table, name, prefix, cur) < 0) {
+ xmlVErrMemory(ctxt, "adding entry failed");
+ xmlFreeElement(cur);
+ cur = NULL;
+ }
}
+error:
if (prefix != NULL) xmlFree(prefix);
if (uqname != NULL) xmlFree(uqname);
return(cur);
--
2.27.0

View File

@ -0,0 +1,70 @@
From a442d16a5fe61626f00f33abe547da9379a37d89 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 26 Feb 2023 14:48:23 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlGetNsList
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/a442d16a5fe61626f00f33abe547da9379a37d89
Conflict:NA
---
tree.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/tree.c b/tree.c
index 35bd948..4a80e28 100644
--- a/tree.c
+++ b/tree.c
@@ -5971,7 +5971,7 @@ xmlGetNsList(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlNode *node)
xmlNsPtr cur;
xmlNsPtr *ret = NULL;
int nbns = 0;
- int maxns = 10;
+ int maxns = 0;
int i;
if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
@@ -5981,16 +5981,6 @@ xmlGetNsList(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlNode *node)
if (node->type == XML_ELEMENT_NODE) {
cur = node->nsDef;
while (cur != NULL) {
- if (ret == NULL) {
- ret =
- (xmlNsPtr *) xmlMalloc((maxns + 1) *
- sizeof(xmlNsPtr));
- if (ret == NULL) {
- xmlTreeErrMemory("getting namespace list");
- return (NULL);
- }
- ret[nbns] = NULL;
- }
for (i = 0; i < nbns; i++) {
if ((cur->prefix == ret[i]->prefix) ||
(xmlStrEqual(cur->prefix, ret[i]->prefix)))
@@ -5998,15 +5988,18 @@ xmlGetNsList(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlNode *node)
}
if (i >= nbns) {
if (nbns >= maxns) {
- maxns *= 2;
- ret = (xmlNsPtr *) xmlRealloc(ret,
- (maxns +
- 1) *
+ xmlNsPtr *tmp;
+
+ maxns = maxns ? maxns * 2 : 10;
+ tmp = (xmlNsPtr *) xmlRealloc(ret,
+ (maxns + 1) *
sizeof(xmlNsPtr));
- if (ret == NULL) {
+ if (tmp == NULL) {
xmlTreeErrMemory("getting namespace list");
+ xmlFree(ret);
return (NULL);
}
+ ret = tmp;
}
ret[nbns++] = cur;
ret[nbns] = NULL;
--
2.27.0

View File

@ -0,0 +1,32 @@
From ec471ee3202d4434b695e652e1fd5e0dfc592d1b Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 2 Nov 2022 15:58:31 +0100
Subject: [PATCH 07/28] malloc-fail: Fix memory leak in xmlNewDocNodeEatName
Found with libFuzzer, see #344.
Reference: https://github.com/GNOME/libxml2/commit/dd50cfeb61c4f74ffc1dca1e818e01cf478e366d
Conflict: NA
---
tree.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tree.c b/tree.c
index 6a8c2ea..bb85220 100644
--- a/tree.c
+++ b/tree.c
@@ -2385,8 +2385,9 @@ xmlNewDocNodeEatName(xmlDocPtr doc, xmlNsPtr ns,
}
} else {
/* if name don't come from the doc dictionary free it here */
- if ((name != NULL) && (doc != NULL) &&
- (!(xmlDictOwns(doc->dict, name))))
+ if ((name != NULL) &&
+ ((doc == NULL) || (doc->dict == NULL) ||
+ (!(xmlDictOwns(doc->dict, name)))))
xmlFree(name);
}
return(cur);
--
2.27.0

View File

@ -0,0 +1,39 @@
From dee436cd010d7144730526914193bd9fe6c74821 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 2 Nov 2022 15:53:52 +0100
Subject: [PATCH 06/28] malloc-fail: Fix memory leak in xmlNewPropInternal
Also fixes a memory leak if called with a non-element node.
Found with libFuzzer, see #344.
Reference: https://github.com/GNOME/libxml2/commit/fa361de0b759f045c5f6f7f9c09a133abcc074c9
Conflict: NA
---
tree.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tree.c b/tree.c
index b32561d..6a8c2ea 100644
--- a/tree.c
+++ b/tree.c
@@ -1866,7 +1866,7 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
if ((node != NULL) && (node->type != XML_ELEMENT_NODE)) {
if ((eatname == 1) &&
- ((node->doc == NULL) ||
+ ((node->doc == NULL) || (node->doc->dict == NULL) ||
(!(xmlDictOwns(node->doc->dict, name)))))
xmlFree((xmlChar *) name);
return (NULL);
@@ -1879,6 +1879,7 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
if (cur == NULL) {
if ((eatname == 1) &&
((node == NULL) || (node->doc == NULL) ||
+ (node->doc->dict == NULL) ||
(!(xmlDictOwns(node->doc->dict, name)))))
xmlFree((xmlChar *) name);
xmlTreeErrMemory("building attribute");
--
2.27.0

View File

@ -0,0 +1,38 @@
From f8852184a111f6c4abb38ea3d2b2b91f45347a7a Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 14 Feb 2023 13:03:13 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlParseEntityDecl
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/f8852184a111f6c4abb38ea3d2b2b91f45347a7a
Conflict:NA
---
parser.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/parser.c b/parser.c
index 3aea3e2..37d7dec 100644
--- a/parser.c
+++ b/parser.c
@@ -5518,7 +5518,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
if (ctxt->myDoc == NULL) {
xmlErrMemory(ctxt, "New Doc failed");
- return;
+ goto done;
}
ctxt->myDoc->properties = XML_DOC_INTERNAL;
}
@@ -5589,7 +5589,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
if (ctxt->myDoc == NULL) {
xmlErrMemory(ctxt, "New Doc failed");
- return;
+ goto done;
}
ctxt->myDoc->properties = XML_DOC_INTERNAL;
}
--
2.27.0

View File

@ -0,0 +1,30 @@
From 33264f08a089667a6b69f9ba019e8c3f0bb36d39 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 2 Nov 2022 16:11:00 +0100
Subject: [PATCH 10/28] malloc-fail: Fix memory leak in xmlParseReference
Found with libFuzzer, see #344.
Reference: https://github.com/GNOME/libxml2/commit/afc7e3a7f41e2e29ac36d4d7cbd0c0755558fa5d
Conflict: NA
---
parser.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/parser.c b/parser.c
index 780a8b3..334a0aa 100644
--- a/parser.c
+++ b/parser.c
@@ -7463,8 +7463,8 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
firstChild = cur;
}
xmlAddChild((xmlNodePtr) ent, nw);
- xmlAddChild(ctxt->node, cur);
}
+ xmlAddChild(ctxt->node, cur);
if (cur == last)
break;
cur = next;
--
2.27.0

View File

@ -0,0 +1,30 @@
From 97086fd76b21fee6e41c13921c450411442d9da6 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 14 Feb 2023 14:45:58 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlParserInputBufferCreateMem
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/97086fd76b21fee6e41c13921c450411442d9da6
Conflict:NA
---
xmlIO.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xmlIO.c b/xmlIO.c
index 71c9fbf..edf31e8 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -2953,7 +2953,7 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
ret->closecallback = NULL;
errcode = xmlBufAdd(ret->buffer, (const xmlChar *) mem, size);
if (errcode != 0) {
- xmlFree(ret);
+ xmlFreeParserInputBuffer(ret);
return(NULL);
}
}
--
2.27.0

View File

@ -0,0 +1,67 @@
From ed615967dfeba615218826bb4ef0c87877cb53cd Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 17 Feb 2023 15:23:42 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlRegexpCompile
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/ed615967dfeba615218826bb4ef0c87877cb53cd
Conflict:NA
---
xmlregexp.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/xmlregexp.c b/xmlregexp.c
index 11c684a..360916f 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -5566,7 +5566,7 @@ xmlRegexpPrint(FILE *output, xmlRegexpPtr regexp) {
*/
xmlRegexpPtr
xmlRegexpCompile(const xmlChar *regexp) {
- xmlRegexpPtr ret;
+ xmlRegexpPtr ret = NULL;
xmlRegParserCtxtPtr ctxt;
ctxt = xmlRegNewParserCtxt(regexp);
@@ -5576,7 +5576,7 @@ xmlRegexpCompile(const xmlChar *regexp) {
/* initialize the parser */
ctxt->state = xmlRegStatePush(ctxt);
if (ctxt->state == NULL)
- return(NULL);
+ goto error;
ctxt->start = ctxt->state;
ctxt->end = NULL;
@@ -5585,10 +5585,8 @@ xmlRegexpCompile(const xmlChar *regexp) {
if (CUR != 0) {
ERROR("xmlFAParseRegExp: extra characters");
}
- if (ctxt->error != 0) {
- xmlRegFreeParserCtxt(ctxt);
- return(NULL);
- }
+ if (ctxt->error != 0)
+ goto error;
ctxt->end = ctxt->state;
ctxt->start->type = XML_REGEXP_START_STATE;
ctxt->end->type = XML_REGEXP_FINAL_STATE;
@@ -5597,11 +5595,11 @@ xmlRegexpCompile(const xmlChar *regexp) {
xmlFAEliminateEpsilonTransitions(ctxt);
- if (ctxt->error != 0) {
- xmlRegFreeParserCtxt(ctxt);
- return(NULL);
- }
+ if (ctxt->error != 0)
+ goto error;
ret = xmlRegEpxFromParse(ctxt);
+
+error:
xmlRegFreeParserCtxt(ctxt);
return(ret);
}
--
2.27.0

View File

@ -0,0 +1,28 @@
From 1a90087543485763d8e6124a1818e10637e512ae Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 2 Nov 2022 16:05:05 +0100
Subject: [PATCH 09/28] malloc-fail: Fix memory leak in xmlSAX2ExternalSubset
Found with libFuzzer, see #344.
Reference: https://github.com/GNOME/libxml2/commit/7ceaee9430ca24bda7f2480f387dbebfc259002a
Conflict: NA
---
SAX2.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/SAX2.c b/SAX2.c
index 9801393..96bbcb3 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -436,6 +436,7 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
xmlMalloc(5 * sizeof(xmlParserInputPtr));
if (ctxt->inputTab == NULL) {
xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset");
+ xmlFreeInputStream(input);
ctxt->input = oldinput;
ctxt->inputNr = oldinputNr;
ctxt->inputMax = oldinputMax;
--
2.27.0

View File

@ -0,0 +1,28 @@
From cb4334b7abf265f55d1a41f435fedd67494eeb18 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 14 Feb 2023 18:10:14 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlSAX2StartElementNs
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/cb4334b7abf265f55d1a41f435fedd67494eeb18
Conflict:NA
---
SAX2.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/SAX2.c b/SAX2.c
index 2426e93..916e974 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -2242,6 +2242,7 @@ xmlSAX2StartElementNs(void *ctx,
ret->name = lname;
if (ret->name == NULL) {
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
+ xmlFree(ret);
return;
}
}
--
2.27.0

View File

@ -0,0 +1,35 @@
From a5787229e5c53d522364cd68397cdc61094ac51a Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 5 Mar 2023 14:09:34 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlSchemaBucketCreate
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/260d6b8d77d11a20a2614eef99e88e68eaca6550
Conflict:NA
---
xmlschemas.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/xmlschemas.c b/xmlschemas.c
index 724920b..9ace2b7 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -3658,12 +3658,12 @@ xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
ret->type = type;
ret->globals = xmlSchemaItemListCreate();
if (ret->globals == NULL) {
- xmlFree(ret);
+ xmlSchemaBucketFree(ret);
return(NULL);
}
ret->locals = xmlSchemaItemListCreate();
if (ret->locals == NULL) {
- xmlFree(ret);
+ xmlSchemaBucketFree(ret);
return(NULL);
}
/*
--
2.27.0

View File

@ -0,0 +1,41 @@
From ba290a86639a6a9fc8af81936ad2d3a4d22d502f Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 5 Mar 2023 14:08:57 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlSchemaItemListAddSize
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/ba290a86639a6a9fc8af81936ad2d3a4d22d502f
Conflict:NA
---
xmlschemas.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/xmlschemas.c b/xmlschemas.c
index 4a767ac..9be7999 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -3445,14 +3445,17 @@ xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
}
list->sizeItems = initialSize;
} else if (list->sizeItems <= list->nbItems) {
+ void **tmp;
+
list->sizeItems *= 2;
- list->items = (void **) xmlRealloc(list->items,
+ tmp = (void **) xmlRealloc(list->items,
list->sizeItems * sizeof(void *));
- if (list->items == NULL) {
+ if (tmp == NULL) {
xmlSchemaPErrMemory(NULL, "growing item list", NULL);
- list->sizeItems = 0;
+ list->sizeItems /= 2;
return(-1);
}
+ list->items = tmp;
}
list->items[list->nbItems++] = item;
return(0);
--
2.27.0

View File

@ -0,0 +1,29 @@
From cfbc1f48ee6259efaedcdc485d86b90e252da970 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 5 Mar 2023 14:06:51 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlSchemaParse
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/cfbc1f48ee6259efaedcdc485d86b90e252da970
Conflict:NA
---
xmlschemas.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xmlschemas.c b/xmlschemas.c
index c68103c..fa9d113 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -21473,7 +21473,7 @@ xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
if (ctxt->constructor == NULL) {
ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
if (ctxt->constructor == NULL)
- return(NULL);
+ goto exit_failure;
/* Take ownership of the constructor to be able to free it. */
ctxt->ownsConstructor = 1;
}
--
2.27.0

View File

@ -0,0 +1,42 @@
From 961a4f35bfcbe3f2b0ca0932e880ea73cbb2ab2c Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 5 Mar 2023 14:10:41 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlSchemaParseUnion
Also report malloc failure from xmlStrndup.
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/961a4f35bfcbe3f2b0ca0932e880ea73cbb2ab2c
Conflict:NA
---
xmlschemas.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/xmlschemas.c b/xmlschemas.c
index d2f8bf1..4dbee37 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -9017,6 +9017,11 @@ xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (end == cur)
break;
tmp = xmlStrndup(cur, end - cur);
+ if (tmp == NULL) {
+ xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
+ "duplicating type name", NULL);
+ return (-1);
+ }
if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
/*
@@ -9027,6 +9032,7 @@ xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (link == NULL) {
xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
"allocating a type link", NULL);
+ FREE_AND_NULL(tmp)
return (-1);
}
link->type = NULL;
--
2.27.0

View File

@ -0,0 +1,48 @@
From f0b5515c26a65c218dcab95b411f25f2e57328d0 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 2 Nov 2022 15:44:42 +0100
Subject: [PATCH 05/28] malloc-fail: Fix memory leak in xmlStaticCopyNodeList
Found with libFuzzer, see #344.
Reference: https://github.com/GNOME/libxml2/commit/a22bd982bf10291deea8ba0c61bf75b898c604ce
Conflict: NA
---
tree.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/tree.c b/tree.c
index 84da156..b32561d 100644
--- a/tree.c
+++ b/tree.c
@@ -4388,7 +4388,7 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
}
if (doc->intSubset == NULL) {
q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
- if (q == NULL) return(NULL);
+ if (q == NULL) goto error;
q->doc = doc;
q->parent = parent;
doc->intSubset = (xmlDtdPtr) q;
@@ -4400,7 +4400,7 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
} else
#endif /* LIBXML_TREE_ENABLED */
q = xmlStaticCopyNode(node, doc, parent, 1);
- if (q == NULL) return(NULL);
+ if (q == NULL) goto error;
if (ret == NULL) {
q->prev = NULL;
ret = p = q;
@@ -4413,6 +4413,9 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
node = node->next;
}
return(ret);
+error:
+ xmlFreeNodeList(ret);
+ return(NULL);
}
/**
--
2.27.0

View File

@ -0,0 +1,120 @@
From 2fbf7876510dd9c5996151e2569078146e869697 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 2 Nov 2022 16:22:54 +0100
Subject: [PATCH 12/28] malloc-fail: Fix memory leak in xmlStringGetNodeList
Also make sure to return NULL on error instead of a partial node list.
Found with libFuzzer, see #344.
Reference: https://github.com/GNOME/libxml2/commit/b45927095e0c857b68a96466e3075d60a6a5dd9e
Conflict: NA
---
tree.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/tree.c b/tree.c
index bb85220..ac156e1 100644
--- a/tree.c
+++ b/tree.c
@@ -1496,9 +1496,9 @@ out:
*/
xmlNodePtr
xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
- xmlNodePtr ret = NULL, last = NULL;
+ xmlNodePtr ret = NULL, head = NULL, last = NULL;
xmlNodePtr node;
- xmlChar *val;
+ xmlChar *val = NULL;
const xmlChar *cur = value;
const xmlChar *q;
xmlEntityPtr ent;
@@ -1596,14 +1596,12 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
*/
if (!xmlBufIsEmpty(buf)) {
node = xmlNewDocText(doc, NULL);
- if (node == NULL) {
- if (val != NULL) xmlFree(val);
- goto out;
- }
+ if (node == NULL)
+ goto out;
node->content = xmlBufDetach(buf);
if (last == NULL) {
- last = ret = node;
+ last = head = node;
} else {
last = xmlAddNextSibling(last, node);
}
@@ -1613,11 +1611,9 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
* Create a new REFERENCE_REF node
*/
node = xmlNewReference(doc, val);
- if (node == NULL) {
- if (val != NULL) xmlFree(val);
+ if (node == NULL)
goto out;
- }
- else if ((ent != NULL) && (ent->children == NULL)) {
+ if ((ent != NULL) && (ent->children == NULL)) {
xmlNodePtr temp;
/* Set to non-NULL value to avoid recursion. */
@@ -1633,12 +1629,13 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
}
}
if (last == NULL) {
- last = ret = node;
+ last = head = node;
} else {
last = xmlAddNextSibling(last, node);
}
}
xmlFree(val);
+ val = NULL;
}
cur++;
q = cur;
@@ -1657,7 +1654,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
} else
cur++;
}
- if ((cur != q) || (ret == NULL)) {
+ if ((cur != q) || (head == NULL)) {
/*
* Handle the last piece of text.
*/
@@ -1666,21 +1663,24 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
if (!xmlBufIsEmpty(buf)) {
node = xmlNewDocText(doc, NULL);
- if (node == NULL) {
- xmlBufFree(buf);
- return(NULL);
- }
+ if (node == NULL)
+ goto out;
node->content = xmlBufDetach(buf);
if (last == NULL) {
- ret = node;
+ head = node;
} else {
xmlAddNextSibling(last, node);
}
}
+ ret = head;
+ head = NULL;
+
out:
xmlBufFree(buf);
+ if (val != NULL) xmlFree(val);
+ if (head != NULL) xmlFreeNodeList(head);
return(ret);
}
--
2.27.0

View File

@ -0,0 +1,29 @@
From 3b59fdf001f030e1b2180d3303347119e05d8dcb Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 15 Feb 2023 13:28:24 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlXIncludeAddNode
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/3b59fdf001f030e1b2180d3303347119e05d8dcb
Conflict:xinclude.c
---
xinclude.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/xinclude.c b/xinclude.c
index 6e5b61d..cc22848 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -660,6 +660,7 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
ref = xmlXIncludeNewRef(ctxt, URL, cur);
xmlFree(URL);
if (ref == NULL) {
+ xmlFree(fragment);
return(-1);
}
ref->fragment = fragment;
--
2.27.0

View File

@ -0,0 +1,164 @@
From ec05f04d8b5a0a60515235f65ed1256644a77741 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 Feb 2023 12:40:02 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlXIncludeLoadTxt
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/ec05f04d8b5a0a60515235f65ed1256644a77741
Conflict:xinclude.c
---
xinclude.c | 67 +++++++++++++++++++++++-------------------------------
1 file changed, 28 insertions(+), 39 deletions(-)
diff --git a/xinclude.c b/xinclude.c
index cc22848..c0b4439 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -1791,14 +1791,15 @@ error:
static int
xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
xmlParserInputBufferPtr buf;
- xmlNodePtr node;
- xmlURIPtr uri;
- xmlChar *URL;
+ xmlNodePtr node = NULL;
+ xmlURIPtr uri = NULL;
+ xmlChar *URL = NULL;
int i;
+ int ret = -1;
xmlChar *encoding = NULL;
xmlCharEncoding enc = (xmlCharEncoding) 0;
- xmlParserCtxtPtr pctxt;
- xmlParserInputPtr inputStream;
+ xmlParserCtxtPtr pctxt = NULL;
+ xmlParserInputPtr inputStream = NULL;
int len;
const xmlChar *content;
@@ -1814,21 +1815,19 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
if (uri == NULL) {
xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI,
"invalid value URI %s\n", url);
- return(-1);
+ goto error;
}
if (uri->fragment != NULL) {
xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_TEXT_FRAGMENT,
"fragment identifier forbidden for text: %s\n",
(const xmlChar *) uri->fragment);
- xmlFreeURI(uri);
- return(-1);
+ goto error;
}
URL = xmlSaveUri(uri);
- xmlFreeURI(uri);
if (URL == NULL) {
xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI,
"invalid value URI %s\n", url);
- return(-1);
+ goto error;
}
/*
@@ -1839,8 +1838,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
XML_XINCLUDE_TEXT_DOCUMENT,
"text serialization of document not available\n", NULL);
- xmlFree(URL);
- return(-1);
+ goto error;
}
/*
@@ -1870,11 +1868,8 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
XML_XINCLUDE_UNKNOWN_ENCODING,
"encoding %s not supported\n", encoding);
- xmlFree(encoding);
- xmlFree(URL);
- return(-1);
+ goto error;
}
- xmlFree(encoding);
}
/*
@@ -1882,27 +1877,18 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
*/
pctxt = xmlNewParserCtxt();
inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt);
- if(inputStream == NULL) {
- xmlFreeParserCtxt(pctxt);
- xmlFree(URL);
- return(-1);
- }
+ if(inputStream == NULL)
+ goto error;
buf = inputStream->buf;
- if (buf == NULL) {
- xmlFreeInputStream (inputStream);
- xmlFreeParserCtxt(pctxt);
- xmlFree(URL);
- return(-1);
- }
+ if (buf == NULL)
+ goto error;
if (buf->encoder)
xmlCharEncCloseFunc(buf->encoder);
buf->encoder = xmlGetCharEncodingHandler(enc);
node = xmlNewText(NULL);
if (node == NULL) {
- xmlFreeInputStream(inputStream);
- xmlFreeParserCtxt(pctxt);
- xmlFree(URL);
- return(-1);
+ xmlXIncludeErrMemory(ctxt, ctxt->incTab[nr]->ref, NULL);
+ goto error;
}
/*
@@ -1921,28 +1907,31 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
if (!IS_CHAR(cur)) {
xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_INVALID_CHAR,
"%s contains invalid char\n", URL);
- xmlFreeNode(node);
- xmlFreeInputStream(inputStream);
- xmlFreeParserCtxt(pctxt);
- xmlFree(URL);
- return(-1);
+ goto error;
}
i += l;
}
xmlNodeAddContentLen(node, content, len);
- xmlFreeParserCtxt(pctxt);
xmlXIncludeAddTxt(ctxt, node->content, URL);
- xmlFreeInputStream(inputStream);
loaded:
/*
* Add the element as the replacement copy.
*/
ctxt->incTab[nr]->inc = node;
+ node = NULL;
+ ret = 0;
+
+error:
+ xmlFreeNode(node);
+ xmlFreeInputStream(inputStream);
+ xmlFreeParserCtxt(pctxt);
+ xmlFree(encoding);
+ xmlFreeURI(uri);
xmlFree(URL);
- return(0);
+ return(ret);
}
/**
--
2.27.0

View File

@ -0,0 +1,51 @@
From 6f9604f0e3e52e96881ab3b662f35fbe04cd49ac Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 26 Feb 2023 16:09:50 +0100
Subject: [PATCH] malloc-fail: Fix memory leak in xmlXPathCacheNewNodeSet
Found with libFuzzer, see #344.
Reference:https://github.com/GNOME/libxml2/commit/6f9604f0e3e52e96881ab3b662f35fbe04cd49ac
Conflict:NA
---
xpath.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/xpath.c b/xpath.c
index 84b139d..1f358e3 100644
--- a/xpath.c
+++ b/xpath.c
@@ -2448,21 +2448,24 @@ xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
(cache->miscObjs->number != 0))
{
xmlXPathObjectPtr ret;
+ xmlNodeSetPtr set;
/*
* Fallback to misc-cache.
*/
+ set = xmlXPathNodeSetCreate(val);
+ if (set == NULL) {
+ ctxt->lastError.domain = XML_FROM_XPATH;
+ ctxt->lastError.code = XML_ERR_NO_MEMORY;
+ return(NULL);
+ }
+
ret = (xmlXPathObjectPtr)
cache->miscObjs->items[--cache->miscObjs->number];
ret->type = XPATH_NODESET;
ret->boolval = 0;
- ret->nodesetval = xmlXPathNodeSetCreate(val);
- if (ret->nodesetval == NULL) {
- ctxt->lastError.domain = XML_FROM_XPATH;
- ctxt->lastError.code = XML_ERR_NO_MEMORY;
- return(NULL);
- }
+ ret->nodesetval = set;
#ifdef XP_DEBUG_OBJ_USAGE
xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
#endif
--
2.27.0

Some files were not shown because too many files have changed in this diff Show More