Author: markt
Date: Mon Dec  9 10:01:16 2013
New Revision: 1549528

URL: http://svn.apache.org/r1549528
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. The 
block is implemented via a custom resolver to enable the logging of any blocked 
entities.

Modified:
    tomcat/trunk/java/org/apache/catalina/Context.java
    tomcat/trunk/java/org/apache/catalina/Globals.java
    tomcat/trunk/java/org/apache/catalina/ant/ValidatorTask.java
    tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java
    tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
    tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
    tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java
    tomcat/trunk/java/org/apache/jasper/Constants.java
    tomcat/trunk/java/org/apache/jasper/JspC.java
    tomcat/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java
    tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
    tomcat/trunk/java/org/apache/jasper/compiler/TagPluginManager.java
    tomcat/trunk/java/org/apache/jasper/compiler/TldCache.java
    tomcat/trunk/java/org/apache/jasper/servlet/JasperInitializer.java
    tomcat/trunk/java/org/apache/jasper/servlet/JspCServletContext.java
    tomcat/trunk/java/org/apache/jasper/servlet/TldScanner.java
    tomcat/trunk/java/org/apache/tomcat/util/descriptor/DigesterFactory.java
    tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java
    tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalStrings.properties
    
tomcat/trunk/java/org/apache/tomcat/util/descriptor/tagplugin/TagPluginParser.java
    tomcat/trunk/java/org/apache/tomcat/util/descriptor/tld/TldParser.java
    tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/WebXmlParser.java
    tomcat/trunk/test/javax/servlet/resources/TestSchemaValidation.java
    tomcat/trunk/test/org/apache/catalina/core/TesterContext.java
    tomcat/trunk/test/org/apache/jasper/servlet/TestTldScanner.java
    tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java
    tomcat/trunk/test/org/apache/tomcat/util/descriptor/tld/TestTldParser.java
    tomcat/trunk/webapps/docs/config/context.xml
    tomcat/trunk/webapps/docs/security-howto.xml

Modified: tomcat/trunk/java/org/apache/catalina/Context.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Context.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Context.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Context.java Mon Dec  9 10:01:16 2013
@@ -617,6 +617,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/trunk/java/org/apache/catalina/Globals.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Globals.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Globals.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Globals.java Mon Dec  9 10:01:16 2013
@@ -279,4 +279,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/trunk/java/org/apache/catalina/ant/ValidatorTask.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ant/ValidatorTask.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/ant/ValidatorTask.java (original)
+++ tomcat/trunk/java/org/apache/catalina/ant/ValidatorTask.java Mon Dec  9 
10:01:16 2013
@@ -24,6 +24,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;
@@ -90,7 +91,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/trunk/java/org/apache/catalina/core/ApplicationContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java Mon Dec  
9 10:01:16 2013
@@ -304,12 +304,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);
     }
 
@@ -322,11 +330,14 @@ public class ApplicationContext
     public Enumeration<String> getInitParameterNames() {
         Set<String> names = new HashSet<>();
         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/trunk/java/org/apache/catalina/core/StandardContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Mon Dec  9 
10:01:16 2013
@@ -699,6 +699,13 @@ public class StandardContext extends Con
      */
     private boolean webXmlNamespaceAware = Globals.STRICT_SERVLET_COMPLIANCE;
 
+
+    /**
+     * Attribute used to turn on/off the use of external entities.
+     */
+    private boolean xmlBlockExternal = Globals.IS_SECURITY_ENABLED;
+
+
     /**
      * Attribute value used to turn on/off XML validation
      */
@@ -6387,6 +6394,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/trunk/java/org/apache/catalina/startup/ContextConfig.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java Mon Dec  9 
10:01:16 2013
@@ -730,7 +730,7 @@ public class ContextConfig implements Li
         contextConfig(contextDigester);
 
         webXmlParser = new WebXmlParser(context.getXmlNamespaceAware(),
-                context.getXmlValidation());
+                context.getXmlValidation(), context.getXmlBlockExternal());
     }
 
 

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

Modified: tomcat/trunk/java/org/apache/jasper/Constants.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/Constants.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/Constants.java (original)
+++ tomcat/trunk/java/org/apache/jasper/Constants.java Mon Dec  9 10:01:16 2013
@@ -160,4 +160,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/trunk/java/org/apache/jasper/JspC.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/JspC.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/JspC.java (original)
+++ tomcat/trunk/java/org/apache/jasper/JspC.java Mon Dec  9 10:01:16 2013
@@ -134,6 +134,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;
@@ -165,6 +166,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;
@@ -373,6 +375,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 +
@@ -860,6 +864,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;
     }
@@ -1440,8 +1452,12 @@ 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");
+        }
 
-        TldScanner scanner = new TldScanner(context, true, isValidateTld());
+        TldScanner scanner = new TldScanner(
+                context, true, isValidateTld(), isBlockExternal());
         scanner.setClassLoader(classLoader);
 
         try {

Modified: 
tomcat/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java 
(original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java 
Mon Dec  9 10:01:16 2013
@@ -24,6 +24,7 @@ import java.util.Hashtable;
 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;
@@ -119,10 +120,20 @@ class ImplicitTagLibraryInfo extends Tag
                     try {
                         URL url = ctxt.getResource(path);
                         TldResourcePath resourcePath = new 
TldResourcePath(url, path);
+                        ServletContext servletContext = 
ctxt.getServletContext();
                         boolean validate = Boolean.parseBoolean(
-                                ctxt.getServletContext().getInitParameter(
+                                servletContext.getInitParameter(
                                         
Constants.XML_VALIDATION_TLD_INIT_PARAM));
-                        TldParser parser = new TldParser(true, validate, new 
ImplicitTldRuleSet());
+                        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);
+                        }
+                        TldParser parser = new TldParser(true, validate,
+                                new ImplicitTldRuleSet(), blockExternal);
                         taglibXml = parser.parse(resourcePath);
                     } catch (IOException | SAXException e) {
                         err.jspError(e);

Modified: tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java 
(original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java Mon Dec 
 9 10:01:16 2013
@@ -28,8 +28,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.apache.tomcat.util.descriptor.tld.TldResourcePath;
 import org.apache.tomcat.util.scan.Jar;
 import org.xml.sax.Attributes;
@@ -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 final ErrorDispatcher err;
     private final 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);
     }
 
     /*
@@ -232,13 +251,26 @@ class JspDocumentParser
         }
     }
 
+
+    @Override
+    public InputSource getExternalSubset(String name, String baseURI)
+            throws SAXException, IOException {
+        return entityResolver.getExternalSubset(name, baseURI);
+    }
+
     @Override
-    public InputSource resolveEntity(String name, String publicId, String 
baseURI, String systemId)
+    public InputSource resolveEntity(String publicId, String systemId)
             throws SAXException, IOException {
-        // TODO URLs returned by the Jar abstraction may be of the form 
jar:jar: which
-        // is not a URL that can be resolved by the JRE. This should use the 
JarFactory
-        // to construct and return a valid InputSource.
-        return null;
+        return entityResolver.resolveEntity(publicId, systemId);
+    }
+
+    @Override
+    public InputSource resolveEntity(String name, String publicId,
+            String baseURI, String systemId) throws SAXException, IOException {
+        // TODO URLs returned by the Jar abstraction may be of the form 
jar:jar:
+        //      which is not a URL that can be resolved by the JRE. This should
+        //      use the JarFactory to construct and return a valid InputSource.
+        return entityResolver.resolveEntity(name, publicId, baseURI, systemId);
     }
 
     /*

Modified: tomcat/trunk/java/org/apache/jasper/compiler/TagPluginManager.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/TagPluginManager.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/TagPluginManager.java 
(original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/TagPluginManager.java Mon Dec  
9 10:01:16 2013
@@ -24,6 +24,7 @@ import java.util.Map;
 
 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;
@@ -61,7 +62,16 @@ public class TagPluginManager {
         if (initialized)
             return;
 
-        TagPluginParser parser = new TagPluginParser(ctxt);
+        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);
+        }
+
+        TagPluginParser parser = new TagPluginParser(ctxt, blockExternal);
 
         try {
             Enumeration<URL> urls =

Modified: tomcat/trunk/java/org/apache/jasper/compiler/TldCache.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/TldCache.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/TldCache.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/TldCache.java Mon Dec  9 
10:01:16 2013
@@ -74,7 +74,15 @@ public class TldCache {
         }
         boolean validate = Boolean.parseBoolean(
                 
servletContext.getInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM));
-        tldParser = new TldParser(true, 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);
+        }
+        tldParser = new TldParser(true, validate, blockExternal);
     }
 
 

Modified: tomcat/trunk/java/org/apache/jasper/servlet/JasperInitializer.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/servlet/JasperInitializer.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/servlet/JasperInitializer.java 
(original)
+++ tomcat/trunk/java/org/apache/jasper/servlet/JasperInitializer.java Mon Dec  
9 10:01:16 2013
@@ -80,9 +80,17 @@ public class JasperInitializer implement
 
         boolean validate = Boolean.parseBoolean(
                 
context.getInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM));
+        String blockExternalString = context.getInitParameter(
+                Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
+        boolean blockExternal;
+        if (blockExternalString == null) {
+            blockExternal = Constants.IS_SECURITY_ENABLED;
+        } else {
+            blockExternal = Boolean.parseBoolean(blockExternalString);
+        }
 
         // scan the application for TLDs
-        TldScanner scanner = new TldScanner(context, true, validate);
+        TldScanner scanner = new TldScanner(context, true, validate, 
blockExternal);
         try {
             scanner.scan();
         } catch (IOException | SAXException e) {

Modified: tomcat/trunk/java/org/apache/jasper/servlet/JspCServletContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/servlet/JspCServletContext.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/servlet/JspCServletContext.java 
(original)
+++ tomcat/trunk/java/org/apache/jasper/servlet/JspCServletContext.java Mon Dec 
 9 10:01:16 2013
@@ -44,11 +44,11 @@ import javax.servlet.SessionCookieConfig
 import javax.servlet.SessionTrackingMode;
 import javax.servlet.descriptor.JspConfigDescriptor;
 
+import org.apache.jasper.Constants;
 import org.apache.jasper.JasperException;
 import org.apache.jasper.compiler.Localizer;
 import org.apache.jasper.util.ExceptionUtils;
 import org.apache.tomcat.JarScanType;
-import org.apache.tomcat.util.descriptor.web.Constants;
 import org.apache.tomcat.util.descriptor.web.FragmentJarScannerCallback;
 import org.apache.tomcat.util.descriptor.web.WebXml;
 import org.apache.tomcat.util.descriptor.web.WebXmlParser;
@@ -124,13 +124,21 @@ public class JspCServletContext implemen
 
     private WebXml buildMergedWebXml() throws JasperException {
         WebXml webXml = new WebXml();
-
-        WebXmlParser webXmlParser = new WebXmlParser(false, false);
+        String blockExternalString = getInitParameter(
+                Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
+        boolean blockExternal;
+        if (blockExternalString == null) {
+            blockExternal = Constants.IS_SECURITY_ENABLED;
+        } else {
+            blockExternal = Boolean.parseBoolean(blockExternalString);
+        }
+        WebXmlParser webXmlParser = new WebXmlParser(false, false, 
blockExternal);
         // Use this class's classloader as Ant will have set the TCCL to its 
own
         webXmlParser.setClassLoader(getClass().getClassLoader());
 
         try {
-            URL url = getResource(Constants.WEB_XML_LOCATION);
+            URL url = getResource(
+                    
org.apache.tomcat.util.descriptor.web.Constants.WEB_XML_LOCATION);
             if (!webXmlParser.parseWebXml(url, webXml, false)) {
                 throw new 
JasperException(Localizer.getMessage("jspc.error.invalidWebXml"));
             }

Modified: tomcat/trunk/java/org/apache/jasper/servlet/TldScanner.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/servlet/TldScanner.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/servlet/TldScanner.java (original)
+++ tomcat/trunk/java/org/apache/jasper/servlet/TldScanner.java Mon Dec  9 
10:01:16 2013
@@ -72,9 +72,11 @@ public class TldScanner {
      */
     public TldScanner(ServletContext context,
                       boolean namespaceAware,
-                      boolean validation) {
+                      boolean validation,
+                      boolean blockExternal) {
         this.context = context;
-        this.tldParser = new TldParser(namespaceAware, validation);
+
+        this.tldParser = new TldParser(namespaceAware, validation, 
blockExternal);
     }
 
     /**

Modified: 
tomcat/trunk/java/org/apache/tomcat/util/descriptor/DigesterFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/descriptor/DigesterFactory.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/descriptor/DigesterFactory.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/descriptor/DigesterFactory.java 
Mon Dec  9 10:01:16 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.tomcat.util.descriptor;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -23,6 +24,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
@@ -31,10 +33,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<>();
@@ -89,7 +97,8 @@ public class DigesterFactory {
         addSelf(systemIds, "javaee_web_services_1_4.xsd");
         addSelf(systemIds, "javaee_web_services_client_1_4.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) {
@@ -107,15 +116,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/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java Mon 
Dec  9 10:01:16 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/trunk/java/org/apache/tomcat/util/descriptor/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalStrings.properties?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalStrings.properties 
Mon Dec  9 10:01:16 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/trunk/java/org/apache/tomcat/util/descriptor/tagplugin/TagPluginParser.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/descriptor/tagplugin/TagPluginParser.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/util/descriptor/tagplugin/TagPluginParser.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/util/descriptor/tagplugin/TagPluginParser.java
 Mon Dec  9 10:01:16 2013
@@ -42,8 +42,9 @@ public class TagPluginParser {
     private final Digester digester;
     private final Map<String, String> plugins = new HashMap<>();
 
-    public TagPluginParser(ServletContext context) {
-        digester = DigesterFactory.newDigester(false, false, new 
TagPluginRuleSet());
+    public TagPluginParser(ServletContext context, boolean blockExternal) {
+        digester = DigesterFactory.newDigester(
+                false, false, new TagPluginRuleSet(), blockExternal);
         digester.setClassLoader(context.getClassLoader());
     }
 

Modified: tomcat/trunk/java/org/apache/tomcat/util/descriptor/tld/TldParser.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/descriptor/tld/TldParser.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/descriptor/tld/TldParser.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/descriptor/tld/TldParser.java Mon 
Dec  9 10:01:16 2013
@@ -35,12 +35,15 @@ public class TldParser {
     private static final Log log = LogFactory.getLog(TldParser.class);
     private final Digester digester;
 
-    public TldParser(boolean namespaceAware, boolean validation) {
-        this(namespaceAware, validation, new TldRuleSet());
+    public TldParser(boolean namespaceAware, boolean validation,
+            boolean blockExternal) {
+        this(namespaceAware, validation, new TldRuleSet(), blockExternal);
     }
 
-    public TldParser(boolean namespaceAware, boolean validation, RuleSet 
ruleSet) {
-        digester = DigesterFactory.newDigester(validation, namespaceAware, 
ruleSet);
+    public TldParser(boolean namespaceAware, boolean validation, RuleSet 
ruleSet,
+            boolean blockExternal) {
+        digester = DigesterFactory.newDigester(
+                validation, namespaceAware, ruleSet, blockExternal);
     }
 
     public TaglibXml parse(TldResourcePath path) throws IOException, 
SAXException {

Modified: 
tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/WebXmlParser.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/WebXmlParser.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/WebXmlParser.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/WebXmlParser.java 
Mon Dec  9 10:01:16 2013
@@ -55,15 +55,16 @@ public class WebXmlParser {
     private final WebRuleSet webFragmentRuleSet;
 
 
-    public WebXmlParser(boolean namespaceAware, boolean validation) {
+    public WebXmlParser(boolean namespaceAware, boolean validation,
+            boolean blockExternal) {
         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/trunk/test/javax/servlet/resources/TestSchemaValidation.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/javax/servlet/resources/TestSchemaValidation.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/test/javax/servlet/resources/TestSchemaValidation.java 
(original)
+++ tomcat/trunk/test/javax/servlet/resources/TestSchemaValidation.java Mon Dec 
 9 10:01:16 2013
@@ -31,8 +31,8 @@ public class TestSchemaValidation {
 
     @Test
     public void testWebapp() 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/WEB-INF/web.xml"));
@@ -41,8 +41,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"));
@@ -52,8 +52,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"));
@@ -63,8 +63,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"));
@@ -73,8 +73,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"));
@@ -83,8 +83,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"));
@@ -93,8 +93,8 @@ public class TestSchemaValidation {
 
     @Test
     public void testWebapp_3_1() 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.1/WEB-INF/web.xml"));

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

Modified: tomcat/trunk/test/org/apache/jasper/servlet/TestTldScanner.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/jasper/servlet/TestTldScanner.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/jasper/servlet/TestTldScanner.java (original)
+++ tomcat/trunk/test/org/apache/jasper/servlet/TestTldScanner.java Mon Dec  9 
10:01:16 2013
@@ -39,7 +39,8 @@ public class TestTldScanner extends Tomc
         Context context = tomcat.addWebapp(null, "/test", 
appDir.getAbsolutePath());
         tomcat.start();
 
-        TldScanner scanner = new TldScanner(context.getServletContext(), true, 
true);
+        TldScanner scanner =
+                new TldScanner(context.getServletContext(), true, true, true);
         scanner.scan();
         Assert.assertEquals(5, scanner.getUriTldResourcePathMap().size());
         Assert.assertEquals(1, scanner.getListeners().size());

Modified: 
tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java 
(original)
+++ tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java 
Mon Dec  9 10:01:16 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<>();
     private final Map<String, String> systemIds = new HashMap<>();
 
-    private LocalResolver resolver = new LocalResolver(publicIds, systemIds);
+    private LocalResolver resolver = new LocalResolver(publicIds, systemIds, 
true);
     private String WEB_22_LOCAL;
     private String WEB_31_LOCAL;
     private String WEBCOMMON_31_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_31_LOCAL, source.getSystemId());
     }
-}
\ No newline at end of file
+}

Modified: 
tomcat/trunk/test/org/apache/tomcat/util/descriptor/tld/TestTldParser.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/descriptor/tld/TestTldParser.java?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/descriptor/tld/TestTldParser.java 
(original)
+++ tomcat/trunk/test/org/apache/tomcat/util/descriptor/tld/TestTldParser.java 
Mon Dec  9 10:01:16 2013
@@ -36,7 +36,7 @@ public class TestTldParser {
 
     @Before
     public void init() {
-        parser = new TldParser(true, true);
+        parser = new TldParser(true, true, null, true);
     }
 
     @Test

Modified: tomcat/trunk/webapps/docs/config/context.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/context.xml?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/trunk/webapps/docs/config/context.xml Mon Dec  9 10:01:16 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/trunk/webapps/docs/security-howto.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/security-howto.xml?rev=1549528&r1=1549527&r2=1549528&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/security-howto.xml (original)
+++ tomcat/trunk/webapps/docs/security-howto.xml Mon Dec  9 10:01:16 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-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to