From: sungta <tadinhsung@gmail.com>
Date: Mon, 23 Oct 2017 14:04:59 +0700
Subject: [6/8] Fix replaceChild
Origin: https://github.com/shlomif/perl-XML-LibXML/commit/a83e805fdd968e6065db1293bfe5f91cc1c5fea6
Bug-Debian: https://bugs.debian.org/866676
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-10672
Bug: https://rt.cpan.org/Public/Bug/Display.html?id=122246

if newNode == oldNode or self == newNode then do nothing, just return nNode.
---
 LibXML.xs | 70 ++++++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 38 insertions(+), 32 deletions(-)

diff --git a/LibXML.xs b/LibXML.xs
index ad415c8..718f7db 100644
--- a/LibXML.xs
+++ b/LibXML.xs
@@ -4829,40 +4829,46 @@ replaceChild( self, nNode, oNode )
     PREINIT:
         xmlNodePtr ret = NULL;
     CODE:
-       if ( self->type == XML_DOCUMENT_NODE ) {
-                switch ( nNode->type ) {
-                case XML_ELEMENT_NODE:
-                    warn("replaceChild with an element on a document node not supported yet!");
-                    XSRETURN_UNDEF;
-                    break;
-                case XML_DOCUMENT_FRAG_NODE:
-                    warn("replaceChild with a document fragment node on a document node not supported yet!");
-                    XSRETURN_UNDEF;
-                    break;
-                case XML_TEXT_NODE:
-                case XML_CDATA_SECTION_NODE:
-                    warn("replaceChild with a text node not supported on a document node!");
-                    XSRETURN_UNDEF;
-                    break;
-                default:
-                    break;
-                }
-        }
-        ret = domReplaceChild( self, nNode, oNode );
-        if (ret == NULL) {
-            XSRETURN_UNDEF;
-        }
-        else {
-            LibXML_reparent_removed_node(ret);
-            RETVAL = PmmNodeToSv(ret, PmmOWNERPO(PmmPROXYNODE(ret)));
-            if (nNode->type == XML_DTD_NODE) {
-                LibXML_set_int_subset(nNode->doc, nNode);
+        // if newNode == oldNode or self == newNode then do nothing, just return nNode.
+        if(nNode == oNode || self == nNode ){ 
+          RETVAL = nNode;
+        }
+        else{
+            if ( self->type == XML_DOCUMENT_NODE ) {
+                    switch ( nNode->type ) {
+                    case XML_ELEMENT_NODE:
+                        warn("replaceChild with an element on a document node not supported yet!");
+                        XSRETURN_UNDEF;
+                        break;
+                    case XML_DOCUMENT_FRAG_NODE:
+                        warn("replaceChild with a document fragment node on a document node not supported yet!");
+                        XSRETURN_UNDEF;
+                        break;
+                    case XML_TEXT_NODE:
+                    case XML_CDATA_SECTION_NODE:
+                        warn("replaceChild with a text node not supported on a document node!");
+                        XSRETURN_UNDEF;
+                        break;
+                    default:
+                        break;
+                    }
             }
-            if ( nNode->_private != NULL ) {
-                PmmFixOwner( PmmPROXYNODE(nNode),
-                             PmmOWNERPO(PmmPROXYNODE(self)) );
+            ret = domReplaceChild( self, nNode, oNode );
+            if (ret == NULL) {
+                XSRETURN_UNDEF;
             }
-        }
+            else {
+                LibXML_reparent_removed_node(ret);
+                RETVAL = PmmNodeToSv(ret, PmmOWNERPO(PmmPROXYNODE(ret)));
+                if (nNode->type == XML_DTD_NODE) {
+                    LibXML_set_int_subset(nNode->doc, nNode);
+                }
+                if ( nNode->_private != NULL ) {
+                    PmmFixOwner( PmmPROXYNODE(nNode),
+                                 PmmOWNERPO(PmmPROXYNODE(self)) );
+                }
+            }
+      }
     OUTPUT:
         RETVAL
 
-- 
2.15.0.rc2

