From d3d26867f9b58d995fd3acef16ad15350c05ac93 Mon Sep 17 00:00:00 2001
From: Alberto Massari <amassari@apache.org>
Date: Tue, 17 Apr 2012 09:35:00 +0000
Subject: [PATCH] Verify that the pooled string has the requested length, to
 avoid the case when multiple strings share the same hash code and starts with
 the same substring (XERCESC-1978)

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@1327014 13f79535-47bb-0310-9956-ffa450edef68
---
 src/xercesc/dom/impl/DOMDocumentImpl.hpp | 12 +++++++-----
 src/xercesc/dom/impl/DOMStringPool.hpp   |  3 ++-
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/xercesc/dom/impl/DOMDocumentImpl.hpp b/src/xercesc/dom/impl/DOMDocumentImpl.hpp
index ed0d84d98..0ed9aa6dc 100644
--- a/src/xercesc/dom/impl/DOMDocumentImpl.hpp
+++ b/src/xercesc/dom/impl/DOMDocumentImpl.hpp
@@ -360,6 +360,7 @@ inline const XMLCh*  DOMDocumentImpl::getPooledString(const XMLCh *in)
 {
   if (in == 0)
     return 0;
+  XMLSize_t n = XMLString::stringLen(in);
 
   DOMStringPoolEntry    **pspe;
   DOMStringPoolEntry    *spe;
@@ -368,7 +369,7 @@ inline const XMLCh*  DOMDocumentImpl::getPooledString(const XMLCh *in)
   pspe = &fNameTable[inHash];
   while (*pspe != 0)
   {
-    if (XMLString::equals((*pspe)->fString, in))
+    if ((*pspe)->fLength == n && XMLString::equals((*pspe)->fString, in))
       return (*pspe)->fString;
     pspe = &((*pspe)->fNext);
   }
@@ -380,16 +381,16 @@ inline const XMLCh*  DOMDocumentImpl::getPooledString(const XMLCh *in)
   // declared in the struct, so we don't need to add one again to
   // account for the trailing null.
   //
-  XMLSize_t sizeToAllocate = sizeof(DOMStringPoolEntry) + XMLString::stringLen(in)*sizeof(XMLCh);
+  XMLSize_t sizeToAllocate = sizeof(DOMStringPoolEntry) + n*sizeof(XMLCh);
   *pspe = spe = (DOMStringPoolEntry *)allocate(sizeToAllocate);
+  spe->fLength = n;
   spe->fNext = 0;
   XMLString::copyString((XMLCh*)spe->fString, in);
 
   return spe->fString;
 }
 
-inline const XMLCh* DOMDocumentImpl::
-getPooledNString(const XMLCh *in, XMLSize_t n)
+inline const XMLCh* DOMDocumentImpl::getPooledNString(const XMLCh *in, XMLSize_t n)
 {
   if (in == 0)
     return 0;
@@ -401,7 +402,7 @@ getPooledNString(const XMLCh *in, XMLSize_t n)
   pspe = &fNameTable[inHash];
   while (*pspe != 0)
   {
-    if (XMLString::equalsN((*pspe)->fString, in, n))
+    if ((*pspe)->fLength == n && XMLString::equalsN((*pspe)->fString, in, n))
       return (*pspe)->fString;
     pspe = &((*pspe)->fNext);
   }
@@ -415,6 +416,7 @@ getPooledNString(const XMLCh *in, XMLSize_t n)
   //
   XMLSize_t sizeToAllocate = sizeof(DOMStringPoolEntry) + n*sizeof(XMLCh);
   *pspe = spe = (DOMStringPoolEntry *)allocate(sizeToAllocate);
+  spe->fLength = n;
   spe->fNext = 0;
   XMLString::copyNString((XMLCh*)spe->fString, in, n);
 
diff --git a/src/xercesc/dom/impl/DOMStringPool.hpp b/src/xercesc/dom/impl/DOMStringPool.hpp
index 6178be9a7..03096e49a 100644
--- a/src/xercesc/dom/impl/DOMStringPool.hpp
+++ b/src/xercesc/dom/impl/DOMStringPool.hpp
@@ -43,13 +43,14 @@ class   DOMDocumentImpl;
 //                      hash table array itself is a pointer to the head
 //                      of a singly-linked list of these structs.
 //
-//                      Although this struct is delcared with a string length of one,
+//                      Although this struct is declared with a string length of one,
 //                      the factory method allocates enough storage to hold the full
 //                      string length.
 //
 struct DOMStringPoolEntry
 {
     DOMStringPoolEntry    *fNext;
+    XMLSize_t             fLength;
     XMLCh                 fString[1];
 };
 
-- 
GitLab