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

openSUSE Build Service is sponsored by