From 4850c4669d41b0a4d1fc2b0d9395e647def446af Mon Sep 17 00:00:00 2001
From: Tinny Ng <tng@apache.org>
Date: Fri, 26 Jul 2002 20:31:23 +0000
Subject: [PATCH] Memory Leak in DOMDocumentTypeImpl

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@174074 13f79535-47bb-0310-9956-ffa450edef68
---
 src/xercesc/dom/impl/DOMDocumentTypeImpl.cpp |  42 ++--
 src/xercesc/dom/impl/DOMDocumentTypeImpl.hpp |   4 +-
 src/xercesc/parsers/AbstractDOMParser.cpp    | 191 ++++++++++---------
 src/xercesc/parsers/AbstractDOMParser.hpp    |   6 +
 4 files changed, 125 insertions(+), 118 deletions(-)

diff --git a/src/xercesc/dom/impl/DOMDocumentTypeImpl.cpp b/src/xercesc/dom/impl/DOMDocumentTypeImpl.cpp
index 60a0535fa..330595871 100644
--- a/src/xercesc/dom/impl/DOMDocumentTypeImpl.cpp
+++ b/src/xercesc/dom/impl/DOMDocumentTypeImpl.cpp
@@ -79,6 +79,7 @@ DOMDocumentTypeImpl::DOMDocumentTypeImpl(DOMDocument *ownerDoc,
     entities(0),
     notations(0),
     elements(0),
+    internalSubset(0),
     fIsCreatedFromHeap(heap)
 {
     if (ownerDoc) {
@@ -111,6 +112,7 @@ DOMDocumentTypeImpl::DOMDocumentTypeImpl(DOMDocument *ownerDoc,
     entities(0),
     notations(0),
     elements(0),
+    internalSubset(0),
     fIsCreatedFromHeap(heap)
 {
     if (DOMDocumentImpl::indexofQualifiedName(qualifiedName) < 0)
@@ -120,6 +122,7 @@ DOMDocumentTypeImpl::DOMDocumentTypeImpl(DOMDocument *ownerDoc,
         DOMDocumentImpl *docImpl = (DOMDocumentImpl *)ownerDoc;
         publicId = docImpl->cloneString(pubId);
         systemId = docImpl->cloneString(sysId);
+        internalSubset = docImpl->cloneString(internalSubset);
         name = ((DOMDocumentImpl *)ownerDoc)->getPooledString(qualifiedName);
         entities = new (ownerDoc) DOMNamedNodeMapImpl(this);
         notations= new (ownerDoc) DOMNamedNodeMapImpl(this);
@@ -128,6 +131,7 @@ DOMDocumentTypeImpl::DOMDocumentTypeImpl(DOMDocument *ownerDoc,
     else {
         publicId = XMLString::replicate(pubId);
         systemId = XMLString::replicate(sysId);
+        internalSubset = XMLString::replicate(internalSubset);
         name = XMLString::replicate(qualifiedName);
         entities = new DOMNamedNodeMapImpl(this);
         notations= new DOMNamedNodeMapImpl(this);
@@ -147,6 +151,7 @@ DOMDocumentTypeImpl::DOMDocumentTypeImpl(const DOMDocumentTypeImpl &other, bool
     entities(0),
     notations(0),
     elements(0),
+    internalSubset(0),
     fIsCreatedFromHeap(heap)
 {
     if ((DOMDocumentImpl *)this->fNode.getOwnerDocument()) {
@@ -156,14 +161,15 @@ DOMDocumentTypeImpl::DOMDocumentTypeImpl(const DOMDocumentTypeImpl &other, bool
         //DOM Level 2
         publicId        = other.publicId;
         systemId        = other.systemId;
+        internalSubset  = other.internalSubset;
     }
     else {
         name = XMLString::replicate(other.name);
         publicId = XMLString::replicate(other.publicId);
         systemId = XMLString::replicate(other.systemId);
+        internalSubset = XMLString::replicate(other.internalSubset);
     }
 
-    internalSubset.set(other.internalSubset.getRawBuffer());
     entities = ((DOMNamedNodeMapImpl *)other.entities)->cloneMap(this);
     notations= ((DOMNamedNodeMapImpl *)other.notations)->cloneMap(this);
     elements = ((DOMNamedNodeMapImpl *)other.elements)->cloneMap(this);
@@ -183,6 +189,9 @@ DOMDocumentTypeImpl::~DOMDocumentTypeImpl()
         temp = (XMLCh*) systemId;
         delete [] temp;
 
+        temp = (XMLCh*) internalSubset;
+        delete [] temp;
+
         delete entities;
         delete notations;
         delete elements;
@@ -223,6 +232,10 @@ void DOMDocumentTypeImpl::setOwnerDocument(DOMDocument *doc) {
             systemId = docImpl->cloneString(systemId);
             delete [] temp;
 
+            temp = (XMLCh*) internalSubset; // cast off const
+            systemId = docImpl->cloneString(internalSubset);
+            delete [] temp;
+
             temp = (XMLCh*) name; // cast off const
             name = docImpl->cloneString(name);
             delete [] temp;
@@ -314,11 +327,7 @@ const XMLCh * DOMDocumentTypeImpl::getSystemId() const
 
 const XMLCh * DOMDocumentTypeImpl::getInternalSubset() const
 {
-    const XMLCh* subset = internalSubset.getRawBuffer();
-    if (!XMLString::stringLen(subset))
-        return 0;
-    else
-        return subset;
+    return internalSubset;
 }
 
 bool DOMDocumentTypeImpl::isIntSubsetReading() const
@@ -363,20 +372,13 @@ void        DOMDocumentTypeImpl::setInternalSubset(const XMLCh *value)
     if (value == 0)
         return;
 
-    internalSubset.set(value);
-}
-
-void        DOMDocumentTypeImpl::appendInternalSubset(const XMLCh *value)
-{
-    if (value == 0)
-        return;
-
-    internalSubset.append(value);
-}
-
-void        DOMDocumentTypeImpl::appendInternalSubset(const XMLCh toAppend)
-{
-    internalSubset.append(toAppend);
+    if ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())
+        internalSubset = ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())->getPooledString(value);
+    else {
+        XMLCh* temp = (XMLCh*) internalSubset; // cast off const
+        delete [] temp;
+        internalSubset = XMLString::replicate(value);
+    }
 }
 
 void DOMDocumentTypeImpl::release()
diff --git a/src/xercesc/dom/impl/DOMDocumentTypeImpl.hpp b/src/xercesc/dom/impl/DOMDocumentTypeImpl.hpp
index 5075d6418..c95948c41 100644
--- a/src/xercesc/dom/impl/DOMDocumentTypeImpl.hpp
+++ b/src/xercesc/dom/impl/DOMDocumentTypeImpl.hpp
@@ -95,7 +95,7 @@ private:
     DOMNamedNodeMap*    elements;
     const XMLCh *       publicId;
     const XMLCh *       systemId;
-    XMLBuffer           internalSubset;
+    const XMLCh *       internalSubset;
 
     bool			         intSubsetReading;
     bool                fIsCreatedFromHeap;
@@ -103,8 +103,6 @@ private:
     virtual void        setPublicId(const XMLCh * value);
     virtual void        setSystemId(const XMLCh * value);
     virtual void        setInternalSubset(const XMLCh *value);
-    void                appendInternalSubset(const XMLCh *value);
-    void                appendInternalSubset(const XMLCh toAppend);
     bool                isIntSubsetReading() const;
 
     friend class AbstractDOMParser;
diff --git a/src/xercesc/parsers/AbstractDOMParser.cpp b/src/xercesc/parsers/AbstractDOMParser.cpp
index c9f42e64b..edd68d9be 100644
--- a/src/xercesc/parsers/AbstractDOMParser.cpp
+++ b/src/xercesc/parsers/AbstractDOMParser.cpp
@@ -115,6 +115,7 @@ AbstractDOMParser::AbstractDOMParser(XMLValidator* const valToAdopt) :
 , fDocumentVector(0)
 , fCreateCommentNodes(true)
 , fDocumentAdoptedByUser(false)
+, fInternalSubset(fBufMgr.bidOnBuffer())
 {
     //
     //  Create a scanner and tell it what validator to use. Then set us
@@ -125,9 +126,7 @@ AbstractDOMParser::AbstractDOMParser(XMLValidator* const valToAdopt) :
     fScanner->setDocTypeHandler(this);
 
     fNodeStack = new ValueStackOf<DOMNode*>(64);
-    this->reset();
-
-
+    this->reset();   
 }
 
 
@@ -886,64 +885,64 @@ void AbstractDOMParser::attDef
     {
         if (elemDecl.hasAttDefs())
         {
-            fDocumentType->appendInternalSubset(attDef.getFullName());
+            fInternalSubset.append(attDef.getFullName());
 
             // Get the type and display it
             const XMLAttDef::AttTypes type = attDef.getType();
             switch(type)
             {
             case XMLAttDef::CData :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgCDATAString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgCDATAString);
                 break;
             case XMLAttDef::ID :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgIDString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgIDString);
                 break;
             case XMLAttDef::IDRef :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgIDRefString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgIDRefString);
                 break;
             case XMLAttDef::IDRefs :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgIDRefsString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgIDRefsString);
                 break;
             case XMLAttDef::Entity :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgEntityString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgEntityString);
                 break;
             case XMLAttDef::Entities :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgEntitiesString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgEntitiesString);
                 break;
             case XMLAttDef::NmToken :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgNmTokenString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgNmTokenString);
                 break;
             case XMLAttDef::NmTokens :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgNmTokensString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgNmTokensString);
                 break;
 
             case XMLAttDef::Notation :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgNotationString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgNotationString);
                 break;
 
             case XMLAttDef::Enumeration :
-                fDocumentType->appendInternalSubset(chSpace);
+                fInternalSubset.append(chSpace);
                 const XMLCh* enumString = attDef.getEnumeration();
                 int length = XMLString::stringLen(enumString);
                 if (length > 0) {
 
-                    fDocumentType->appendInternalSubset(chOpenParen );
+                    fInternalSubset.append(chOpenParen );
                     for(int i=0; i<length; i++) {
                         if (enumString[i] == chSpace)
-                            fDocumentType->appendInternalSubset(chPipe);
+                            fInternalSubset.append(chPipe);
                         else
-                            fDocumentType->appendInternalSubset(enumString[i]);
+                            fInternalSubset.append(enumString[i]);
                     }
-                    fDocumentType->appendInternalSubset(chCloseParen);
+                    fInternalSubset.append(chCloseParen);
                 }
                 break;
             }
@@ -952,25 +951,25 @@ void AbstractDOMParser::attDef
             switch(def)
             {
             case XMLAttDef::Required :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgRequiredString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgRequiredString);
                 break;
             case XMLAttDef::Implied :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgImpliedString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgImpliedString);
                 break;
             case XMLAttDef::Fixed :
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(XMLUni::fgFixedString);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(XMLUni::fgFixedString);
                 break;
             }
 
             const XMLCh* defaultValue = attDef.getValue();
             if (defaultValue != 0) {
-                fDocumentType->appendInternalSubset(chSpace);
-                fDocumentType->appendInternalSubset(chDoubleQuote);
-                fDocumentType->appendInternalSubset(defaultValue);
-                fDocumentType->appendInternalSubset(chDoubleQuote);
+                fInternalSubset.append(chSpace);
+                fInternalSubset.append(chDoubleQuote);
+                fInternalSubset.append(defaultValue);
+                fInternalSubset.append(chDoubleQuote);
             }
         }
     }
@@ -985,13 +984,13 @@ void AbstractDOMParser::doctypeComment
     {
         if (comment != 0)
         {
-            fDocumentType->appendInternalSubset(XMLUni::fgCommentString);
-            fDocumentType->appendInternalSubset(chSpace);
-            fDocumentType->appendInternalSubset(comment);
-            fDocumentType->appendInternalSubset(chSpace);
-            fDocumentType->appendInternalSubset(chDash);
-            fDocumentType->appendInternalSubset(chDash);
-            fDocumentType->appendInternalSubset(chCloseAngle);
+            fInternalSubset.append(XMLUni::fgCommentString);
+            fInternalSubset.append(chSpace);
+            fInternalSubset.append(comment);
+            fInternalSubset.append(chSpace);
+            fInternalSubset.append(chDash);
+            fInternalSubset.append(chDash);
+            fInternalSubset.append(chCloseAngle);
         }
     }
 }
@@ -1018,13 +1017,13 @@ void AbstractDOMParser::doctypePI
     if (fDocumentType->isIntSubsetReading())
     {
         //add these chars to internalSubset variable
-        fDocumentType->appendInternalSubset(chOpenAngle);
-        fDocumentType->appendInternalSubset(chQuestion);
-        fDocumentType->appendInternalSubset(target);
-        fDocumentType->appendInternalSubset(chSpace);
-        fDocumentType->appendInternalSubset(data);
-        fDocumentType->appendInternalSubset(chQuestion);
-        fDocumentType->appendInternalSubset(chCloseAngle);
+        fInternalSubset.append(chOpenAngle);
+        fInternalSubset.append(chQuestion);
+        fInternalSubset.append(target);
+        fInternalSubset.append(chSpace);
+        fInternalSubset.append(data);
+        fInternalSubset.append(chQuestion);
+        fInternalSubset.append(chCloseAngle);
     }	
 }
 
@@ -1036,7 +1035,7 @@ void AbstractDOMParser::doctypeWhitespace
 )
 {
     if (fDocumentType->isIntSubsetReading())
-        fDocumentType->appendInternalSubset(chars);
+        fInternalSubset.append(chars);
 }
 
 void AbstractDOMParser::elementDecl
@@ -1047,20 +1046,20 @@ void AbstractDOMParser::elementDecl
 {
     if (fDocumentType->isIntSubsetReading())
     {
-        fDocumentType->appendInternalSubset(chOpenAngle);
-        fDocumentType->appendInternalSubset(chBang);
-        fDocumentType->appendInternalSubset(XMLUni::fgElemString);
-        fDocumentType->appendInternalSubset(chSpace);
-        fDocumentType->appendInternalSubset(decl.getFullName());
+        fInternalSubset.append(chOpenAngle);
+        fInternalSubset.append(chBang);
+        fInternalSubset.append(XMLUni::fgElemString);
+        fInternalSubset.append(chSpace);
+        fInternalSubset.append(decl.getFullName());
 
         //get the ContentSpec information
         const XMLCh* contentModel = decl.getFormattedContentModel();
         if (contentModel != 0) {
-            fDocumentType->appendInternalSubset(chSpace);
-            fDocumentType->appendInternalSubset(contentModel);
+            fInternalSubset.append(chSpace);
+            fInternalSubset.append(contentModel);
         }
 
-        fDocumentType->appendInternalSubset(chCloseAngle);
+        fInternalSubset.append(chCloseAngle);
     }
 }
 
@@ -1072,7 +1071,7 @@ void AbstractDOMParser::endAttList
     if (fDocumentType->isIntSubsetReading())
     {
         //print the closing angle
-        fDocumentType->appendInternalSubset(chCloseAngle);
+        fInternalSubset.append(chCloseAngle);
     }
 
 	// this section sets up default attributes.
@@ -1164,7 +1163,9 @@ void AbstractDOMParser::endAttList
 
 void AbstractDOMParser::endIntSubset()
 {
-	fDocumentType->intSubsetReading = false;
+    fDocumentType->setInternalSubset(fInternalSubset.getRawBuffer());
+    fBufMgr.releaseBuffer(fInternalSubset);
+    fDocumentType->intSubsetReading = false;
 }
 
 void AbstractDOMParser::endExtSubset()
@@ -1193,50 +1194,50 @@ void AbstractDOMParser::entityDecl
     if (fDocumentType->isIntSubsetReading())
     {
         //add thes chars to internalSubset variable
-        fDocumentType->appendInternalSubset(chOpenAngle);
-        fDocumentType->appendInternalSubset(chBang);
-        fDocumentType->appendInternalSubset(XMLUni::fgEntityString);
-        fDocumentType->appendInternalSubset(chSpace);
+        fInternalSubset.append(chOpenAngle);
+        fInternalSubset.append(chBang);
+        fInternalSubset.append(XMLUni::fgEntityString);
+        fInternalSubset.append(chSpace);
 
-        fDocumentType->appendInternalSubset(entityDecl.getName());
+        fInternalSubset.append(entityDecl.getName());
 
         const XMLCh* id = entity->getPublicId();
         if (id != 0) {
-            fDocumentType->appendInternalSubset(chSpace);
-            fDocumentType->appendInternalSubset(XMLUni::fgPubIDString);
-            fDocumentType->appendInternalSubset(chSpace);
-            fDocumentType->appendInternalSubset(chDoubleQuote);
-            fDocumentType->appendInternalSubset(id);
-            fDocumentType->appendInternalSubset(chDoubleQuote);
+            fInternalSubset.append(chSpace);
+            fInternalSubset.append(XMLUni::fgPubIDString);
+            fInternalSubset.append(chSpace);
+            fInternalSubset.append(chDoubleQuote);
+            fInternalSubset.append(id);
+            fInternalSubset.append(chDoubleQuote);
         }
         id = entity->getSystemId();
         if (id != 0) {
-            fDocumentType->appendInternalSubset(chSpace);
-            fDocumentType->appendInternalSubset(XMLUni::fgSysIDString);
-            fDocumentType->appendInternalSubset(chSpace);
-            fDocumentType->appendInternalSubset(chDoubleQuote);
-            fDocumentType->appendInternalSubset(id);
-            fDocumentType->appendInternalSubset(chDoubleQuote);
+            fInternalSubset.append(chSpace);
+            fInternalSubset.append(XMLUni::fgSysIDString);
+            fInternalSubset.append(chSpace);
+            fInternalSubset.append(chDoubleQuote);
+            fInternalSubset.append(id);
+            fInternalSubset.append(chDoubleQuote);
 
         }
         id = entity->getNotationName();
         if (id != 0) {
-            fDocumentType->appendInternalSubset(chSpace);
-            fDocumentType->appendInternalSubset(XMLUni::fgNDATAString);
-            fDocumentType->appendInternalSubset(chSpace);
-            fDocumentType->appendInternalSubset(chDoubleQuote);
-            fDocumentType->appendInternalSubset(id);
-            fDocumentType->appendInternalSubset(chDoubleQuote);
+            fInternalSubset.append(chSpace);
+            fInternalSubset.append(XMLUni::fgNDATAString);
+            fInternalSubset.append(chSpace);
+            fInternalSubset.append(chDoubleQuote);
+            fInternalSubset.append(id);
+            fInternalSubset.append(chDoubleQuote);
         }
         id = entityDecl.getValue();
         if (id !=0) {
-            fDocumentType->appendInternalSubset(chSpace);
-            fDocumentType->appendInternalSubset(chDoubleQuote);
-            fDocumentType->appendInternalSubset(id);
-            fDocumentType->appendInternalSubset(chDoubleQuote);
+            fInternalSubset.append(chSpace);
+            fInternalSubset.append(chDoubleQuote);
+            fInternalSubset.append(id);
+            fInternalSubset.append(chDoubleQuote);
         }
 
-        fDocumentType->appendInternalSubset(chCloseAngle);
+        fInternalSubset.append(chCloseAngle);
     }
 
 }
@@ -1268,11 +1269,11 @@ void AbstractDOMParser::startAttList
 {
     if (fDocumentType->isIntSubsetReading())
     {
-        fDocumentType->appendInternalSubset(chOpenAngle);
-        fDocumentType->appendInternalSubset(chBang);
-        fDocumentType->appendInternalSubset(XMLUni::fgAttListString);
-        fDocumentType->appendInternalSubset(chSpace);
-        fDocumentType->appendInternalSubset(elemDecl.getFullName());
+        fInternalSubset.append(chOpenAngle);
+        fInternalSubset.append(chBang);
+        fInternalSubset.append(XMLUni::fgAttListString);
+        fInternalSubset.append(chSpace);
+        fInternalSubset.append(elemDecl.getFullName());
     }
 }
 
diff --git a/src/xercesc/parsers/AbstractDOMParser.hpp b/src/xercesc/parsers/AbstractDOMParser.hpp
index 8638316f9..08046b303 100644
--- a/src/xercesc/parsers/AbstractDOMParser.hpp
+++ b/src/xercesc/parsers/AbstractDOMParser.hpp
@@ -1339,6 +1339,11 @@ private :
     //      The DOMDocument ownership has been transferred to application
     //      If set to true, the parser does not own the document anymore
     //      and thus will not release its memory.
+    //
+    //  fInternalSubset
+    //      Buffer for storing the internal subset information.
+    //      Once complete (after DOCTYPE is finished scanning), send
+    //      it to DocumentType Node
     // -----------------------------------------------------------------------
     bool                          fCreateEntityReferenceNodes;
     bool                          fIncludeIgnorableWhitespace;
@@ -1355,6 +1360,7 @@ private :
     RefVectorOf<DOMDocumentImpl>* fDocumentVector;
     bool                          fCreateCommentNodes;
     bool                          fDocumentAdoptedByUser;
+    XMLBuffer&                    fInternalSubset;
 };
 
 
-- 
GitLab