You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/12/09 11:05:57 UTC

svn commit: r1549529 - in /tomcat/tc7.0.x/trunk: ./ java/org/apache/catalina/ java/org/apache/catalina/ant/ java/org/apache/catalina/core/ java/org/apache/catalina/startup/ java/org/apache/jasper/ java/org/apache/jasper/compiler/ java/org/apache/jasper...

Author: markt
Date: Mon Dec  9 10:05:56 2013
New Revision: 1549529

URL: http://svn.apache.org/r1549529
Log:
Add an option to the Context to control the blocking of XML external entities when parsing XML configuration files and enable this blocking by default when a security manager is used. The block is implemented via a custom resolver to enable the logging of any blocked entities.

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/Context.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/Globals.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/ant/ValidatorTask.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/ApplicationContext.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/StandardContext.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/FailedContext.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java
    tomcat/tc7.0.x/trunk/java/org/apache/jasper/Constants.java
    tomcat/tc7.0.x/trunk/java/org/apache/jasper/JspC.java
    tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java
    tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspConfig.java
    tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
    tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java
    tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TagPluginManager.java
    tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java
    tomcat/tc7.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/DigesterFactory.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/LocalStrings.properties
    tomcat/tc7.0.x/trunk/test/javax/servlet/resources/TestSchemaValidation.java
    tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterContext.java
    tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
    tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml
    tomcat/tc7.0.x/trunk/webapps/docs/security-howto.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1549528

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/Context.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/Context.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/Context.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/Context.java Mon Dec  9 10:05:56 2013
@@ -675,6 +675,25 @@ public interface Context extends Contain
 
 
     /**
+     * Will the parsing of web.xml, web-fragment.xml, *.tld, *.jspx, *.tagx and
+     * tagplugin.xml files for this Context block the use of external entities?
+     *
+     * @return true if access to external entities is blocked
+     */
+    public boolean getXmlBlockExternal();
+
+
+    /**
+     * Controls whether the parsing of web.xml, web-fragment.xml, *.tld, *.jspx,
+     * *.tagx and tagplugin.xml files for this Context will block the use of
+     * external entities.
+     *
+     * @param xmlBlockExternal true to block external entities
+     */
+    public void setXmlBlockExternal(boolean xmlBlockExternal);
+
+
+    /**
      * Will the parsing of *.tld files for this Context be performed by a
      * validating parser?
      *

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/Globals.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/Globals.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/Globals.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/Globals.java Mon Dec  9 10:05:56 2013
@@ -316,4 +316,15 @@ public final class Globals {
      */
     public static final String JASPER_XML_VALIDATION_TLD_INIT_PARAM =
             "org.apache.jasper.XML_VALIDATE_TLD";
+
+
+    /**
+     * Name of the ServletContext init-param that determines if the JSP engine
+     * will block external entities from being used in *.tld, *.jspx, *.tagx and
+     * tagplugin.xml files.
+     * <p>
+     * This must be kept in sync with org.apache.jasper.Constants
+     */
+    public static final String JASPER_XML_BLOCK_EXTERNAL_INIT_PARAM =
+            "org.apache.jasper.XML_BLOCK_EXTERNAL";
 }

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/ant/ValidatorTask.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/ant/ValidatorTask.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/ant/ValidatorTask.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/ant/ValidatorTask.java Mon Dec  9 10:05:56 2013
@@ -21,6 +21,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 
+import org.apache.catalina.Globals;
 import org.apache.catalina.startup.Constants;
 import org.apache.tomcat.util.descriptor.DigesterFactory;
 import org.apache.tomcat.util.digester.Digester;
@@ -87,7 +88,10 @@ public class ValidatorTask extends BaseR
         Thread.currentThread().setContextClassLoader
             (ValidatorTask.class.getClassLoader());
 
-        Digester digester = DigesterFactory.newDigester(true, true, null);
+        // Called through trusted manager interface. If running under a
+        // SecurityManager assume that untrusted applications may be deployed.
+        Digester digester = DigesterFactory.newDigester(
+                true, true, null, Globals.IS_SECURITY_ENABLED);
         try {
             file = file.getCanonicalFile();
             InputStream stream = 

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/ApplicationContext.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/ApplicationContext.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/ApplicationContext.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/ApplicationContext.java Mon Dec  9 10:05:56 2013
@@ -320,12 +320,20 @@ public class ApplicationContext
      */
     @Override
     public String getInitParameter(final String name) {
-        // Special handling for XML validation as the context setting must
+        // Special handling for XML settings as the context setting must
         // always override anything that might have been set by an application.
         if (Globals.JASPER_XML_VALIDATION_TLD_INIT_PARAM.equals(name) &&
                 context.getTldValidation()) {
             return "true";
         }
+        if (Globals.JASPER_XML_BLOCK_EXTERNAL_INIT_PARAM.equals(name)) {
+            if (context.getXmlBlockExternal()) {
+                return "true";
+            } else if (Globals.IS_SECURITY_ENABLED) {
+                // System admin has explicitly changed the default
+                return "false";
+            }
+        }
         return parameters.get(name);
     }
 
@@ -338,11 +346,14 @@ public class ApplicationContext
     public Enumeration<String> getInitParameterNames() {
         Set<String> names = new HashSet<String>();
         names.addAll(parameters.keySet());
-        // Special handling for XML validation as this attribute will always be
-        // available if validation has been enabled on the context
+        // Special handling for XML settings as these attributes will always be
+        // available if they have been set on the context
         if (context.getTldValidation()) {
             names.add(Globals.JASPER_XML_VALIDATION_TLD_INIT_PARAM);
         }
+        if (context.getXmlBlockExternal() || Globals.IS_SECURITY_ENABLED) {
+            names.add(Globals.JASPER_XML_BLOCK_EXTERNAL_INIT_PARAM);
+        }
         return Collections.enumeration(names);
     }
 

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/StandardContext.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/StandardContext.java Mon Dec  9 10:05:56 2013
@@ -698,6 +698,13 @@ public class StandardContext extends Con
     protected int cacheMaxSize = 10240; // 10 MB
 
 
+
+    /**
+     * Attribute used to turn on/off the use of external entities.
+     */
+    private boolean xmlBlockExternal = Globals.IS_SECURITY_ENABLED;
+
+
     /**
      * Cache object max size in KB.
      */
@@ -6625,6 +6632,18 @@ public class StandardContext extends Con
 
 
     @Override
+    public void setXmlBlockExternal(boolean xmlBlockExternal) {
+        this.xmlBlockExternal = xmlBlockExternal;
+    }
+
+
+    @Override
+    public boolean getXmlBlockExternal() {
+        return xmlBlockExternal;
+    }
+
+
+    @Override
     public void setTldValidation(boolean tldValidation){
         this.tldValidation = tldValidation;
     }

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java Mon Dec  9 10:05:56 2013
@@ -516,14 +516,16 @@ public class ContextConfig implements Li
     public void createWebXmlDigester(boolean namespaceAware,
             boolean validation) {
 
+        boolean blockExternal = context.getXmlBlockExternal();
+        
         webRuleSet = new WebRuleSet(false);
         webDigester = DigesterFactory.newDigester(validation,
-                namespaceAware, webRuleSet);
+                namespaceAware, webRuleSet, blockExternal);
         webDigester.getParser();
 
         webFragmentRuleSet = new WebRuleSet(true);
         webFragmentDigester = DigesterFactory.newDigester(validation,
-                namespaceAware, webFragmentRuleSet);
+                namespaceAware, webFragmentRuleSet, blockExternal);
         webFragmentDigester.getParser();
     }
 

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/FailedContext.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/FailedContext.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/FailedContext.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/FailedContext.java Mon Dec  9 10:05:56 2013
@@ -428,6 +428,11 @@ public class FailedContext extends Lifec
     @Override
     public void setTldValidation(boolean tldValidation) { /* NO-OP */ }
     @Override
+    public boolean getXmlBlockExternal() { return true; }
+    @Override
+    public void setXmlBlockExternal(boolean xmlBlockExternal) { /* NO-OP */ }
+
+    @Override
     public boolean getTldValidation() { return false; }
 
     @Override

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java Mon Dec  9 10:05:56 2013
@@ -85,20 +85,21 @@ public final class TldConfig  implements
      * Create (if necessary) and return a Digester configured to process the
      * tld.
      */
-    private static Digester createTldDigester(boolean validation) {
+    private static Digester createTldDigester(boolean validation,
+            boolean blockExternal) {
         
         Digester digester = null;
         if (!validation) {
             if (tldDigesters[0] == null) {
                 tldDigesters[0] = DigesterFactory.newDigester(validation,
-                        true, new TldRuleSet());
+                        true, new TldRuleSet(), blockExternal);
                 tldDigesters[0].getParser();
             }
             digester = tldDigesters[0];
         } else {
             if (tldDigesters[1] == null) {
                 tldDigesters[1] = DigesterFactory.newDigester(validation,
-                        true, new TldRuleSet());
+                        true, new TldRuleSet(), blockExternal);
                 tldDigesters[1].getParser();
             }
             digester = tldDigesters[1];
@@ -567,7 +568,8 @@ public final class TldConfig  implements
     
     private void init() {
         if (tldDigester == null){
-            tldDigester = createTldDigester(context.getTldValidation());
+            tldDigester = createTldDigester(context.getTldValidation(),
+                    context.getXmlBlockExternal());
         }
     }
 

Modified: tomcat/tc7.0.x/trunk/java/org/apache/jasper/Constants.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/Constants.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/jasper/Constants.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/jasper/Constants.java Mon Dec  9 10:05:56 2013
@@ -241,4 +241,13 @@ public class Constants {
      */
     public static final String XML_VALIDATION_TLD_INIT_PARAM =
             "org.apache.jasper.XML_VALIDATE_TLD";
+
+    /**
+     * Name of the ServletContext init-param that determines if the XML parsers
+     * will block the resolution of external entities.
+     * <p>
+     * This must be kept in sync with org.apache.catalina.Globals
+     */
+    public static final String XML_BLOCK_EXTERNAL_INIT_PARAM =
+            "org.apache.jasper.XML_BLOCK_EXTERNAL";
 }

Modified: tomcat/tc7.0.x/trunk/java/org/apache/jasper/JspC.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/JspC.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/jasper/JspC.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/jasper/JspC.java Mon Dec  9 10:05:56 2013
@@ -127,6 +127,7 @@ public class JspC extends Task implement
     protected static final String SWITCH_SMAP = "-smap";
     protected static final String SWITCH_DUMP_SMAP = "-dumpsmap";
     protected static final String SWITCH_VALIDATE_TLD = "-validateTld";
+    protected static final String SWITCH_BLOCK_EXTERNAL = "-blockExternal";
     protected static final String SHOW_SUCCESS ="-s";
     protected static final String LIST_ERRORS = "-l";
     protected static final int INC_WEBXML = 10;
@@ -158,6 +159,7 @@ public class JspC extends Task implement
     protected boolean trimSpaces = false;
     protected boolean genStringAsCharArray = false;
     protected boolean validateTld;
+    protected boolean blockExternal;
     protected boolean xpoweredBy;
     protected boolean mappedFile = false;
     protected boolean poolingEnabled = true;
@@ -367,6 +369,8 @@ public class JspC extends Task implement
                 smapDumped = true;
             } else if (tok.equals(SWITCH_VALIDATE_TLD)) {
                 setValidateTld(true);
+            } else if (tok.equals(SWITCH_BLOCK_EXTERNAL)) {
+                setBlockExternal(true);
             } else {
                 if (tok.startsWith("-")) {
                     throw new JasperException("Unrecognized option: " + tok +
@@ -854,6 +858,14 @@ public class JspC extends Task implement
         return validateTld;
     }
 
+    public void setBlockExternal( boolean b ) {
+        this.blockExternal = b;
+    }
+
+    public boolean isBlockExternal() {
+        return blockExternal;
+    }
+
     public void setListErrors( boolean b ) {
         listErrors = b;
     }
@@ -1435,6 +1447,9 @@ public class JspC extends Task implement
         if (isValidateTld()) {
             context.setInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM, "true");
         }
+        if (isBlockExternal()) {
+            context.setInitParameter(Constants.XML_BLOCK_EXTERNAL_INIT_PARAM, "true");
+        }
 
         rctxt = new JspRuntimeContext(context, this);
         jspConfig = new JspConfig(context);

Modified: tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java Mon Dec  9 10:05:56 2013
@@ -23,6 +23,7 @@ import java.util.Iterator;
 import java.util.Set;
 import java.util.Vector;
 
+import javax.servlet.ServletContext;
 import javax.servlet.jsp.tagext.FunctionInfo;
 import javax.servlet.jsp.tagext.TagFileInfo;
 import javax.servlet.jsp.tagext.TagInfo;
@@ -124,11 +125,21 @@ class ImplicitTagLibraryInfo extends Tag
                                 pi.addDependant(path, ctxt.getLastModified(path));
                             }
                             
+                            ServletContext servletContext = ctxt.getServletContext();
                             boolean validate = Boolean.parseBoolean(
-                                    ctxt.getServletContext().getInitParameter(
+                                    servletContext.getInitParameter(
                                             Constants.XML_VALIDATION_TLD_INIT_PARAM));
-
-                            ParserUtils pu = new ParserUtils(validate);
+                            String blockExternalString =
+                                    servletContext.getInitParameter(
+                                            Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
+                            boolean blockExternal;
+                            if (blockExternalString == null) {
+                                blockExternal = Constants.IS_SECURITY_ENABLED;
+                            } else {
+                                blockExternal = Boolean.parseBoolean(blockExternalString);
+                            }
+                            
+                            ParserUtils pu = new ParserUtils(validate, blockExternal);
                             TreeNode tld = pu.parseXMLDocument(uri, in);
 
                             if (tld.findAttribute("version") != null) {

Modified: tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspConfig.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspConfig.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspConfig.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspConfig.java Mon Dec  9 10:05:56 2013
@@ -80,10 +80,18 @@ public class JspConfig {
             
             boolean validate = Boolean.parseBoolean(
                     ctxt.getInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM));
+            String blockExternalString =
+                    ctxt.getInitParameter(Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
+            boolean blockExternal;
+            if (blockExternalString == null) {
+                blockExternal = Constants.IS_SECURITY_ENABLED;
+            } else {
+                blockExternal = Boolean.parseBoolean(blockExternalString);
+            }
 
             TreeNode webApp = null;
             if (webXml.getInputSource() != null) {
-                ParserUtils pu = new ParserUtils(validate);
+                ParserUtils pu = new ParserUtils(validate, blockExternal);
                 webApp = pu.parseXMLDocument(webXml.getSystemId(),
                         webXml.getInputSource());
             }

Modified: tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java Mon Dec  9 10:05:56 2013
@@ -30,8 +30,11 @@ import javax.servlet.jsp.tagext.TagLibra
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 
+import org.apache.jasper.Constants;
 import org.apache.jasper.JasperException;
 import org.apache.jasper.JspCompilationContext;
+import org.apache.tomcat.util.descriptor.DigesterFactory;
+import org.apache.tomcat.util.descriptor.LocalResolver;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.Locator;
@@ -39,6 +42,7 @@ import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 import org.xml.sax.XMLReader;
 import org.xml.sax.ext.DefaultHandler2;
+import org.xml.sax.ext.EntityResolver2;
 import org.xml.sax.helpers.AttributesImpl;
 
 /**
@@ -91,6 +95,7 @@ class JspDocumentParser
     private boolean inDTD;
 
     private boolean isValidating;
+    private final EntityResolver2 entityResolver;
 
     private ErrorDispatcher err;
     private boolean isTagFile;
@@ -119,6 +124,20 @@ class JspDocumentParser
         this.isTagFile = isTagFile;
         this.directivesOnly = directivesOnly;
         this.isTop = true;
+
+        String blockExternalString = ctxt.getServletContext().getInitParameter(
+                Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
+        boolean blockExternal;
+        if (blockExternalString == null) {
+            blockExternal = Constants.IS_SECURITY_ENABLED;
+        } else {
+            blockExternal = Boolean.parseBoolean(blockExternalString);
+        }
+
+        this.entityResolver = new LocalResolver(
+                DigesterFactory.SERVLET_API_PUBLIC_IDS,
+                DigesterFactory.SERVLET_API_SYSTEM_IDS,
+                blockExternal);
     }
 
     /*
@@ -239,12 +258,29 @@ class JspDocumentParser
         }
     }
 
+    
+    @Override
+    public InputSource getExternalSubset(String name, String baseURI)
+            throws SAXException, IOException {
+        return entityResolver.getExternalSubset(name, baseURI);
+    }
+
+    
+    
+    @Override
+    public InputSource resolveEntity(String publicId, String systemId)
+            throws SAXException, IOException {
+        return entityResolver.resolveEntity(publicId, systemId);
+    }
+
+    
     @Override
     public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId)
             throws SAXException, IOException {
-        return null;
+        return entityResolver.resolveEntity(name, publicId, baseURI, systemId);
     }
 
+    
     /*
      * Receives notification of the start of an element.
      *

Modified: tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java Mon Dec  9 10:05:56 2013
@@ -31,6 +31,7 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Vector;
 
+import javax.servlet.ServletContext;
 import javax.servlet.jsp.tagext.FunctionInfo;
 import javax.servlet.jsp.tagext.PageData;
 import javax.servlet.jsp.tagext.TagAttributeInfo;
@@ -213,12 +214,20 @@ class TagLibraryInfoImpl extends TagLibr
         Vector<TagFileInfo> tagFileVector = new Vector<TagFileInfo>();
         Hashtable<String, FunctionInfo> functionTable = new Hashtable<String, FunctionInfo>();
 
-        boolean validate = Boolean.parseBoolean(
-                ctxt.getServletContext().getInitParameter(
-                        Constants.XML_VALIDATION_TLD_INIT_PARAM));
+        ServletContext servletContext = ctxt.getServletContext();
+        boolean validate = Boolean.parseBoolean(servletContext.getInitParameter(
+                Constants.XML_VALIDATION_TLD_INIT_PARAM));
+        String blockExternalString = servletContext.getInitParameter(
+                Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
+        boolean blockExternal;
+        if (blockExternalString == null) {
+            blockExternal = Constants.IS_SECURITY_ENABLED;
+        } else {
+            blockExternal = Boolean.parseBoolean(blockExternalString);
+        }
 
         // Create an iterator over the child elements of our <taglib> element
-        ParserUtils pu = new ParserUtils(validate);
+        ParserUtils pu = new ParserUtils(validate, blockExternal);
         TreeNode tld = pu.parseXMLDocument(uri, in);
 
         // Check to see if the <taglib> root element contains a 'version'

Modified: tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TagPluginManager.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TagPluginManager.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TagPluginManager.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TagPluginManager.java Mon Dec  9 10:05:56 2013
@@ -25,6 +25,7 @@ import java.util.Iterator;
 
 import javax.servlet.ServletContext;
 
+import org.apache.jasper.Constants;
 import org.apache.jasper.JasperException;
 import org.apache.jasper.compiler.tagplugin.TagPlugin;
 import org.apache.jasper.compiler.tagplugin.TagPluginContext;
@@ -119,8 +120,18 @@ public class TagPluginManager {
     private void loadTagPlugins(ErrorDispatcher err, InputStream is)
             throws JasperException {
 
-        TreeNode root =
-                (new ParserUtils(false)).parseXMLDocument(TAG_PLUGINS_XML, is);
+        String blockExternalString = ctxt.getInitParameter(
+                Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
+        boolean blockExternal;
+        if (blockExternalString == null) {
+            blockExternal = Constants.IS_SECURITY_ENABLED;
+        } else {
+            blockExternal = Boolean.parseBoolean(blockExternalString);
+        }
+        
+        ParserUtils pu = new ParserUtils(false, blockExternal);
+        
+        TreeNode root = pu.parseXMLDocument(TAG_PLUGINS_XML, is);
         if (root == null) {
             return;
         }

Modified: tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java Mon Dec  9 10:05:56 2013
@@ -289,10 +289,20 @@ public class TldLocationsCache {
             boolean validate = Boolean.parseBoolean(
                     ctxt.getInitParameter(
                             Constants.XML_VALIDATION_TLD_INIT_PARAM));
-
+            String blockExternalString = ctxt.getInitParameter(
+                    Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
+            boolean blockExternal;
+            if (blockExternalString == null) {
+                blockExternal = Constants.IS_SECURITY_ENABLED;
+            } else {
+                blockExternal = Boolean.parseBoolean(blockExternalString);
+            }
+            
             // Parse the web application deployment descriptor
+            ParserUtils pu = new ParserUtils(validate, blockExternal);
+            
             TreeNode webtld = null;
-            webtld = new ParserUtils(validate).parseXMLDocument(webXml.getSystemId(),
+            webtld = pu.parseXMLDocument(webXml.getSystemId(),
                     webXml.getInputSource());
 
             // Allow taglib to be an element of the root or jsp-config (JSP2.0)
@@ -498,9 +508,17 @@ public class TldLocationsCache {
             boolean validate = Boolean.parseBoolean(
                     ctxt.getInitParameter(
                             Constants.XML_VALIDATION_TLD_INIT_PARAM));
-
-            TreeNode tld = new ParserUtils(validate).parseXMLDocument(
-                    resourcePath, stream);
+            String blockExternalString = ctxt.getInitParameter(
+                    Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
+            boolean blockExternal;
+            if (blockExternalString == null) {
+                blockExternal = Constants.IS_SECURITY_ENABLED;
+            } else {
+                blockExternal = Boolean.parseBoolean(blockExternalString);
+            }
+            
+            ParserUtils pu = new ParserUtils(validate, blockExternal); 
+            TreeNode tld = pu.parseXMLDocument(resourcePath, stream);
             TreeNode uriNode = tld.findChild("uri");
             if (uriNode != null) {
                 String body = uriNode.getBody();

Modified: tomcat/tc7.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java Mon Dec  9 10:05:56 2013
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.jasper.xmlparser;
 
 import java.io.IOException;
@@ -24,9 +23,11 @@ import javax.xml.parsers.DocumentBuilder
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
+import org.apache.jasper.Constants;
 import org.apache.jasper.JasperException;
 import org.apache.jasper.compiler.Localizer;
 import org.apache.tomcat.util.descriptor.DigesterFactory;
+import org.apache.tomcat.util.descriptor.LocalResolver;
 import org.apache.tomcat.util.descriptor.XmlErrorHandler;
 import org.w3c.dom.Comment;
 import org.w3c.dom.Document;
@@ -49,7 +50,6 @@ import org.xml.sax.SAXParseException;
  * @author Craig R. McClanahan
  * @version $Id$
  */
-
 public class ParserUtils {
 
     /**
@@ -60,12 +60,25 @@ public class ParserUtils {
     /**
      * An entity resolver for use when parsing XML documents.
      */
-    static EntityResolver entityResolver = DigesterFactory.SERVLET_API_RESOLVER;
+    static EntityResolver entityResolver;
+    
+    private final EntityResolver entityResolverInstance;
     
     private final boolean validating;
 
     public ParserUtils(boolean validating) {
+        this(validating, Constants.IS_SECURITY_ENABLED);
+    }
+
+    public ParserUtils(boolean validating, boolean blockExternal) {
         this.validating = validating;
+        if (entityResolver == null) {
+            this.entityResolverInstance = new LocalResolver(
+                    DigesterFactory.SERVLET_API_PUBLIC_IDS,
+                    DigesterFactory.SERVLET_API_SYSTEM_IDS, blockExternal);
+        } else {
+            this.entityResolverInstance = entityResolver;
+        }
     }
 
     // --------------------------------------------------------- Public Methods
@@ -92,7 +105,7 @@ public class ParserUtils {
             factory.setNamespaceAware(true);
             factory.setValidating(validating);
             DocumentBuilder builder = factory.newDocumentBuilder();
-            builder.setEntityResolver(entityResolver);
+            builder.setEntityResolver(entityResolverInstance);
             builder.setErrorHandler(errorHandler);
             document = builder.parse(is);
         } catch (ParserConfigurationException ex) {

Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/DigesterFactory.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/DigesterFactory.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/DigesterFactory.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/DigesterFactory.java Mon Dec  9 10:05:56 2013
@@ -17,6 +17,7 @@
 package org.apache.tomcat.util.descriptor;
 
 import java.net.URL;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -24,6 +25,7 @@ import javax.servlet.ServletContext;
 
 import org.apache.tomcat.util.digester.Digester;
 import org.apache.tomcat.util.digester.RuleSet;
+import org.xml.sax.ext.EntityResolver2;
 
 /**
  * Wrapper class around the Digester that hide Digester's initialization
@@ -32,10 +34,16 @@ import org.apache.tomcat.util.digester.R
 public class DigesterFactory {
 
     /**
-     * A resolver for the resources packaged in servlet-api.jar
+     * Mapping of well-known public IDs used by the Servlet API to the matching
+     * local resource.
      */
-    public static final LocalResolver SERVLET_API_RESOLVER;
+    public static final Map<String,String> SERVLET_API_PUBLIC_IDS;
 
+    /**
+     * Mapping of well-known system IDs used by the Servlet API to the matching
+     * local resource.
+     */
+    public static final Map<String,String> SERVLET_API_SYSTEM_IDS;
 
     static {
         Map<String, String> publicIds = new HashMap<String, String>();
@@ -81,7 +89,8 @@ public class DigesterFactory {
         addSelf(systemIds, "javaee_web_services_1_3.xsd");
         addSelf(systemIds, "javaee_web_services_client_1_3.xsd");
 
-        SERVLET_API_RESOLVER = new LocalResolver(publicIds, systemIds);
+        SERVLET_API_PUBLIC_IDS = Collections.unmodifiableMap(publicIds);
+        SERVLET_API_SYSTEM_IDS = Collections.unmodifiableMap(systemIds);
     }
 
     private static void addSelf(Map<String, String> ids, String id) {
@@ -103,15 +112,19 @@ public class DigesterFactory {
      * @param xmlValidation turn on/off xml validation
      * @param xmlNamespaceAware turn on/off namespace validation
      * @param rule an instance of <code>RuleSet</code> used for parsing the xml.
+     * @param blockExternal turn on/off the blocking of external resources
      */
     public static Digester newDigester(boolean xmlValidation,
                                        boolean xmlNamespaceAware,
-                                       RuleSet rule) {
+                                       RuleSet rule,
+                                       boolean blockExternal) {
         Digester digester = new Digester();
         digester.setNamespaceAware(xmlNamespaceAware);
         digester.setValidating(xmlValidation);
         digester.setUseContextClassLoader(true);
-        digester.setEntityResolver(SERVLET_API_RESOLVER);
+        EntityResolver2 resolver = new LocalResolver(SERVLET_API_PUBLIC_IDS,
+                SERVLET_API_SYSTEM_IDS, blockExternal);
+        digester.setEntityResolver(resolver);
         if (rule != null) {
             digester.addRuleSet(rule);
         }

Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java Mon Dec  9 10:05:56 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.tomcat.util.descriptor;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URI;
@@ -23,6 +24,7 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Map;
 
+import org.apache.tomcat.util.res.StringManager;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.ext.EntityResolver2;
@@ -32,22 +34,30 @@ import org.xml.sax.ext.EntityResolver2;
  */
 public class LocalResolver implements EntityResolver2 {
 
+    private static final StringManager sm =
+            StringManager.getManager(Constants.PACKAGE_NAME);
+
     private final Map<String,String> publicIds;
     private final Map<String,String> systemIds;
-
+    private final boolean blockExternal;
 
     /**
      * Constructor providing mappings of public and system identifiers to local
      * resources. Each map contains a mapping from a well-known identifier to a
      * URL for a local resource path.
      *
-     * @param publicIds mapping of public identifiers to local resources
-     * @param systemIds mapping of system identifiers to local resources
+     * @param publicIds mapping of well-known public identifiers to local
+     *                  resources
+     * @param systemIds mapping of well-known system identifiers to local
+     *                  resources
+     * @param blockExternal are external resources blocked that are not
+     *                      well-known
      */
     public LocalResolver(Map<String,String> publicIds,
-            Map<String,String> systemIds) {
+            Map<String,String> systemIds, boolean blockExternal) {
         this.publicIds = publicIds;
         this.systemIds = systemIds;
+        this.blockExternal = blockExternal;
     }
 
 
@@ -60,63 +70,77 @@ public class LocalResolver implements En
 
     @Override
     public InputSource resolveEntity(String name, String publicId,
-            String baseURI, String systemId) throws SAXException, IOException {
-
-        String resolved = resolve(publicId, systemId, baseURI);
-        if (resolved == null) {
-            return null;
-        }
+            String base, String systemId) throws SAXException, IOException {
 
-        InputSource is = new InputSource(resolved);
-        is.setPublicId(publicId);
-        return is;
-    }
-
-
-    @Override
-    public InputSource getExternalSubset(String name, String baseURI)
-            throws SAXException, IOException {
-        return null;
-    }
-
-
-    private String resolve(String publicId, String systemId, String baseURI) {
-        // try resolving using the publicId
+        // First try resolving using the publicId
         String resolved = publicIds.get(publicId);
         if (resolved != null) {
-            return resolved;
+            InputSource is = new InputSource(resolved);
+            is.setPublicId(publicId);
+            return is;
         }
 
-        // try resolving using the systemId
+        // If there is no systemId, can't try anything else
         if (systemId == null) {
-            return null;
+            throw new FileNotFoundException(sm.getString("localResolver.unresolvedEntity",
+                    name, publicId, systemId, base));
         }
 
-        systemId = resolve(baseURI, systemId);
+        // Try resolving with the supplied systemId
         resolved = systemIds.get(systemId);
         if (resolved != null) {
-            return resolved;
+            InputSource is = new InputSource(resolved);
+            is.setPublicId(publicId);
+            return is;
         }
 
-        // fall back to the supplied systemId
-        return systemId;
-    }
-
-
-    private static String resolve(String baseURI, String systemId) {
+        // Resolve the supplied systemId against the base
+        URI systemUri;
         try {
-            if (baseURI == null) {
-                return systemId;
+            if (base == null) {
+                systemUri = new URI(systemId);
+            } else {
+                // Can't use URI.resolve() because "jar:..." URLs are not valid
+                // hierarchical URIs so resolve() does not work. new URL()
+                // delegates to the jar: stream handler and it manages to figure
+                // it out.
+                URI baseUri = new URI(base);
+                systemUri = new URL(baseUri.toURL(), systemId).toURI();
             }
-            URI systemUri = new URI(systemId);
-            if (systemUri.isAbsolute()) {
-                return systemId;
-            }
-            return new URL(new URL(baseURI), systemId).toString();
+            systemUri = systemUri.normalize();
         } catch (URISyntaxException e) {
-            return systemId;
-        } catch (MalformedURLException e) {
-            return systemId;
+            // May be caused by a | being used instead of a : in an absolute
+            // file URI on Windows.
+            if (blockExternal) {
+                // Absolute paths aren't allowed so block it
+                throw new MalformedURLException(e.getMessage());
+            } else {
+                // See if the URLHandler can resolve it
+                return new InputSource(systemId);
+            }
+        }
+        if (systemUri.isAbsolute()) {
+            // Try the resolved systemId
+            resolved = systemIds.get(systemUri.toString());
+            if (resolved != null) {
+                InputSource is = new InputSource(resolved);
+                is.setPublicId(publicId);
+                return is;
+            }
+            if (!blockExternal) {
+                InputSource is = new InputSource(systemUri.toString());
+                is.setPublicId(publicId);
+                return is;
+            }
         }
+        throw new FileNotFoundException(sm.getString("localResolver.unresolvedEntity",
+                name, publicId, systemId, base));
+    }
+
+
+    @Override
+    public InputSource getExternalSubset(String name, String baseURI)
+            throws SAXException, IOException {
+        return null;
     }
-}
\ No newline at end of file
+}

Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/LocalStrings.properties?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/LocalStrings.properties (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/descriptor/LocalStrings.properties Mon Dec  9 10:05:56 2013
@@ -13,5 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+localResolver.unresolvedEntity=Could not resolve XML resource [{0}] with public ID [{1}], system ID [{2}] and base URI [{3}] to a known, local entity.
+
 xmlErrorHandler.error=Non-fatal error [{0}] reported processing [{1}].
 xmlErrorHandler.warning=Warning [{0}] reported processing [{1}].

Modified: tomcat/tc7.0.x/trunk/test/javax/servlet/resources/TestSchemaValidation.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/javax/servlet/resources/TestSchemaValidation.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/test/javax/servlet/resources/TestSchemaValidation.java (original)
+++ tomcat/tc7.0.x/trunk/test/javax/servlet/resources/TestSchemaValidation.java Mon Dec  9 10:05:56 2013
@@ -31,8 +31,8 @@ public class TestSchemaValidation {
 
     @Test
     public void testWebapp_2_2() throws Exception {
-        Digester digester =
-                DigesterFactory.newDigester(true, true, new WebRuleSet(false));
+        Digester digester = DigesterFactory.newDigester(
+                true, true, new WebRuleSet(false), true);
         digester.push(new WebXml());
         WebXml desc = (WebXml) digester.parse(
                 new File("test/webapp-2.2/WEB-INF/web.xml"));
@@ -42,8 +42,8 @@ public class TestSchemaValidation {
 
     @Test
     public void testWebapp_2_3() throws Exception {
-        Digester digester =
-                DigesterFactory.newDigester(true, true, new WebRuleSet(false));
+        Digester digester = DigesterFactory.newDigester(
+                true, true, new WebRuleSet(false), true);
         digester.push(new WebXml());
         WebXml desc = (WebXml) digester.parse(
                 new File("test/webapp-2.3/WEB-INF/web.xml"));
@@ -53,8 +53,8 @@ public class TestSchemaValidation {
 
     @Test
     public void testWebapp_2_4() throws Exception {
-        Digester digester =
-                DigesterFactory.newDigester(true, true, new WebRuleSet(false));
+        Digester digester = DigesterFactory.newDigester(
+                true, true, new WebRuleSet(false), true);
         digester.push(new WebXml());
         WebXml desc = (WebXml) digester.parse(
                 new File("test/webapp-2.4/WEB-INF/web.xml"));
@@ -63,8 +63,8 @@ public class TestSchemaValidation {
 
     @Test
     public void testWebapp_2_5() throws Exception {
-        Digester digester =
-                DigesterFactory.newDigester(true, true, new WebRuleSet(false));
+        Digester digester = DigesterFactory.newDigester(
+                true, true, new WebRuleSet(false), true);
         digester.push(new WebXml());
         WebXml desc = (WebXml) digester.parse(
                 new File("test/webapp-2.5/WEB-INF/web.xml"));
@@ -73,8 +73,8 @@ public class TestSchemaValidation {
 
     @Test
     public void testWebapp_3_0() throws Exception {
-        Digester digester =
-                DigesterFactory.newDigester(true, true, new WebRuleSet(false));
+        Digester digester = DigesterFactory.newDigester(
+                true, true, new WebRuleSet(false), true);
         digester.push(new WebXml());
         WebXml desc = (WebXml) digester.parse(
                 new File("test/webapp-3.0/WEB-INF/web.xml"));

Modified: tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterContext.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterContext.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterContext.java (original)
+++ tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterContext.java Mon Dec  9 10:05:56 2013
@@ -636,6 +636,16 @@ public class TesterContext implements Co
     }
 
     @Override
+    public boolean getXmlBlockExternal() {
+        return false;
+    }
+
+    @Override
+    public void setXmlBlockExternal(boolean xmlBlockExternal) {
+        // NO-OP
+    }
+
+    @Override
     public boolean getTldNamespaceAware() {
         return true;
     }

Modified: tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java (original)
+++ tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java Mon Dec  9 10:05:56 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.tomcat.util.descriptor;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
@@ -34,7 +35,7 @@ public class TestLocalResolver {
     private final Map<String, String> publicIds = new HashMap<String, String>();
     private final Map<String, String> systemIds = new HashMap<String, String>();
 
-    private LocalResolver resolver = new LocalResolver(publicIds, systemIds);
+    private LocalResolver resolver = new LocalResolver(publicIds, systemIds, true);
     private String WEB_22_LOCAL;
     private String WEB_30_LOCAL;
     private String WEBCOMMON_30_LOCAL;
@@ -53,25 +54,25 @@ public class TestLocalResolver {
         return ServletContext.class.getResource(id).toExternalForm();
     }
 
-    @Test
-    public void unknownNullIdIsNull() throws IOException, SAXException {
+    @Test(expected = FileNotFoundException.class)
+    public void unknownNullId() throws IOException, SAXException {
         Assert.assertNull(resolver.resolveEntity(null, null));
     }
 
-    @Test
-    public void unknownPublicIdIsNull() throws IOException, SAXException {
+    @Test(expected = FileNotFoundException.class)
+    public void unknownPublicId() throws IOException, SAXException {
         Assert.assertNull(resolver.resolveEntity("unknown", null));
     }
 
-    @Test
-    public void unknownSystemIdIsReturned() throws IOException, SAXException {
+    @Test(expected = FileNotFoundException.class)
+    public void unknownSystemId() throws IOException, SAXException {
         InputSource source = resolver.resolveEntity(null, "unknown");
         Assert.assertEquals(null, source.getPublicId());
         Assert.assertEquals("unknown", source.getSystemId());
     }
 
-    @Test
-    public void unknownSystemIdIsResolvedAgainstBaseURI()
+    @Test(expected = FileNotFoundException.class)
+    public void unknownRelativeSystemId()
             throws IOException, SAXException {
         InputSource source = resolver.resolveEntity(
                 null, null, "http://example.com/home.html", "unknown");
@@ -121,4 +122,4 @@ public class TestLocalResolver {
         Assert.assertEquals(null, source.getPublicId());
         Assert.assertEquals(WEB_30_LOCAL, source.getSystemId());
     }
-}
\ No newline at end of file
+}

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Mon Dec  9 10:05:56 2013
@@ -216,6 +216,12 @@
         <bug>55851</bug>: Further fixes to enable SPNEGO authentication to work
         with IBM JDKs. Based on a patch by Arunav Sanyal. (markt)
       </fix>
+      <add>
+        Add an option to the Context to control the blocking of XML external
+        entities when parsing XML configuration files and enable this blocking
+        by default when a security manager is used. The block is implemented via
+        a custom resolver to enable the logging of any blocked entities. (markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Coyote">

Modified: tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml Mon Dec  9 10:05:56 2013
@@ -524,6 +524,16 @@
         Context.  If not specified, a standard default value will be used.</p>
       </attribute>
 
+      <attribute name="xmlBlockExternal" required="false">
+        <p>If the value of this flag is <code>true</code>, the parsing of
+        <code>web.xml</code>, <code>web-fragment.xml</code>, <code>*.tld</code>,
+        <code>*.jspx</code>, <code>*.tagx</code> and <code>tagPlugins.xml</code>
+        files for this web application will not permit external entities to be
+        loaded. If a <code>SecurityManager</code> is configured then the default
+        value of this attribute will be <code>true</code>, else the default
+        value will be <code>false</code>.</p>
+      </attribute>
+
       <attribute name="xmlNamespaceAware" required="false">
         <p>If the value of this flag is <code>true</code>, the parsing of
         <code>web.xml</code> and <code>web-fragment.xml</code> files for this

Modified: tomcat/tc7.0.x/trunk/webapps/docs/security-howto.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/security-howto.xml?rev=1549529&r1=1549528&r2=1549529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/security-howto.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/security-howto.xml Mon Dec  9 10:05:56 2013
@@ -179,6 +179,9 @@
     <ul>
       <li>The default value for the <strong>deployXML</strong> attribute of the
       <strong>Host</strong> element is changed to <code>false</code>.</li>
+      <li>The default value for the <strong>xmlBlockExternal</strong> attribute
+      of the <strong>Context</strong> element is changed to <code>true</code>.
+      </li>
     </ul>
   </section>
 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org