File libxml2-NULL-deref-xmlDumpElementContent.patch of Package libxml2.3901
From 9de7cf0cfe4deffdb520d38ef241c53a9e95449e Mon Sep 17 00:00:00 2001
Message-Id: <9de7cf0cfe4deffdb520d38ef241c53a9e95449e.1481870083.git.npajkovsky@suse.cz>
From: Nikola Pajkovsky <npajkovsky@suse.cz>
Date: Wed, 14 Dec 2016 14:46:10 +0100
Subject: [PATCH] fix NULL deref in xmlDumpElementContent()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
running xmllint --recover for xml in bottom causes segmentation
fault in xmlDumpElementContent().
0x00007ffff78944e3 in xmlDumpElementContent (buf=0x62ec90, content=0x62d3f0, glob=1) at valid.c:1181
1181 if ((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
(gdb) p *content
$1 = {
type = XML_ELEMENT_CONTENT_SEQ,
ocur = XML_ELEMENT_CONTENT_ONCE,
name = 0x0,
c1 = 0x62d3b0,
c2 = 0x0, <--- NULL deref
parent = 0x62d470,
prefix = 0x0
}
It has been fixed by testing ->c1 and ->c2 before dereferencing and it
seems to work.
However, I have seen this code for the first time and I don't know, if
parser can return xmlElementContentPtr with one of its child NULL.
<?xml version="1.0"?>
<!DOCTYPE root [
<!ELEMENT root (a,b)>
<!ELEMENT a EMPTY>
<!ELEMENT b (#PCDATA|c)* >
<!ELEMENT c ANY>
<!ELEMENT d ANY>
<!ELEMENT e ANY>
<!ELEMENT f ANY>
<!--* test all pble children,cp,choice,seq patterns in P47,P48,P49,P-->
<!ELEMENT child0 (a)>
<!ELEMENT child1 (a|b|c)>
<!ELEMENT child2 (a ,b,b?,a*,c,c,a,a,b+,c ) >
<!ELEMENT child3 (a+|b)? >
<!ELEMENT child4 (a, (b|cp+, (a|d)?, (e|f)* )?>
<!ELEMENT child5 ( (a,b) | c? | ((d|e),b,c) )* >
<!ELEMENT child5_1 ( (a半)* | (c,b)? | (d,a)+ | ((e|f),b,c) )* >
<!ELEMENT child6 (a,b,c)*>
<!ELEMENT child7 ((a,b)|c*|((d|e),b,c) )+ >
<!ELEMENT child8 ( a, (bb), b)+>
]>
<root><a/><b>
<c></c >
content of b element
</b></root>
<!--* test: tests P47,P48,P49,P50*-->
Signed-off-by: Nikola Pajkovsky <npajkovsky@suse.cz>
---
valid.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/valid.c b/valid.c
index 19f84b826233..8bd8336573a4 100644
--- a/valid.c
+++ b/valid.c
@@ -1172,29 +1172,29 @@ xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob)
xmlBufferWriteCHAR(buf, content->name);
break;
case XML_ELEMENT_CONTENT_SEQ:
- if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
- (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
+ if (content->c1 && ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
+ (content->c1->type == XML_ELEMENT_CONTENT_SEQ)))
xmlDumpElementContent(buf, content->c1, 1);
else
xmlDumpElementContent(buf, content->c1, 0);
xmlBufferWriteChar(buf, " , ");
- if ((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
+ if (content->c2 && ((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
((content->c2->type == XML_ELEMENT_CONTENT_SEQ) &&
- (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)))
+ (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE))))
xmlDumpElementContent(buf, content->c2, 1);
else
xmlDumpElementContent(buf, content->c2, 0);
break;
case XML_ELEMENT_CONTENT_OR:
- if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
- (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
+ if (content->c1 && ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
+ (content->c1->type == XML_ELEMENT_CONTENT_SEQ)))
xmlDumpElementContent(buf, content->c1, 1);
else
xmlDumpElementContent(buf, content->c1, 0);
xmlBufferWriteChar(buf, " | ");
- if ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) ||
+ if (content->c2 && ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) ||
((content->c2->type == XML_ELEMENT_CONTENT_OR) &&
- (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)))
+ (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE))))
xmlDumpElementContent(buf, content->c2, 1);
else
xmlDumpElementContent(buf, content->c2, 0);
--
2.10.2