[PATCH] x2: Disabling automatic schema loading, and more schema validation

View: New views
4 Messages — Rating Filter:   Alert me  

[PATCH] x2: Disabling automatic schema loading, and more schema validation

by Wouter Coene-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I'm working on an application which is built against Xerces 2.8.0. This
application subclasses XMLGrammarPoolImpl to provide its own grammar caching
behaviour. In order to control this better it would be convenient if Xerces
would not automatically attempt to load schema grammars if they could not be
located in the grammar pool (as can already be controlled for DTDs).

The first attached patch (load-schema.patch) adds a new property on
SAX2XMLReader and DOMBuilder named XMLUni::fgLoadSchema[1], which controls
this behaviour. Is there a possibility of getting this in the next release
of Xerces?

Secondly, Xerces' SAX2XMLReader and DOMBuilder have a property
XMLUni::fgXercesSchemaFullChecking[2], which controls validation of schema
files themselves. However, even when this property is set, Xerces doesn't
validate the loaded schema files against its schemas. The second attached
patch (schema-checking.patch) should change this. Is the current Xerces
behaviour a bug?

Thanks,
Wouter Coene

[1]. Or "http://apache.org/xml/features/nonvalidating/load-schema"
[2]. Or "http://apache.org/xml/features/validation/schema-full-checking"

Index: src/xercesc/parsers/AbstractDOMParser.cpp
===================================================================
--- src/xercesc/parsers/AbstractDOMParser.cpp (revision 1377)
+++ src/xercesc/parsers/AbstractDOMParser.cpp (revision 1379)
@@ -319,6 +319,11 @@
     return fScanner->getLoadExternalDTD();
 }
 
+bool AbstractDOMParser::getLoadSchema() const
+{
+    return fScanner->getLoadSchema();
+}
+
 bool AbstractDOMParser::getCalculateSrcOfs() const
 {
     return fScanner->getCalculateSrcOfs();
@@ -442,6 +447,11 @@
     fScanner->setLoadExternalDTD(newState);
 }
 
+void AbstractDOMParser::setLoadSchema(const bool newState)
+{
+    fScanner->setLoadSchema(newState);
+}
+
 void AbstractDOMParser::setCalculateSrcOfs(const bool newState)
 {
     fScanner->setCalculateSrcOfs(newState);
Index: src/xercesc/parsers/SAX2XMLReaderImpl.cpp
===================================================================
--- src/xercesc/parsers/SAX2XMLReaderImpl.cpp (revision 1377)
+++ src/xercesc/parsers/SAX2XMLReaderImpl.cpp (revision 1379)
@@ -1300,6 +1300,10 @@
     {
         fScanner->setLoadExternalDTD(value);
     }
+    else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadSchema) == 0)
+    {
+        fScanner->setLoadSchema(value);
+    }
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
     {
         fScanner->setExitOnFirstFatal(!value);
@@ -1374,6 +1378,8 @@
         return fScanner->getIdentityConstraintChecking();
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadExternalDTD) == 0)
         return fScanner->getLoadExternalDTD();
+    else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadSchema) == 0)
+        return fScanner->getLoadSchema();
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
         return !fScanner->getExitOnFirstFatal();
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesValidationErrorAsFatal) == 0)
Index: src/xercesc/parsers/AbstractDOMParser.hpp
===================================================================
--- src/xercesc/parsers/AbstractDOMParser.hpp (revision 1377)
+++ src/xercesc/parsers/AbstractDOMParser.hpp (revision 1379)
@@ -347,6 +347,18 @@
       */
     bool getLoadExternalDTD() const;
 
+    /** Get the 'Loading Schema' flag
+      *
+      * This method returns the state of the parser's loading schema
+      * flag.
+      *
+      * @return true, if the parser is currently configured to
+      *         automatically load schemas, false otherwise.
+      *
+      * @see #setLoadSchema
+      */
+    bool getLoadSchema() const;
+
     /** Get the 'create comment node' flag
       *
       * This method returns the flag that specifies whether the parser is
@@ -748,6 +760,21 @@
       */
     void setLoadExternalDTD(const bool newState);
 
+    /** Set the 'Loading Schema' flag
+      *
+      * This method allows users to enable or disable the loading of schemas.
+      * When set to false, the parser not attempt to load schemas beyond
+      * querying the grammar pool for it.
+      *
+      * The parser's default state is: true.
+      *
+      * @param newState The value specifying whether external DTD should
+      *                 be loaded or not.
+      *
+      * @see #getLoadSchema
+      */
+    void setLoadSchema(const bool newState);
+
      /** Set the 'create comment nodes' flag
       *
       * This method allows the user to specify whether the parser should
Index: src/xercesc/parsers/DOMBuilderImpl.cpp
===================================================================
--- src/xercesc/parsers/DOMBuilderImpl.cpp (revision 1377)
+++ src/xercesc/parsers/DOMBuilderImpl.cpp (revision 1379)
@@ -200,6 +200,11 @@
         setLoadExternalDTD(state);
     }
 
+    else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadSchema) == 0)
+    {
+        setLoadSchema(state);
+    }
+
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
     {
         setExitOnFirstFatalError(!state);
@@ -320,6 +325,11 @@
         return getLoadExternalDTD();
     }
 
+    else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadSchema) == 0)
+    {
+        return getLoadSchema();
+    }
+
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
     {
         return !getExitOnFirstFatalError();
Index: src/xercesc/parsers/SAX2XMLReaderImpl.hpp
===================================================================
--- src/xercesc/parsers/SAX2XMLReaderImpl.hpp (revision 1377)
+++ src/xercesc/parsers/SAX2XMLReaderImpl.hpp (revision 1379)
@@ -279,6 +279,7 @@
     * <br>http://apache.org/xml/features/validation/schema (default: true)
     * <br>http://apache.org/xml/features/validation/schema-full-checking (default: false)
     * <br>http://apache.org/xml/features/nonvalidating/load-external-dtd (default: true)
+    * <br>http://apache.org/xml/features/nonvalidating/load-schema (default: true)
     * <br>http://apache.org/xml/features/continue-after-fatal-error (default: false)
     * <br>http://apache.org/xml/features/validation-error-as-fatal (default: false)
     * <br>http://apache.org/xml/features/validation/reuse-validator (Deprecated) (default: false)
Index: src/xercesc/validators/schema/TraverseSchema.cpp
===================================================================
--- src/xercesc/validators/schema/TraverseSchema.cpp (revision 1377)
+++ src/xercesc/validators/schema/TraverseSchema.cpp (revision 1379)
@@ -608,6 +608,11 @@
         return;
     }
 
+    if (!fScanner->getLoadSchema())
+    {
+      return;
+    }
+
     // ------------------------------------------------------------------
     // Parse input source
     // ------------------------------------------------------------------
@@ -809,7 +814,7 @@
         return;
     }
 
-    if (grammarFound) {
+    if (grammarFound || (!fScanner->getLoadSchema())) {
         return;
     }
 
@@ -8030,6 +8035,12 @@
         return false;
     }
 
+    if (!fScanner->getLoadSchema())
+    {
+      reportSchemaError(redefineElem, XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError, includeURL);
+      return false;
+    }
+
     // ------------------------------------------------------------------
     // Parse input source
     // ------------------------------------------------------------------
Index: src/xercesc/internal/SGXMLScanner.cpp
===================================================================
--- src/xercesc/internal/SGXMLScanner.cpp (revision 1377)
+++ src/xercesc/internal/SGXMLScanner.cpp (revision 1379)
@@ -3649,7 +3649,7 @@
         grammar = fGrammarResolver->getGrammar(&theSchemaDescription);
     }
 
-    if (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType) {
+    if (fLoadSchema && (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType)) {
         XSDDOMParser parser(0, fMemoryManager, 0);
 
         parser.setValidationScheme(XercesDOMParser::Val_Never);
@@ -3798,7 +3798,7 @@
             }
         }
     }
-    else {
+    else if (grammar) {
 
         //  Since we have seen a grammar, set our validation flag
         //  at this point if the validation scheme is auto
Index: src/xercesc/internal/XMLScanner.cpp
===================================================================
--- src/xercesc/internal/XMLScanner.cpp (revision 1377)
+++ src/xercesc/internal/XMLScanner.cpp (revision 1379)
@@ -163,6 +163,7 @@
     , fToCacheGrammar(false)
     , fUseCachedGrammar(false)
     , fLoadExternalDTD(true)
+    , fLoadSchema(true)
     , fNormalizeData(true)
     , fGenerateSyntheticAnnotations(false)
     , fValidateAnnotations(false)
@@ -260,7 +261,8 @@
     , fIdentityConstraintChecking(true)
     , fToCacheGrammar(false)
     , fUseCachedGrammar(false)
- , fLoadExternalDTD(true)
+  , fLoadExternalDTD(true)
+    , fLoadSchema(true)
     , fNormalizeData(true)
     , fGenerateSyntheticAnnotations(false)
     , fValidateAnnotations(false)
Index: src/xercesc/internal/IGXMLScanner2.cpp
===================================================================
--- src/xercesc/internal/IGXMLScanner2.cpp (revision 1377)
+++ src/xercesc/internal/IGXMLScanner2.cpp (revision 1379)
@@ -1772,7 +1772,7 @@
         grammar = fGrammarResolver->getGrammar(&theSchemaDescription);
     }
 
-    if (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType) {
+    if (fLoadSchema && (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType)) {
         XSDDOMParser parser(0, fMemoryManager, 0);
 
         parser.setValidationScheme(XercesDOMParser::Val_Never);
@@ -1932,7 +1932,7 @@
             }
         }
     }
-    else {
+    else if (grammar) {
 
         //  Since we have seen a grammar, set our validation flag
         //  at this point if the validation scheme is auto
Index: src/xercesc/internal/XMLScanner.hpp
===================================================================
--- src/xercesc/internal/XMLScanner.hpp (revision 1377)
+++ src/xercesc/internal/XMLScanner.hpp (revision 1379)
@@ -266,6 +266,7 @@
     XMLCh* getExternalNoNamespaceSchemaLocation() const;
     SecurityManager* getSecurityManager() const;
     bool getLoadExternalDTD() const;
+    bool getLoadSchema() const;
     bool getNormalizeData() const;
     bool isCachingGrammarFromParse() const;
     bool isUsingCachedGrammarInParse() const;
@@ -372,6 +373,7 @@
     void setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation);
     void setSecurityManager(SecurityManager* const securityManager);
     void setLoadExternalDTD(const bool loadDTD);
+    void setLoadSchema(const bool loadSchema);
     void setNormalizeData(const bool normalizeData);
     void setCalculateSrcOfs(const bool newValue);
     void setParseSettings(XMLScanner* const refScanner);
@@ -704,6 +706,10 @@
     //  fLoadExternalDTD
     //      This flag indicates whether the external DTD be loaded or not
     //
+    //  fLoadSchema
+    //      This flag indicates whether the parser should attempt to load
+    //      schemas if they cannot be found in the grammar pool.
+    //
     //  fNormalizeData
     //      This flag indicates whether the parser should perform datatype
     //      normalization that is defined in the schema.
@@ -748,6 +754,7 @@
     bool                        fToCacheGrammar;
     bool                        fUseCachedGrammar;
     bool                        fLoadExternalDTD;
+    bool                        fLoadSchema;
     bool                        fNormalizeData;
     bool                        fGenerateSyntheticAnnotations;
     bool                        fValidateAnnotations;
@@ -1048,6 +1055,11 @@
     return fLoadExternalDTD;
 }
 
+inline bool XMLScanner::getLoadSchema() const
+{
+    return fLoadSchema;
+}
+
 inline bool XMLScanner::getNormalizeData() const
 {
     return fNormalizeData;
@@ -1260,6 +1272,11 @@
     fLoadExternalDTD = loadDTD;
 }
 
+inline void XMLScanner::setLoadSchema(const bool loadSchema)
+{
+    fLoadSchema = loadSchema;
+}
+
 inline void XMLScanner::setNormalizeData(const bool normalizeData)
 {
     fNormalizeData = normalizeData;
Index: src/xercesc/util/XMLUni.cpp
===================================================================
--- src/xercesc/util/XMLUni.cpp (revision 1377)
+++ src/xercesc/util/XMLUni.cpp (revision 1379)
@@ -1051,6 +1051,21 @@
     ,   chLatin_d, chLatin_t, chLatin_d, chNull
 };
 
+//Xerces: http://apache.org/xml/features/nonvalidating/load-schema
+const XMLCh XMLUni::fgXercesLoadSchema[] =
+{
+        chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash
+    ,   chForwardSlash, chLatin_a, chLatin_p, chLatin_a, chLatin_c, chLatin_h
+    ,   chLatin_e, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash
+    ,   chLatin_x, chLatin_m, chLatin_l, chForwardSlash, chLatin_f, chLatin_e
+    ,   chLatin_a, chLatin_t, chLatin_u, chLatin_r, chLatin_e, chLatin_s
+    ,   chForwardSlash, chLatin_n, chLatin_o, chLatin_n
+    ,   chLatin_v, chLatin_a, chLatin_l, chLatin_i, chLatin_d
+    ,   chLatin_a, chLatin_t, chLatin_i, chLatin_n, chLatin_g, chForwardSlash
+    ,   chLatin_l, chLatin_o, chLatin_a, chLatin_d, chDash
+    ,   chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chNull
+};
+
 //Xerces: http://apache.org/xml/features/continue-after-fatal-error
 const XMLCh XMLUni::fgXercesContinueAfterFatalError[] =
 {
Index: src/xercesc/util/XMLUni.hpp
===================================================================
--- src/xercesc/util/XMLUni.hpp (revision 1377)
+++ src/xercesc/util/XMLUni.hpp (revision 1379)
@@ -215,6 +215,7 @@
     static const XMLCh fgXercesSchemaExternalNoNameSpaceSchemaLocation[];
     static const XMLCh fgXercesSecurityManager[];
     static const XMLCh fgXercesLoadExternalDTD[];
+    static const XMLCh fgXercesLoadSchema[];
     static const XMLCh fgXercesContinueAfterFatalError[];
     static const XMLCh fgXercesValidationErrorAsFatal[];
     static const XMLCh fgXercesUserAdoptsDOMDocument[];

Index: src/xercesc/internal/SGXMLScanner.cpp
===================================================================
--- src/xercesc/internal/SGXMLScanner.cpp (revision 1436)
+++ src/xercesc/internal/SGXMLScanner.cpp (revision 1437)
@@ -3650,9 +3650,10 @@
     }
 
     if (fLoadSchema && (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType)) {
-        XSDDOMParser parser(0, fMemoryManager, 0);
+        XSDDOMParser parser(0, fMemoryManager, fGrammarResolver->getGrammarPool());
 
-        parser.setValidationScheme(XercesDOMParser::Val_Never);
+        parser.setValidationScheme(getValidationSchemaFullChecking()?
+            XercesDOMParser::Val_Always : XercesDOMParser::Val_Never);
         parser.setDoNamespaces(true);
         parser.setUserEntityHandler(fEntityHandler);
         parser.setUserErrorReporter(fErrorReporter);
@@ -3910,9 +3911,10 @@
     if (fValidatorFromUser)
         fValidator->reset();
 
-    XSDDOMParser parser(0, fMemoryManager, 0);
+    XSDDOMParser parser(0, fMemoryManager, fGrammarResolver->getGrammarPool());
 
-    parser.setValidationScheme(XercesDOMParser::Val_Never);
+    parser.setValidationScheme(getValidationSchemaFullChecking()?
+        XercesDOMParser::Val_Always : XercesDOMParser::Val_Never);
     parser.setDoNamespaces(true);
     parser.setUserEntityHandler(fEntityHandler);
     parser.setUserErrorReporter(fErrorReporter);
Index: src/xercesc/internal/IGXMLScanner2.cpp
===================================================================
--- src/xercesc/internal/IGXMLScanner2.cpp (revision 1436)
+++ src/xercesc/internal/IGXMLScanner2.cpp (revision 1437)
@@ -1773,9 +1773,10 @@
     }
 
     if (fLoadSchema && (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType)) {
-        XSDDOMParser parser(0, fMemoryManager, 0);
+        XSDDOMParser parser(0, fMemoryManager, fGrammarResolver->getGrammarPool());
 
-        parser.setValidationScheme(XercesDOMParser::Val_Never);
+        parser.setValidationScheme(getValidationSchemaFullChecking()?
+            XercesDOMParser::Val_Always : XercesDOMParser::Val_Never);
         parser.setDoNamespaces(true);
         parser.setUserEntityHandler(fEntityHandler);
         parser.setUserErrorReporter(fErrorReporter);
@@ -2062,9 +2063,10 @@
         }
     }
 
-    XSDDOMParser parser(0, fMemoryManager, 0);
+    XSDDOMParser parser(0, fMemoryManager, fGrammarResolver->getGrammarPool());
 
-    parser.setValidationScheme(XercesDOMParser::Val_Never);
+    parser.setValidationScheme(getValidationSchemaFullChecking()?
+        XercesDOMParser::Val_Always : XercesDOMParser::Val_Never);
     parser.setDoNamespaces(true);
     parser.setUserEntityHandler(fEntityHandler);
     parser.setUserErrorReporter(fErrorReporter);


---------------------------------------------------------------------
To unsubscribe, e-mail: c-dev-unsubscribe@...
For additional commands, e-mail: c-dev-help@...

Re: [PATCH] x2: Disabling automatic schema loading, and more schema validation

by Boris Kolpackov-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Wouter,

Wouter Coene <wouter+xerces-c@...> writes:

> The first attached patch (load-schema.patch) adds a new property on
> SAX2XMLReader and DOMBuilder named XMLUni::fgLoadSchema[1], which controls
> this behaviour. Is there a possibility of getting this in the next release
> of Xerces?

This makes sense and I will commit your patch if you can do the following:

- Make it against 3.0.0 since that will be the next release. Note that
  in 3.0.0 DOMBuilder was replaced with DOMLSParser. You can check out
  the current revision (trunk) by following the instructions on this
  page:

  http://xerces.apache.org/xerces-c/source-repository.html

- Provide documentation for your feature in the doc/ directory. You need
  to document it in every place where LoadExternalDTD is documented.


> Secondly, Xerces' SAX2XMLReader and DOMBuilder have a property
> XMLUni::fgXercesSchemaFullChecking[2], which controls validation of schema
> files themselves. However, even when this property is set, Xerces doesn't
> validate the loaded schema files against its schemas. The second attached
> patch (schema-checking.patch) should change this. Is the current Xerces
> behaviour a bug?

No, this is not a bug. There is no real schema for XML Schema (there is
one which is not valid and is for illustration only). Xerces-C++ does
manual validation of schemas so turning on XML Schema validation on
schemas does not make much sense.

Thanks,
Boris

--
Boris Kolpackov, Code Synthesis Tools   http://codesynthesis.com/~boris/blog
Open source XML data binding for C++:   http://codesynthesis.com/products/xsd
Mobile/embedded validating XML parsing: http://codesynthesis.com/products/xsde

---------------------------------------------------------------------
To unsubscribe, e-mail: c-dev-unsubscribe@...
For additional commands, e-mail: c-dev-help@...


Re: [PATCH] x2: Disabling automatic schema loading, and more schema validation

by Wouter Coene-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

According to Boris Kolpackov (boris@...):
> Wouter Coene <wouter+xerces-c@...> writes:
> > The first attached patch (load-schema.patch) adds a new property on
> > SAX2XMLReader and DOMBuilder named XMLUni::fgLoadSchema[1], which controls
> > this behaviour. Is there a possibility of getting this in the next release
> > of Xerces?
>
> This makes sense and I will commit your patch if you can do the following:
[snip]

See attachment (load-schema2.patch) for a patch against Xerces-C's trunk as
of this afternoon (SVN rev 671547).

I'm a bit uncertain of the changes in TraverseSchema though. Maybe someone
more familiar with that code should take a look at it.

Thanks,
Wouter Coene

Index: doc/program-dom.xml
===================================================================
--- doc/program-dom.xml (revision 671547)
+++ doc/program-dom.xml (working copy)
@@ -493,6 +493,20 @@
 
             <p/>
 
+            <anchor name="load-schema"/>
+            <table>
+                <tr><th colspan="2"><em>void setLoadSchema(const bool)</em></th></tr>
+                <tr><th><em>true:</em></th><td> Load the schema. </td></tr>
+                <tr><th><em>false:</em></th><td> Don't load the schema if it wasn't found in the grammar pool. </td></tr>
+                <tr><th><em>default:</em></th><td> true </td></tr>
+                <tr><th><em>note:</em></th><td> This feature is ignored and no schemas are loaded if schema processing is disabled. </td></tr>
+                <tr><th><em>see:</em></th><td>
+                <link anchor="schema">setDoSchema</link>
+                </td></tr>
+            </table>
+
+            <p/>
+
             <anchor name="continue-after-fatal"/>
             <table>
                 <tr><th colspan="2"><em>void setExitOnFirstFatalError(const bool)</em></th></tr>
@@ -1252,6 +1266,21 @@
 
             <p/>
 
+            <anchor name="builder-load-schema"/>
+            <table>
+                <tr><th colspan="2"><em>http://apache.org/xml/features/nonvalidating/load-schema</em></th></tr>
+                <tr><th><em>true:</em></th><td> Load the schema. </td></tr>
+                <tr><th><em>false:</em></th><td> Don't load the schema if it wasn't found in the grammar pool. </td></tr>
+                <tr><th><em>default:</em></th><td> true </td></tr>
+                <tr><th><em>XMLUni Predefined Constant:</em></th><td> fgXercesLoadSchema </td></tr>
+                <tr><th><em>note:</em></th><td> This feature is ignored and no schemas are loaded if schema processing is disabled. </td></tr>
+                <tr><th><em>see:</em></th><td>
+                <link anchor="builder-schema">schema</link>
+                </td></tr>
+            </table>
+
+            <p/>
+
             <anchor name="builder-continue-after-fatal"/>
             <table>
                 <tr><th colspan="2"><em>http://apache.org/xml/features/continue-after-fatal-error</em></th></tr>
Index: doc/program-others.xml
===================================================================
--- doc/program-others.xml (revision 671547)
+++ doc/program-others.xml (working copy)
@@ -845,7 +845,7 @@
             The DGXMLScanner handles XML documents with DOCTYPE information. It does not do any
             XMLSchema processing, which means that any schema specific attributes (e.g. schemaLocation),
             will be treated as normal element attributes. Setting schema grammar specific features/properties
-            will have no effect on its behavior (e.g. setDoSchema(true) is ignored).
+            will have no effect on its behavior (e.g. setDoSchema(true) and setLoadSchema(true) are ignored).
             </p>
 
 <source>
Index: doc/program-sax.xml
===================================================================
--- doc/program-sax.xml (revision 671547)
+++ doc/program-sax.xml (working copy)
@@ -258,6 +258,20 @@
 
             <p/>
 
+            <anchor name="load-schema"/>
+            <table>
+                <tr><th colspan="2"><em>void setLoadSchema(const bool)</em></th></tr>
+                <tr><th><em>true:</em></th><td> Load the schema. </td></tr>
+                <tr><th><em>false:</em></th><td> Don't load the schema if it wasn't found in the grammar pool. </td></tr>
+                <tr><th><em>default:</em></th><td> true </td></tr>
+                <tr><th><em>note:</em></th><td> This feature is ignored and no schemas are loaded if schema processing is disabled. </td></tr>
+                <tr><th><em>see:</em></th><td>
+                <link anchor="schema">setDoSchema</link>
+                </td></tr>
+            </table>
+
+            <p/>
+
             <anchor name="continue-after-fatal"/>
             <table>
                 <tr><th colspan="2"><em>void setExitOnFirstFatalError(const bool)</em></th></tr>
Index: doc/program-sax2.xml
===================================================================
--- doc/program-sax2.xml (revision 671547)
+++ doc/program-sax2.xml (working copy)
@@ -299,6 +299,21 @@
 
             <p/>
 
+            <anchor name="load-schema"/>
+            <table>
+                <tr><th colspan="2"><em>http://apache.org/xml/features/nonvalidating/load-schema</em></th></tr>
+                <tr><th><em>true:</em></th><td> Load the schema. </td></tr>
+                <tr><th><em>false:</em></th><td> Don't load the schema if it wasn't found in the grammar pool. </td></tr>
+                <tr><th><em>default:</em></th><td> true </td></tr>
+                <tr><th><em>XMLUni Predefined Constant:</em></th><td> fgXercesLoadSchema </td></tr>
+                <tr><th><em>note:</em></th><td> This feature is ignored and no schemas are loaded if schema processing is disabled. </td></tr>
+                <tr><th><em>see:</em></th><td>
+                <link anchor="schema">http://apache.org/xml/features/validation/schema</link>
+                </td></tr>
+            </table>
+
+            <p/>
+
             <anchor name="continue-after-fatal"/>
             <table>
                 <tr><th colspan="2"><em>http://apache.org/xml/features/continue-after-fatal-error</em></th></tr>
Index: src/xercesc/dom/DOMLSParser.hpp
===================================================================
--- src/xercesc/dom/DOMLSParser.hpp (revision 671547)
+++ src/xercesc/dom/DOMLSParser.hpp (working copy)
@@ -278,6 +278,12 @@
       *     false
       *         References to external DTDs will be ignored
       *
+      * "http://apache.org/xml/features/nonvalidating/load-schema"
+      *     true (default)
+      *         Allow the parser to load schemas that are not in the grammar pool
+      *     false
+      *         Schemas that are not in the grammar pool are ignored
+      *
       * "http://apache.org/xml/features/continue-after-fatal-error"
       *     true
       *         Parsing should try to continue even if a fatal error has been triggered, trying to generate a DOM tree
Index: src/xercesc/internal/IGXMLScanner2.cpp
===================================================================
--- src/xercesc/internal/IGXMLScanner2.cpp (revision 671547)
+++ src/xercesc/internal/IGXMLScanner2.cpp (working copy)
@@ -1775,7 +1775,7 @@
         grammar = fGrammarResolver->getGrammar(&theSchemaDescription);
     }
 
-    if (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType) {
+    if (fLoadSchema && (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType)) {
         XSDDOMParser parser(0, fMemoryManager, 0);
 
         parser.setValidationScheme(XercesDOMParser::Val_Never);
@@ -1935,7 +1935,7 @@
             }
         }
     }
-    else {
+    else if (grammar) {
 
         //  Since we have seen a grammar, set our validation flag
         //  at this point if the validation scheme is auto
Index: src/xercesc/internal/SGXMLScanner.cpp
===================================================================
--- src/xercesc/internal/SGXMLScanner.cpp (revision 671547)
+++ src/xercesc/internal/SGXMLScanner.cpp (working copy)
@@ -3633,7 +3633,7 @@
         grammar = fGrammarResolver->getGrammar(&theSchemaDescription);
     }
 
-    if (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType) {
+    if (fLoadSchema && (!grammar || grammar->getGrammarType() == Grammar::DTDGrammarType)) {
         XSDDOMParser parser(0, fMemoryManager, 0);
 
         parser.setValidationScheme(XercesDOMParser::Val_Never);
@@ -3782,7 +3782,7 @@
             }
         }
     }
-    else {
+    else if (grammar) {
 
         //  Since we have seen a grammar, set our validation flag
         //  at this point if the validation scheme is auto
Index: src/xercesc/internal/XMLScanner.cpp
===================================================================
--- src/xercesc/internal/XMLScanner.cpp (revision 671547)
+++ src/xercesc/internal/XMLScanner.cpp (working copy)
@@ -100,6 +100,7 @@
     , fToCacheGrammar(false)
     , fUseCachedGrammar(false)
     , fLoadExternalDTD(true)
+    , fLoadSchema(true)
     , fNormalizeData(true)
     , fGenerateSyntheticAnnotations(false)
     , fValidateAnnotations(false)
@@ -199,6 +200,7 @@
     , fToCacheGrammar(false)
     , fUseCachedGrammar(false)
  , fLoadExternalDTD(true)
+    , fLoadSchema(true)
     , fNormalizeData(true)
     , fGenerateSyntheticAnnotations(false)
     , fValidateAnnotations(false)
@@ -657,6 +659,7 @@
     cacheGrammarFromParse(refScanner->isCachingGrammarFromParse());
     useCachedGrammarInParse(refScanner->isUsingCachedGrammarInParse());
     setLoadExternalDTD(refScanner->getLoadExternalDTD());
+    setLoadSchema(refScanner->getLoadSchema());
     setNormalizeData(refScanner->getNormalizeData());
     setExternalSchemaLocation(refScanner->getExternalSchemaLocation());
     setExternalNoNamespaceSchemaLocation(refScanner->getExternalNoNamespaceSchemaLocation());
Index: src/xercesc/internal/XMLScanner.hpp
===================================================================
--- src/xercesc/internal/XMLScanner.hpp (revision 671547)
+++ src/xercesc/internal/XMLScanner.hpp (working copy)
@@ -267,6 +267,7 @@
     XMLCh* getExternalNoNamespaceSchemaLocation() const;
     SecurityManager* getSecurityManager() const;
     bool getLoadExternalDTD() const;
+    bool getLoadSchema() const;
     bool getNormalizeData() const;
     bool isCachingGrammarFromParse() const;
     bool isUsingCachedGrammarInParse() const;
@@ -374,6 +375,7 @@
     void setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation);
     void setSecurityManager(SecurityManager* const securityManager);
     void setLoadExternalDTD(const bool loadDTD);
+    void setLoadSchema(const bool loadSchema);
     void setNormalizeData(const bool normalizeData);
     void setCalculateSrcOfs(const bool newValue);
     void setParseSettings(XMLScanner* const refScanner);
@@ -694,6 +696,10 @@
     //  fLoadExternalDTD
     //      This flag indicates whether the external DTD be loaded or not
     //
+    //  fLoadSchema
+    //      This flag indicates whether the parser should attempt to load
+    //      schemas if they cannot be found in the grammar pool.
+    //
     //  fNormalizeData
     //      This flag indicates whether the parser should perform datatype
     //      normalization that is defined in the schema.
@@ -738,6 +744,7 @@
     bool                        fToCacheGrammar;
     bool                        fUseCachedGrammar;
     bool                        fLoadExternalDTD;
+    bool                        fLoadSchema;
     bool                        fNormalizeData;
     bool                        fGenerateSyntheticAnnotations;
     bool                        fValidateAnnotations;
@@ -1039,6 +1046,11 @@
     return fLoadExternalDTD;
 }
 
+inline bool XMLScanner::getLoadSchema() const
+{
+    return fLoadSchema;
+}
+
 inline bool XMLScanner::getNormalizeData() const
 {
     return fNormalizeData;
@@ -1256,6 +1268,11 @@
     fLoadExternalDTD = loadDTD;
 }
 
+inline void XMLScanner::setLoadSchema(const bool loadSchema)
+{
+    fLoadSchema = loadSchema;
+}
+
 inline void XMLScanner::setNormalizeData(const bool normalizeData)
 {
     fNormalizeData = normalizeData;
Index: src/xercesc/parsers/AbstractDOMParser.cpp
===================================================================
--- src/xercesc/parsers/AbstractDOMParser.cpp (revision 671547)
+++ src/xercesc/parsers/AbstractDOMParser.cpp (working copy)
@@ -320,6 +320,11 @@
     return fScanner->getLoadExternalDTD();
 }
 
+bool AbstractDOMParser::getLoadSchema() const
+{
+    return fScanner->getLoadSchema();
+}
+
 bool AbstractDOMParser::getCalculateSrcOfs() const
 {
     return fScanner->getCalculateSrcOfs();
@@ -448,6 +453,11 @@
     fScanner->setLoadExternalDTD(newState);
 }
 
+void AbstractDOMParser::setLoadSchema(const bool newState)
+{
+    fScanner->setLoadSchema(newState);
+}
+
 void AbstractDOMParser::setCalculateSrcOfs(const bool newState)
 {
     fScanner->setCalculateSrcOfs(newState);
Index: src/xercesc/parsers/AbstractDOMParser.hpp
===================================================================
--- src/xercesc/parsers/AbstractDOMParser.hpp (revision 671547)
+++ src/xercesc/parsers/AbstractDOMParser.hpp (working copy)
@@ -348,6 +348,19 @@
       */
     bool getLoadExternalDTD() const;
 
+    /** Get the 'Loading Schema' flag
+      *
+      * This method returns the state of the parser's loading schema
+      * flag.
+      *
+      * @return true, if the parser is currently configured to
+      *         automatically load schemas that are not in the
+      *         grammar pool, false otherwise.
+      *
+      * @see #setLoadSchema
+      */
+    bool getLoadSchema() const;
+
     /** Get the 'create comment node' flag
       *
       * This method returns the flag that specifies whether the parser is
@@ -768,6 +781,23 @@
       */
     void setLoadExternalDTD(const bool newState);
 
+    /** Set the 'Loading Schema' flag
+      *
+      * This method allows users to enable or disable the loading of schemas.
+      * When set to false, the parser not attempt to load schemas beyond
+      * querying the grammar pool for them.
+      *
+      * The parser's default state is: true.
+      *
+      * @param newState The value specifying whether schemas should
+      *                 be loaded if they're not found in the grammar
+      *                 pool.
+      *
+      * @see #getLoadSchema
+      * @see #setDoSchema
+      */
+    void setLoadSchema(const bool newState);
+
      /** Set the 'create comment nodes' flag
       *
       * This method allows the user to specify whether the parser should
Index: src/xercesc/parsers/DOMLSParserImpl.cpp
===================================================================
--- src/xercesc/parsers/DOMLSParserImpl.cpp (revision 671547)
+++ src/xercesc/parsers/DOMLSParserImpl.cpp (working copy)
@@ -121,6 +121,7 @@
     fSupportedParameters->add(XMLUni::fgXercesSchemaFullChecking);
     fSupportedParameters->add(XMLUni::fgXercesUserAdoptsDOMDocument);
     fSupportedParameters->add(XMLUni::fgXercesLoadExternalDTD);
+    fSupportedParameters->add(XMLUni::fgXercesLoadSchema);
     fSupportedParameters->add(XMLUni::fgXercesContinueAfterFatalError);
     fSupportedParameters->add(XMLUni::fgXercesValidationErrorAsFatal);
     fSupportedParameters->add(XMLUni::fgXercesCacheGrammarFromParse);
@@ -344,6 +345,10 @@
     {
         setLoadExternalDTD(state);
     }
+    else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadSchema) == 0)
+    {
+        setLoadSchema(state);
+    }
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
     {
         setExitOnFirstFatalError(!state);
@@ -531,6 +536,10 @@
     {
         return (void*)getLoadExternalDTD();
     }
+    else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadSchema) == 0)
+    {
+        return (void*)getLoadSchema();
+    }
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
     {
         return (void*)!getExitOnFirstFatalError();
@@ -647,6 +656,7 @@
         XMLString::compareIStringASCII(name, XMLUni::fgXercesSchemaFullChecking) == 0 ||
         XMLString::compareIStringASCII(name, XMLUni::fgXercesIdentityConstraintChecking) == 0 ||
         XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadExternalDTD) == 0 ||
+        XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadSchema) == 0 ||
         XMLString::compareIStringASCII(name, XMLUni::fgXercesContinueAfterFatalError) == 0 ||
         XMLString::compareIStringASCII(name, XMLUni::fgXercesValidationErrorAsFatal) == 0 ||
         XMLString::compareIStringASCII(name, XMLUni::fgXercesCacheGrammarFromParse) == 0 ||
Index: src/xercesc/parsers/SAX2XMLFilterImpl.hpp
===================================================================
--- src/xercesc/parsers/SAX2XMLFilterImpl.hpp (revision 671547)
+++ src/xercesc/parsers/SAX2XMLFilterImpl.hpp (working copy)
@@ -209,6 +209,7 @@
     * <br>http://apache.org/xml/features/validation/schema (default: true)
     * <br>http://apache.org/xml/features/validation/schema-full-checking (default: false)
     * <br>http://apache.org/xml/features/nonvalidating/load-external-dtd (default: true)
+    * <br>http://apache.org/xml/features/nonvalidating/load-schema (default: true)
     * <br>http://apache.org/xml/features/continue-after-fatal-error (default: false)
     * <br>http://apache.org/xml/features/validation-error-as-fatal (default: false)    
     *
Index: src/xercesc/parsers/SAX2XMLReaderImpl.cpp
===================================================================
--- src/xercesc/parsers/SAX2XMLReaderImpl.cpp (revision 671547)
+++ src/xercesc/parsers/SAX2XMLReaderImpl.cpp (working copy)
@@ -1304,6 +1304,10 @@
     {
         fScanner->setLoadExternalDTD(value);
     }
+    else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadSchema) == 0)
+    {
+        fScanner->setLoadSchema(value);
+    }
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
     {
         fScanner->setExitOnFirstFatal(!value);
@@ -1382,6 +1386,8 @@
         return fScanner->getIdentityConstraintChecking();
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadExternalDTD) == 0)
         return fScanner->getLoadExternalDTD();
+    else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesLoadSchema) == 0)
+        return fScanner->getLoadSchema();
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
         return !fScanner->getExitOnFirstFatal();
     else if (XMLString::compareIStringASCII(name, XMLUni::fgXercesValidationErrorAsFatal) == 0)
Index: src/xercesc/parsers/SAX2XMLReaderImpl.hpp
===================================================================
--- src/xercesc/parsers/SAX2XMLReaderImpl.hpp (revision 671547)
+++ src/xercesc/parsers/SAX2XMLReaderImpl.hpp (working copy)
@@ -279,6 +279,7 @@
     * <br>http://apache.org/xml/features/validation/schema (default: true)
     * <br>http://apache.org/xml/features/validation/schema-full-checking (default: false)
     * <br>http://apache.org/xml/features/nonvalidating/load-external-dtd (default: true)
+    * <br>http://apache.org/xml/features/nonvalidating/load-schema (default: true)
     * <br>http://apache.org/xml/features/continue-after-fatal-error (default: false)
     * <br>http://apache.org/xml/features/validation-error-as-fatal (default: false)    
     *
Index: src/xercesc/parsers/SAXParser.cpp
===================================================================
--- src/xercesc/parsers/SAXParser.cpp (revision 671547)
+++ src/xercesc/parsers/SAXParser.cpp (working copy)
@@ -312,6 +312,11 @@
     return fScanner->getLoadExternalDTD();
 }
 
+bool SAXParser::getLoadSchema() const
+{
+    return fScanner->getLoadSchema();
+}
+
 bool SAXParser::isCachingGrammarFromParse() const
 {
     return fScanner->isCachingGrammarFromParse();
@@ -465,6 +470,11 @@
     fScanner->setLoadExternalDTD(newState);
 }
 
+void SAXParser::setLoadSchema(const bool newState)
+{
+    fScanner->setLoadSchema(newState);
+}
+
 void SAXParser::cacheGrammarFromParse(const bool newState)
 {
     fScanner->cacheGrammarFromParse(newState);
Index: src/xercesc/parsers/SAXParser.hpp
===================================================================
--- src/xercesc/parsers/SAXParser.hpp (revision 671547)
+++ src/xercesc/parsers/SAXParser.hpp (working copy)
@@ -377,6 +377,19 @@
       */
     bool getLoadExternalDTD() const;
 
+    /** Get the 'Loading Schema' flag
+      *
+      * This method returns the state of the parser's loading schema
+      * flag.
+      *
+      * @return true, if the parser is currently configured to
+      *         automatically load schemas that are not in the
+      *         grammar pool, false otherwise.
+      *
+      * @see #setLoadSchema
+      */
+    bool getLoadSchema() const;
+
     /** Get the 'Grammar caching' flag
       *
       * This method returns the state of the parser's grammar caching when
@@ -765,6 +778,23 @@
       */
     void setLoadExternalDTD(const bool newState);
 
+    /** Set the 'Loading Schema' flag
+      *
+      * This method allows users to enable or disable the loading of schemas.
+      * When set to false, the parser not attempt to load schemas beyond
+      * querying the grammar pool for them.
+      *
+      * The parser's default state is: true.
+      *
+      * @param newState The value specifying whether schemas should
+      *                 be loaded if they're not found in the grammar
+      *                 pool.
+      *
+      * @see #getLoadSchema
+      * @see #setDoSchema
+      */
+    void setLoadSchema(const bool newState);
+
     /** Set the 'Grammar caching' flag
       *
       * This method allows users to enable or disable caching of grammar when
Index: src/xercesc/sax2/SAX2XMLReader.hpp
===================================================================
--- src/xercesc/sax2/SAX2XMLReader.hpp (revision 671547)
+++ src/xercesc/sax2/SAX2XMLReader.hpp (working copy)
@@ -240,6 +240,7 @@
     * <br>http://apache.org/xml/features/validation/schema (default: true)
     * <br>http://apache.org/xml/features/validation/schema-full-checking (default: false)
     * <br>http://apache.org/xml/features/nonvalidating/load-external-dtd (default: true)
+    * <br>http://apache.org/xml/features/nonvalidating/load-schema (default: true)
     * <br>http://apache.org/xml/features/continue-after-fatal-error (default: false)
     * <br>http://apache.org/xml/features/validation-error-as-fatal (default: false)  
     *
Index: src/xercesc/util/XMLUni.cpp
===================================================================
--- src/xercesc/util/XMLUni.cpp (revision 671547)
+++ src/xercesc/util/XMLUni.cpp (working copy)
@@ -1059,6 +1059,21 @@
     ,   chLatin_d, chLatin_t, chLatin_d, chNull
 };
 
+//Xerces: http://apache.org/xml/features/nonvalidating/load-schema
+const XMLCh XMLUni::fgXercesLoadSchema[] =
+{
+        chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash
+    ,   chForwardSlash, chLatin_a, chLatin_p, chLatin_a, chLatin_c, chLatin_h
+    ,   chLatin_e, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash
+    ,   chLatin_x, chLatin_m, chLatin_l, chForwardSlash, chLatin_f, chLatin_e
+    ,   chLatin_a, chLatin_t, chLatin_u, chLatin_r, chLatin_e, chLatin_s
+    ,   chForwardSlash, chLatin_n, chLatin_o, chLatin_n
+    ,   chLatin_v, chLatin_a, chLatin_l, chLatin_i, chLatin_d
+    ,   chLatin_a, chLatin_t, chLatin_i, chLatin_n, chLatin_g, chForwardSlash
+    ,   chLatin_l, chLatin_o, chLatin_a, chLatin_d, chDash
+    ,   chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a
+};
+
 //Xerces: http://apache.org/xml/features/continue-after-fatal-error
 const XMLCh XMLUni::fgXercesContinueAfterFatalError[] =
 {
Index: src/xercesc/util/XMLUni.hpp
===================================================================
--- src/xercesc/util/XMLUni.hpp (revision 671547)
+++ src/xercesc/util/XMLUni.hpp (working copy)
@@ -216,6 +216,7 @@
     static const XMLCh fgXercesSchemaExternalNoNameSpaceSchemaLocation[];
     static const XMLCh fgXercesSecurityManager[];
     static const XMLCh fgXercesLoadExternalDTD[];
+    static const XMLCh fgXercesLoadSchema[];
     static const XMLCh fgXercesContinueAfterFatalError[];
     static const XMLCh fgXercesValidationErrorAsFatal[];
     static const XMLCh fgXercesUserAdoptsDOMDocument[];
Index: src/xercesc/validators/schema/TraverseSchema.cpp
===================================================================
--- src/xercesc/validators/schema/TraverseSchema.cpp (revision 671547)
+++ src/xercesc/validators/schema/TraverseSchema.cpp (working copy)
@@ -634,6 +634,11 @@
         return;
     }
 
+    if (!fScanner->getLoadSchema()) {
+        reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError, includeURL);
+        return;
+    }
+
     // ------------------------------------------------------------------
     // Parse input source
     // ------------------------------------------------------------------
@@ -848,6 +853,11 @@
             return;
     }
 
+    if (!fScanner->getLoadSchema()) {
+        reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError, importURL);
+        return;
+    }
+
     // ------------------------------------------------------------------
     // Parse input source
     // ------------------------------------------------------------------
@@ -8167,6 +8177,11 @@
         return false;
     }
 
+    if (!fScanner->getLoadSchema()) {
+        reportSchemaError(redefineElem, XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError, includeURL);
+        return false;
+    }
+
     // ------------------------------------------------------------------
     // Parse input source
     // ------------------------------------------------------------------


---------------------------------------------------------------------
To unsubscribe, e-mail: c-dev-unsubscribe@...
For additional commands, e-mail: c-dev-help@...

Re: [PATCH] x2: Disabling automatic schema loading, and more schema validation

by Boris Kolpackov-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Wouter,

Wouter Coene <wouter+xerces-c@...> writes:

> See attachment (load-schema2.patch) for a patch against Xerces-C's trunk as
> of this afternoon (SVN rev 671547).

Ok, your patch is in SVN. I've made a couple of changes (I don't think
your modifications to scanners were correct) so can you try it on your
application to make sure everything works as expected?


> I'm a bit uncertain of the changes in TraverseSchema though.

Yes, those changes were incorrect. We don't need to worry about
import/include since these will never be triggered once no-load
is set (that is, you first need to load a top-level schema which
is not possible except with an explicit loadGrammar call in which
case we want import/include to work).

Thanks for the patch!

Boris

--
Boris Kolpackov, Code Synthesis Tools   http://codesynthesis.com/~boris/blog
Open source XML data binding for C++:   http://codesynthesis.com/products/xsd
Mobile/embedded validating XML parsing: http://codesynthesis.com/products/xsde

---------------------------------------------------------------------
To unsubscribe, e-mail: c-dev-unsubscribe@...
For additional commands, e-mail: c-dev-help@...

LightInTheBox - Buy quality products at wholesale price