From 477d91c30f0ba433a35e3d6bcf69ea5ef3f75a5f Mon Sep 17 00:00:00 2001
From: lsh123 <aleksey@aleksey.com>
Date: Mon, 2 Jul 2018 16:48:09 -0700
Subject: [PATCH] fix xmlSecParseMemory() memory leak (issue #199) (#202)

---
 src/parser.c | 35 +++++++++++++++++++++++++++++++----
 src/xslt.c   |  4 ++++
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/src/parser.c b/src/parser.c
index e18b2d3..ddeb590 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -132,6 +132,10 @@ xmlSecParserFinalize(xmlSecTransformPtr transform) {
     xmlSecAssert(ctx != NULL);
 
     if(ctx->parserCtx != NULL) {
+        if(ctx->parserCtx->myDoc != NULL) {
+            xmlFreeDoc(ctx->parserCtx->myDoc);
+	    ctx->parserCtx->myDoc = NULL;
+        }
         xmlFreeParserCtxt(ctx->parserCtx);
     }
     memset(ctx, 0, sizeof(xmlSecParserCtx));
@@ -294,6 +298,10 @@ xmlSecParserPopXml(xmlSecTransformPtr transform, xmlSecNodeSetPtr* nodes,
         xmlSecXmlParserError("inputPush", ctxt,
                              xmlSecTransformGetName(transform));
         xmlFreeInputStream(input);
+        if(ctxt->myDoc != NULL) {
+            xmlFreeDoc(ctxt->myDoc);
+            ctxt->myDoc = NULL;
+        }
         xmlFreeParserCtxt(ctxt);
         return(-1);
     }
@@ -404,20 +412,27 @@ xmlSecParseFile(const char *filename) {
         xmlSecXmlParserError2("xmlParseDocument", ctxt, NULL,
                               "filename=%s",
                               xmlSecErrorsSafeString(filename));
+        if(ctxt->myDoc != NULL) {
+            xmlFreeDoc(ctxt->myDoc);
+            ctxt->myDoc = NULL;
+        }
         xmlFreeParserCtxt(ctxt);
         return(NULL);
     }
 
     if(!ctxt->wellFormed) {
        xmlSecInternalError("document is not well formed", NULL);
-       xmlFreeDoc(ctxt->myDoc);
-       ctxt->myDoc = NULL;
+       if(ctxt->myDoc != NULL) {
+           xmlFreeDoc(ctxt->myDoc);
+           ctxt->myDoc = NULL;
+       }
        xmlFreeParserCtxt(ctxt);
        return(NULL);
     }
 
     /* done */
     res = ctxt->myDoc;
+    ctxt->myDoc = NULL;
     xmlFreeParserCtxt(ctxt);
     return(res);
 
@@ -495,9 +510,14 @@ xmlSecParseMemoryExt(const xmlSecByte *prefix, xmlSecSize prefixSize,
         goto done;
     }
     doc = ctxt->myDoc;
+    ctxt->myDoc = NULL;
 
 done:
     if(ctxt != NULL) {
+        if(ctxt->myDoc != NULL) {
+            xmlFreeDoc(ctxt->myDoc);
+            ctxt->myDoc = NULL;
+        }
         xmlFreeParserCtxt(ctxt);
     }
     return(doc);
@@ -536,20 +556,27 @@ xmlSecParseMemory(const xmlSecByte *buffer, xmlSecSize size, int recovery) {
     ret = xmlParseDocument(ctxt);
     if(ret < 0) {
         xmlSecXmlParserError("xmlParseDocument", ctxt, NULL);
+        if(ctxt->myDoc != NULL) {
+            xmlFreeDoc(ctxt->myDoc);
+            ctxt->myDoc = NULL;
+        }	
         xmlFreeParserCtxt(ctxt);
         return(NULL);
     }
 
     if(!(ctxt->wellFormed) && !recovery) {
         xmlSecInternalError("document is not well formed", NULL);
-        xmlFreeDoc(ctxt->myDoc);
-        ctxt->myDoc = NULL;
+        if(ctxt->myDoc != NULL) {
+            xmlFreeDoc(ctxt->myDoc);
+            ctxt->myDoc = NULL;
+        }
         xmlFreeParserCtxt(ctxt);
         return(NULL);
     }
 
     /* done */
     res = ctxt->myDoc;
+    ctxt->myDoc = NULL;
     xmlFreeParserCtxt(ctxt);
     return(res);
 }
diff --git a/src/xslt.c b/src/xslt.c
index 2f43e41..1822cdc 100644
--- a/src/xslt.c
+++ b/src/xslt.c
@@ -219,6 +219,10 @@ xmlSecXsltFinalize(xmlSecTransformPtr transform) {
         xsltFreeStylesheet(ctx->xslt);
     }
     if(ctx->parserCtx != NULL) {
+        if(ctx->parserCtx->myDoc != NULL) {
+            xmlFreeDoc(ctx->parserCtx->myDoc);
+	    ctx->parserCtx->myDoc = NULL;
+        }
         xmlFreeParserCtxt(ctx->parserCtx);
     }
     memset(ctx, 0, sizeof(xmlSecXsltCtx));
-- 
1.7.12.4

