[libxml2] Fix exponential runtime and memory in xi:fallback processing



commit 1abf2967f955858764a6de5d7b7fe247cb637853
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Thu Aug 6 17:51:57 2020 +0200

    Fix exponential runtime and memory in xi:fallback processing
    
    When creating XML_XINCLUDE_START nodes, the children of the original
    xi:include node must be freed, otherwise fallback content is copied
    twice, doubling runtime and memory consumption for each nested
    xi:fallback/xi:include pair.
    
    Found with libFuzzer.

 result/XInclude/fallback5.xml     |  51 +++++++++++++++++
 result/XInclude/fallback5.xml.rdr | 116 ++++++++++++++++++++++++++++++++++++++
 test/XInclude/docs/fallback5.xml  |  83 +++++++++++++++++++++++++++
 xinclude.c                        |   8 +++
 4 files changed, 258 insertions(+)
---
diff --git a/result/XInclude/fallback5.xml b/result/XInclude/fallback5.xml
new file mode 100644
index 000000000..0ba503d99
--- /dev/null
+++ b/result/XInclude/fallback5.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<a>
+ 
+   <elem/>
+   
+     <elem/>
+     
+       <elem/>
+       
+         <elem/>
+         
+           <elem/>
+           
+             <elem/>
+             
+               <elem/>
+               
+                 <elem/>
+                 
+                   <elem/>
+                   
+                     <elem/>
+                     
+                       <elem/>
+                       
+                         <elem/>
+                         
+                           <elem/>
+                           
+                             <elem/>
+                             
+                               <elem/>
+                               
+                                 <elem/>
+                                
+                              
+                            
+                          
+                        
+                      
+                    
+                  
+                
+              
+            
+          
+        
+      
+    
+  
+</a>
diff --git a/result/XInclude/fallback5.xml.rdr b/result/XInclude/fallback5.xml.rdr
new file mode 100644
index 000000000..0e1dab71c
--- /dev/null
+++ b/result/XInclude/fallback5.xml.rdr
@@ -0,0 +1,116 @@
+0 1 a 0 0
+1 14 #text 0 1 
+ 
+1 14 #text 0 1 
+   
+1 1 elem 1 0
+1 14 #text 0 1 
+   
+1 14 #text 0 1 
+     
+1 1 elem 1 0
+1 14 #text 0 1 
+     
+1 14 #text 0 1 
+       
+1 1 elem 1 0
+1 14 #text 0 1 
+       
+1 14 #text 0 1 
+         
+1 1 elem 1 0
+1 14 #text 0 1 
+         
+1 14 #text 0 1 
+           
+1 1 elem 1 0
+1 14 #text 0 1 
+           
+1 14 #text 0 1 
+             
+1 1 elem 1 0
+1 14 #text 0 1 
+             
+1 14 #text 0 1 
+               
+1 1 elem 1 0
+1 14 #text 0 1 
+               
+1 14 #text 0 1 
+                 
+1 1 elem 1 0
+1 14 #text 0 1 
+                 
+1 14 #text 0 1 
+                   
+1 1 elem 1 0
+1 14 #text 0 1 
+                   
+1 14 #text 0 1 
+                     
+1 1 elem 1 0
+1 14 #text 0 1 
+                     
+1 14 #text 0 1 
+                       
+1 1 elem 1 0
+1 14 #text 0 1 
+                       
+1 14 #text 0 1 
+                         
+1 1 elem 1 0
+1 14 #text 0 1 
+                         
+1 14 #text 0 1 
+                           
+1 1 elem 1 0
+1 14 #text 0 1 
+                           
+1 14 #text 0 1 
+                             
+1 1 elem 1 0
+1 14 #text 0 1 
+                             
+1 14 #text 0 1 
+                               
+1 1 elem 1 0
+1 14 #text 0 1 
+                               
+1 14 #text 0 1 
+                                 
+1 1 elem 1 0
+1 14 #text 0 1 
+                                
+1 14 #text 0 1 
+                              
+1 14 #text 0 1 
+                            
+1 14 #text 0 1 
+                          
+1 14 #text 0 1 
+                        
+1 14 #text 0 1 
+                      
+1 14 #text 0 1 
+                    
+1 14 #text 0 1 
+                  
+1 14 #text 0 1 
+                
+1 14 #text 0 1 
+              
+1 14 #text 0 1 
+            
+1 14 #text 0 1 
+          
+1 14 #text 0 1 
+        
+1 14 #text 0 1 
+      
+1 14 #text 0 1 
+    
+1 14 #text 0 1 
+  
+1 14 #text 0 1 
+
+0 15 a 0 0
diff --git a/test/XInclude/docs/fallback5.xml b/test/XInclude/docs/fallback5.xml
new file mode 100644
index 000000000..d3ad42461
--- /dev/null
+++ b/test/XInclude/docs/fallback5.xml
@@ -0,0 +1,83 @@
+<a>
+ <xi:include href="a01.xml" xmlns:xi="http://www.w3.org/2001/XInclude";>
+  <xi:fallback>
+   <elem/>
+   <xi:include href="a02.xml">
+    <xi:fallback>
+     <elem/>
+     <xi:include href="a03.xml">
+      <xi:fallback>
+       <elem/>
+       <xi:include href="a04.xml">
+        <xi:fallback>
+         <elem/>
+         <xi:include href="a05.xml">
+          <xi:fallback>
+           <elem/>
+           <xi:include href="a06.xml">
+            <xi:fallback>
+             <elem/>
+             <xi:include href="a07.xml">
+              <xi:fallback>
+               <elem/>
+               <xi:include href="a08.xml">
+                <xi:fallback>
+                 <elem/>
+                 <xi:include href="a09.xml">
+                  <xi:fallback>
+                   <elem/>
+                   <xi:include href="a10.xml">
+                    <xi:fallback>
+                     <elem/>
+                     <xi:include href="a11.xml">
+                      <xi:fallback>
+                       <elem/>
+                       <xi:include href="a12.xml">
+                        <xi:fallback>
+                         <elem/>
+                         <xi:include href="a13.xml">
+                          <xi:fallback>
+                           <elem/>
+                           <xi:include href="a14.xml">
+                            <xi:fallback>
+                             <elem/>
+                             <xi:include href="a15.xml">
+                              <xi:fallback>
+                               <elem/>
+                               <xi:include href="a16.xml">
+                                <xi:fallback>
+                                 <elem/>
+                                </xi:fallback>
+                               </xi:include>
+                              </xi:fallback>
+                             </xi:include>
+                            </xi:fallback>
+                           </xi:include>
+                          </xi:fallback>
+                         </xi:include>
+                        </xi:fallback>
+                       </xi:include>
+                      </xi:fallback>
+                     </xi:include>
+                    </xi:fallback>
+                   </xi:include>
+                  </xi:fallback>
+                 </xi:include>
+                </xi:fallback>
+               </xi:include>
+              </xi:fallback>
+             </xi:include>
+            </xi:fallback>
+           </xi:include>
+          </xi:fallback>
+         </xi:include>
+        </xi:fallback>
+       </xi:include>
+      </xi:fallback>
+     </xi:include>
+    </xi:fallback>
+   </xi:include>
+  </xi:fallback>
+ </xi:include>
+</a>
+
diff --git a/xinclude.c b/xinclude.c
index 2917d4565..5ea87adec 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -2260,11 +2260,19 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
        xmlUnlinkNode(cur);
        xmlFreeNode(cur);
     } else {
+        xmlNodePtr child, next;
+
        /*
         * Change the current node as an XInclude start one, and add an
         * XInclude end one
         */
        cur->type = XML_XINCLUDE_START;
+        /* Remove fallback children */
+        for (child = cur->children; child != NULL; child = next) {
+            next = child->next;
+            xmlUnlinkNode(child);
+            xmlFreeNode(child);
+        }
        end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL);
        if (end == NULL) {
            xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]