From 7c9252b74c07a86c9f70d24c072046f97a6a637e Mon Sep 17 00:00:00 2001
From: Gareth Reakes <gareth@apache.org>
Date: Wed, 30 Apr 2003 15:50:23 +0000
Subject: [PATCH] Fix to the ever expanding entity problem. Big thanks to
 Tinny.

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@174939 13f79535-47bb-0310-9956-ffa450edef68
---
 src/xercesc/dom/impl/DOMDocumentImpl.cpp      |  7 +++++
 src/xercesc/dom/impl/DOMDocumentImpl.hpp      |  4 +++
 .../dom/impl/DOMEntityReferenceImpl.cpp       | 29 +++++++++++++++++++
 .../dom/impl/DOMEntityReferenceImpl.hpp       |  1 +
 src/xercesc/parsers/AbstractDOMParser.cpp     |  2 +-
 5 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/src/xercesc/dom/impl/DOMDocumentImpl.cpp b/src/xercesc/dom/impl/DOMDocumentImpl.cpp
index aa9c7f20f..3d6adb5ef 100644
--- a/src/xercesc/dom/impl/DOMDocumentImpl.cpp
+++ b/src/xercesc/dom/impl/DOMDocumentImpl.cpp
@@ -362,7 +362,14 @@ DOMEntityReference *DOMDocumentImpl::createEntityReference(const XMLCh *nam)
     return new (this, DOMDocumentImpl::ENTITY_REFERENCE_OBJECT) DOMEntityReferenceImpl(this, nam);
 };
 
+DOMEntityReference *DOMDocumentImpl::createEntityReferenceByParser(const XMLCh *nam)
+{
+    if (!nam || !isXMLName(nam))
+        throw DOMException(
+        DOMException::INVALID_CHARACTER_ERR, 0);
 
+    return new (this, DOMDocumentImpl::ENTITY_REFERENCE_OBJECT) DOMEntityReferenceImpl(this, nam, false);
+};
 
 DOMNotation *DOMDocumentImpl::createNotation(const XMLCh *nam)
 {
diff --git a/src/xercesc/dom/impl/DOMDocumentImpl.hpp b/src/xercesc/dom/impl/DOMDocumentImpl.hpp
index f813d2889..ecdcc11c8 100644
--- a/src/xercesc/dom/impl/DOMDocumentImpl.hpp
+++ b/src/xercesc/dom/impl/DOMDocumentImpl.hpp
@@ -197,6 +197,10 @@ public:
     virtual void                 removeNodeIterator(DOMNodeIteratorImpl* nodeIterator); //non-standard api
 
 
+    // Extension to be called by the Parser
+    DOMEntityReference*  createEntityReferenceByParser(const XMLCh * name);
+
+
     //
     // Functions to keep track of document mutations, so that node list chached
     //   information can be invalidated.  One global changes counter per document.
diff --git a/src/xercesc/dom/impl/DOMEntityReferenceImpl.cpp b/src/xercesc/dom/impl/DOMEntityReferenceImpl.cpp
index ad60caf58..0b626f520 100644
--- a/src/xercesc/dom/impl/DOMEntityReferenceImpl.cpp
+++ b/src/xercesc/dom/impl/DOMEntityReferenceImpl.cpp
@@ -98,6 +98,35 @@ DOMEntityReferenceImpl::DOMEntityReferenceImpl(DOMDocument *ownerDoc,
 }
 
 
+DOMEntityReferenceImpl::DOMEntityReferenceImpl(DOMDocument *ownerDoc,
+                                         const XMLCh *entityName,
+                                         bool cloneChild)
+    : fNode(ownerDoc), fParent(ownerDoc), fBaseURI(0)
+{
+    fName = ((DOMDocumentImpl *)getOwnerDocument())->getPooledString(entityName);
+    // EntityReference behaves as a read-only node, since its contents
+    // reflect the Entity it refers to -- but see setNodeName().
+    //retrieve the corresponding entity content
+
+    if (ownerDoc) {
+        if (ownerDoc->getDoctype()) {
+            if (ownerDoc->getDoctype()->getEntities()) {
+                DOMEntityImpl* entity = (DOMEntityImpl*)ownerDoc->getDoctype()->getEntities()->getNamedItem(entityName);
+                if (entity) {
+                    fBaseURI = entity->getBaseURI();
+                    if (cloneChild) {
+                        DOMEntityReference* refEntity = entity->getEntityRef();
+                        if (refEntity) {
+                            fParent.cloneChildren(refEntity);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    fNode.setReadOnly(true, true);
+}
 
 DOMEntityReferenceImpl::DOMEntityReferenceImpl(const DOMEntityReferenceImpl &other,
                                          bool deep)
diff --git a/src/xercesc/dom/impl/DOMEntityReferenceImpl.hpp b/src/xercesc/dom/impl/DOMEntityReferenceImpl.hpp
index 3c54dc28f..a2100e2b0 100644
--- a/src/xercesc/dom/impl/DOMEntityReferenceImpl.hpp
+++ b/src/xercesc/dom/impl/DOMEntityReferenceImpl.hpp
@@ -94,6 +94,7 @@ private:
 
 public:
     DOMEntityReferenceImpl(DOMDocument *ownerDoc, const XMLCh *entityName);
+    DOMEntityReferenceImpl(DOMDocument *ownerDoc, const XMLCh *entityName, bool cloneChild);
     DOMEntityReferenceImpl(const DOMEntityReferenceImpl &other, bool deep=false);
     virtual ~DOMEntityReferenceImpl();
 
diff --git a/src/xercesc/parsers/AbstractDOMParser.cpp b/src/xercesc/parsers/AbstractDOMParser.cpp
index bc7f9a838..0bcc9c586 100644
--- a/src/xercesc/parsers/AbstractDOMParser.cpp
+++ b/src/xercesc/parsers/AbstractDOMParser.cpp
@@ -1015,7 +1015,7 @@ void AbstractDOMParser::startEntityReference(const XMLEntityDecl& entDecl)
         entity->setActualEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
     fCurrentEntity = entity;
 
-    DOMEntityReference *er = fDocument->createEntityReference(entName);
+    DOMEntityReference *er = fDocument->createEntityReferenceByParser(entName);
 
     //set the readOnly flag to false before appending node, will be reset in endEntityReference
     DOMEntityReferenceImpl *erImpl = (DOMEntityReferenceImpl *) er;
-- 
GitLab