From d8842c8f75578cacb5c72405991a4cca207ff6f0 Mon Sep 17 00:00:00 2001
From: Khaled Noaman <knoaman@apache.org>
Date: Fri, 16 Aug 2002 15:46:17 +0000
Subject: [PATCH] Bug 7698 : filenames with embedded spaces in schemaLocation
 strings not handled properly.

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@174124 13f79535-47bb-0310-9956-ffa450edef68
---
 src/xercesc/internal/XMLScanner.hpp           |  6 ++++
 src/xercesc/internal/XMLScanner2.cpp          | 31 +++++++++++++++++--
 .../validators/schema/TraverseSchema.cpp      |  8 +++--
 .../validators/schema/TraverseSchema.hpp      | 27 ++++++++++++++++
 4 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/src/xercesc/internal/XMLScanner.hpp b/src/xercesc/internal/XMLScanner.hpp
index 000afcc38..663e74a95 100644
--- a/src/xercesc/internal/XMLScanner.hpp
+++ b/src/xercesc/internal/XMLScanner.hpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.10  2002/08/16 15:46:17  knoaman
+ * Bug 7698 : filenames with embedded spaces in schemaLocation strings not handled properly.
+ *
  * Revision 1.9  2002/07/31 18:49:29  tng
  * [Bug 6227] Make method getLastExtLocation() constant.
  *
@@ -615,6 +618,9 @@ private :
     void resetURIStringPool();
     InputSource* resolveSystemId(const XMLCh* const sysId); // return owned by caller
 
+    // Spaces are not allowed in URI, so %20 is used instead.
+    // Convert %20 to spaces before resolving the URI
+    void normalizeURI(const XMLCh* const systemURI, XMLBuffer& normalizedURI);
 
     // -----------------------------------------------------------------------
     //  Private helper methods
diff --git a/src/xercesc/internal/XMLScanner2.cpp b/src/xercesc/internal/XMLScanner2.cpp
index aa23da49b..2fb2d3b70 100644
--- a/src/xercesc/internal/XMLScanner2.cpp
+++ b/src/xercesc/internal/XMLScanner2.cpp
@@ -1421,23 +1421,27 @@ void XMLScanner::resolveSchemaGrammar(const XMLCh* const loc, const XMLCh* const
         // Create a buffer for expanding the system id
         XMLBufBid bbSys(&fBufMgr);
         XMLBuffer& expSysId = bbSys.getBuffer();
+        XMLBuffer& normalizedSysId = bbSys.getBuffer();
+
+        normalizeURI(loc, normalizedSysId);
 
         //
         //  Allow the entity handler to expand the system id if they choose
         //  to do so.
         //
         InputSource* srcToFill = 0;
+        const XMLCh* normalizedURI = normalizedSysId.getRawBuffer();
         if (fEntityHandler)
         {
-            if (!fEntityHandler->expandSystemId(loc, expSysId))
-                expSysId.set(loc);
+            if (!fEntityHandler->expandSystemId(normalizedURI, expSysId))
+                expSysId.set(normalizedURI);
 
             srcToFill = fEntityHandler->resolveEntity( XMLUni::fgZeroLenString
                                                      , expSysId.getRawBuffer());
         }
          else
         {
-            expSysId.set(loc);
+            expSysId.set(normalizedURI);
         }
 
         //
@@ -3193,4 +3197,25 @@ bool XMLScanner::anyAttributeValidation(SchemaAttDef* attWildCard, unsigned int
     return anyEncountered;
 }
 
+void XMLScanner::normalizeURI(const XMLCh* const systemURI,
+                              XMLBuffer& normalizedURI)
+{
+    const XMLCh* pszSrc = systemURI;
+
+    normalizedURI.reset();
 
+    while (*pszSrc) {
+
+        if ((*(pszSrc) == chPercent)
+        &&  (*(pszSrc+1) == chDigit_2)
+        &&  (*(pszSrc+2) == chDigit_0))
+        {
+            pszSrc += 3;
+            normalizedURI.append(chSpace);
+        }
+        else {
+            normalizedURI.append(*pszSrc);
+            pszSrc++;
+        }
+    }
+}
diff --git a/src/xercesc/validators/schema/TraverseSchema.cpp b/src/xercesc/validators/schema/TraverseSchema.cpp
index 90a3952ef..2b54a80e0 100644
--- a/src/xercesc/validators/schema/TraverseSchema.cpp
+++ b/src/xercesc/validators/schema/TraverseSchema.cpp
@@ -6046,9 +6046,11 @@ InputSource* TraverseSchema::resolveSchemaLocation(const XMLCh* const loc) {
     // Create an input source
     // ------------------------------------------------------------------
     InputSource* srcToFill = 0;
+    normalizeURI(loc, fBuffer);
 
+    const XMLCh* normalizedURI = fBuffer.getRawBuffer();
     if (fEntityHandler){
-        srcToFill = fEntityHandler->resolveEntity(XMLUni::fgZeroLenString, loc);
+        srcToFill = fEntityHandler->resolveEntity(XMLUni::fgZeroLenString, normalizedURI);
     }
 
     //  If they didn't create a source via the entity resolver, then we
@@ -6057,7 +6059,7 @@ InputSource* TraverseSchema::resolveSchemaLocation(const XMLCh* const loc) {
 
         try {
 
-            XMLURL urlTmp(fSchemaInfo->getCurrentSchemaURL(), loc);
+            XMLURL urlTmp(fSchemaInfo->getCurrentSchemaURL(), normalizedURI);
 
             if (urlTmp.isRelative()) {
                 ThrowXML(MalformedURLException,
@@ -6068,7 +6070,7 @@ InputSource* TraverseSchema::resolveSchemaLocation(const XMLCh* const loc) {
         }
         catch(const MalformedURLException&) {
             // Its not a URL, so lets assume its a local file name.
-            srcToFill = new LocalFileInputSource(fSchemaInfo->getCurrentSchemaURL(),loc);
+            srcToFill = new LocalFileInputSource(fSchemaInfo->getCurrentSchemaURL(),normalizedURI);
         }
     }
 
diff --git a/src/xercesc/validators/schema/TraverseSchema.hpp b/src/xercesc/validators/schema/TraverseSchema.hpp
index 310e33e19..e3fc580ff 100644
--- a/src/xercesc/validators/schema/TraverseSchema.hpp
+++ b/src/xercesc/validators/schema/TraverseSchema.hpp
@@ -690,6 +690,10 @@ private:
     void processKeyRefFor(SchemaInfo* const aSchemaInfo,
                           ValueVectorOf<SchemaInfo*>* const infoList);
 
+    // Spaces are not allowed in URI, so %20 is used instead.
+    // Convert %20 to spaces before resolving the URI
+    void normalizeURI(const XMLCh* const systemURI, XMLBuffer& normalizedURI);
+
     // -----------------------------------------------------------------------
     //  Private constants
     // -----------------------------------------------------------------------
@@ -924,6 +928,29 @@ inline void TraverseSchema::getRedefineNewTypeName(const XMLCh* const oldTypeNam
     }
 }
 
+inline void TraverseSchema::normalizeURI(const XMLCh* const systemURI,
+                                         XMLBuffer& normalizedURI)
+{
+    const XMLCh* pszSrc = systemURI;
+
+    normalizedURI.reset();
+
+    while (*pszSrc) {
+
+        if ((*(pszSrc) == chPercent)
+        &&  (*(pszSrc+1) == chDigit_2)
+        &&  (*(pszSrc+2) == chDigit_0))
+        {
+            pszSrc += 3;
+            normalizedURI.append(chSpace);
+        }
+        else {
+            normalizedURI.append(*pszSrc);
+            pszSrc++;
+        }
+    }
+}
+
 #endif
 
 /**
-- 
GitLab