Author: markt Date: Tue Jul 9 10:07:23 2013 New Revision: 1501176 URL: http://svn.apache.org/r1501176 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55218 and https://issues.apache.org/bugzilla/show_bug.cgi?id=55219 Upgrade digester to use DefaultHandler2 and use LexicalHandler to detect publicId. Simplify web application version detection in web.xml Extracted from a patch by Jeremy Boynes.
Added: tomcat/trunk/test/javax/servlet/resources/ tomcat/trunk/test/javax/servlet/resources/TestSchemaValidation.java (with props) Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/LocalStrings.properties tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/WebXml.java tomcat/trunk/java/org/apache/tomcat/util/digester/Digester.java tomcat/trunk/test/org/apache/tomcat/util/descriptor/web/TestWebXml.java 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=1501176&r1=1501175&r2=1501176&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Tue Jul 9 10:07:23 2013 @@ -113,6 +113,7 @@ import org.apache.tomcat.JarScanner; import org.apache.tomcat.util.ExceptionUtils; import org.apache.tomcat.util.IntrospectionUtils; import org.apache.tomcat.util.buf.UDecoder; +import org.apache.tomcat.util.descriptor.XmlIdentifiers; import org.apache.tomcat.util.descriptor.web.ApplicationListener; import org.apache.tomcat.util.descriptor.web.ApplicationParameter; import org.apache.tomcat.util.descriptor.web.ErrorPage; @@ -5759,17 +5760,10 @@ public class StandardContext extends Con */ @Override public boolean isServlet22() { - - if (this.publicId == null) - return (false); - if (this.publicId.equals - (org.apache.catalina.startup.Constants.WebDtdPublicId_22)) - return (true); - else - return (false); - + return XmlIdentifiers.WEB_22_PUBLIC.equals(publicId); } + @Override public Set<String> addServletSecurity( ServletRegistration.Dynamic registration, Modified: tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/LocalStrings.properties?rev=1501176&r1=1501175&r2=1501176&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/LocalStrings.properties Tue Jul 9 10:07:23 2013 @@ -48,5 +48,5 @@ webXml.mergeConflictSessionTrackingMode= webXml.mergeConflictString=The [{0}] with name [{1}] was defined inconsistently in multiple fragments including fragment with name [{2}] located at [{3}] webXml.multipleOther=Multiple others entries in ordering webXml.unrecognisedPublicId=The public ID [{0}] did not match any of the known public ID's for web.xml files so the version could not be identified -webXml.version.nfe=Unable to parse [{0}] from the version string [{1}]. This component of the version string will be ignored. +webXml.version.unknown=Unknown version string [{0}]. Default version will be used. webXml.wrongFragmentName=Used a wrong fragment name {0} at web.xml absolute-ordering tag! \ No newline at end of file Modified: tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/WebXml.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/WebXml.java?rev=1501176&r1=1501175&r2=1501176&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/WebXml.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/descriptor/web/WebXml.java Tue Jul 9 10:07:23 2013 @@ -32,6 +32,7 @@ import java.util.Set; import javax.servlet.ServletContext; import javax.servlet.SessionTrackingMode; +import org.apache.tomcat.util.descriptor.XmlIdentifiers; import org.apache.tomcat.util.res.StringManager; /** @@ -127,93 +128,55 @@ public class WebXml { * @param version Values of <code>null</code> will be ignored */ public void setVersion(String version) { - if (version == null) return; - - // Update major and minor version - // Expected format is n.n - allow for any number of digits just in case - String major = null; - String minor = null; - int split = version.indexOf('.'); - if (split < 0) { - // Major only - major = version; - } else { - major = version.substring(0, split); - minor = version.substring(split + 1); - } - if (major == null || major.length() == 0) { - majorVersion = 0; - } else { - try { - majorVersion = Integer.parseInt(major); - } catch (NumberFormatException nfe) { - log.warn(sm.getString("webXml.version.nfe", major, version), - nfe); - majorVersion = 0; - } + if (version == null) { + return; } - - if (minor == null || minor.length() == 0) { - minorVersion = 0; - } else { - try { - minorVersion = Integer.parseInt(minor); - } catch (NumberFormatException nfe) { - log.warn(sm.getString("webXml.version.nfe", minor, version), - nfe); + switch (version) { + case "2.4": + majorVersion = 2; + minorVersion = 4; + break; + case "2.5": + majorVersion = 2; + minorVersion = 5; + break; + case "3.0": + majorVersion = 3; minorVersion = 0; - } + break; + case "3.1": + majorVersion = 3; + minorVersion = 1; + break; + default: + log.warn(sm.getString("webXml.version.unknown", version)); } } + // Optional publicId attribute private String publicId = null; public String getPublicId() { return publicId; } public void setPublicId(String publicId) { // Update major and minor version if (publicId == null) { - // skip - } else if (org.apache.catalina.startup.Constants.WebSchemaPublicId_31. - equalsIgnoreCase(publicId) || - org.apache.catalina.startup.Constants.WebFragmentSchemaPublicId_31. - equalsIgnoreCase(publicId)) { - majorVersion = 3; - minorVersion = 1; - this.publicId = publicId; - } else if (org.apache.catalina.startup.Constants.WebSchemaPublicId_30. - equalsIgnoreCase(publicId) || - org.apache.catalina.startup.Constants.WebFragmentSchemaPublicId_30. - equalsIgnoreCase(publicId)) { - majorVersion = 3; - minorVersion = 0; - this.publicId = publicId; - } else if (org.apache.catalina.startup.Constants.WebSchemaPublicId_25. - equalsIgnoreCase(publicId)) { - majorVersion = 2; - minorVersion = 5; - this.publicId = publicId; - } else if (org.apache.catalina.startup.Constants.WebSchemaPublicId_24. - equalsIgnoreCase(publicId)) { - majorVersion = 2; - minorVersion = 4; - this.publicId = publicId; - } else if (org.apache.catalina.startup.Constants.WebDtdPublicId_23. - equalsIgnoreCase(publicId)) { - majorVersion = 2; - minorVersion = 3; - this.publicId = publicId; - } else if (org.apache.catalina.startup.Constants.WebDtdPublicId_22. - equalsIgnoreCase(publicId)) { - majorVersion = 2; - minorVersion = 2; - this.publicId = publicId; - } else if ("datatypes".equals(publicId)) { - // Will occur when validation is enabled and dependencies are - // traced back. Ignore it. - } else { - // Unrecognised publicId - log.warn(sm.getString("webXml.unrecognisedPublicId", publicId)); + return; + } + switch (publicId) { + case XmlIdentifiers.WEB_22_PUBLIC: + majorVersion = 2; + minorVersion = 2; + this.publicId = publicId; + break; + case XmlIdentifiers.WEB_23_PUBLIC: + majorVersion = 2; + minorVersion = 3; + this.publicId = publicId; + break; + default: + log.warn(sm.getString("webXml.unrecognisedPublicId", publicId)); + break; } } Modified: tomcat/trunk/java/org/apache/tomcat/util/digester/Digester.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/digester/Digester.java?rev=1501176&r1=1501175&r2=1501176&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/digester/Digester.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/digester/Digester.java Tue Jul 9 10:07:23 2013 @@ -21,6 +21,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.EmptyStackException; import java.util.HashMap; import java.util.Iterator; @@ -45,8 +47,8 @@ import org.xml.sax.SAXNotRecognizedExcep import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; +import org.xml.sax.ext.DefaultHandler2; import org.xml.sax.helpers.AttributesImpl; -import org.xml.sax.helpers.DefaultHandler; /** @@ -68,7 +70,7 @@ import org.xml.sax.helpers.DefaultHandle * the support of XML schema. You need Xerces 2.1/2.3 and up to make * this class working with XML schema</p> */ -public class Digester extends DefaultHandler { +public class Digester extends DefaultHandler2 { // ---------------------------------------------------------- Static Fields @@ -791,6 +793,9 @@ public class Digester extends DefaultHan reader.setEntityResolver(entityResolver); } + reader.setProperty( + "http://xml.org/sax/properties/lexical-handler", this); + reader.setErrorHandler(this); return reader; } @@ -1275,26 +1280,15 @@ public class Digester extends DefaultHan return entityResolver; } - /** - * Resolve the requested external entity. - * - * @param publicId The public identifier of the entity being referenced - * @param systemId The system identifier of the entity being referenced - * - * @exception SAXException if a parsing exception occurs - * - */ @Override - public InputSource resolveEntity(String publicId, String systemId) - throws SAXException { + public InputSource resolveEntity(String name, String publicId, + String baseURI, String systemId) throws SAXException, IOException { if (saxLog.isDebugEnabled()) { - saxLog.debug("resolveEntity('" + publicId + "', '" + systemId + "')"); + saxLog.debug("resolveEntity('" + publicId + "', '" + systemId + + "', '" + baseURI + "')"); } - if (publicId != null) - this.publicId = publicId; - // Has this system identifier been registered? String entityURL = null; if (publicId != null) { @@ -1312,9 +1306,24 @@ public class Digester extends DefaultHan } else { // try to resolve using system ID if (log.isDebugEnabled()) { - log.debug(" Trying to resolve using system ID '" + systemId + "'"); + log.debug(" Trying to resolve using system ID '" + + systemId + "'"); } entityURL = systemId; + // resolve systemId against baseURI if it is not absolute + if (baseURI != null) { + try { + URI uri = new URI(systemId); + if (!uri.isAbsolute()) { + entityURL = new URI(baseURI).resolve(uri).toString(); + } + } catch (URISyntaxException e) { + if (log.isDebugEnabled()) { + log.debug("Invalid URI '" + baseURI + "' or '" + + systemId + "'"); + } + } + } } } @@ -1331,8 +1340,16 @@ public class Digester extends DefaultHan } - // ------------------------------------------------- ErrorHandler Methods + // ----------------------------------------------- LexicalHandler Methods + @Override + public void startDTD(String name, String publicId, String systemId) + throws SAXException { + setPublicId(publicId); + } + + + // ------------------------------------------------- ErrorHandler Methods /** * Forward notification of a parsing error to the application supplied Added: tomcat/trunk/test/javax/servlet/resources/TestSchemaValidation.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/javax/servlet/resources/TestSchemaValidation.java?rev=1501176&view=auto ============================================================================== --- tomcat/trunk/test/javax/servlet/resources/TestSchemaValidation.java (added) +++ tomcat/trunk/test/javax/servlet/resources/TestSchemaValidation.java Tue Jul 9 10:07:23 2013 @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package javax.servlet.resources; + +import java.io.File; + +import org.junit.Assert; +import org.junit.Test; + +import org.apache.catalina.startup.WebRuleSet; +import org.apache.tomcat.util.descriptor.DigesterFactory; +import org.apache.tomcat.util.descriptor.XmlIdentifiers; +import org.apache.tomcat.util.descriptor.web.WebXml; +import org.apache.tomcat.util.digester.Digester; + +public class TestSchemaValidation { + + @Test + public void testWebapp() throws Exception { + Digester digester = + DigesterFactory.newDigester(true, true, new WebRuleSet(false)); + digester.push(new WebXml()); + WebXml desc = (WebXml) digester.parse( + new File("test/webapp/WEB-INF/web.xml")); + Assert.assertEquals("3.1", desc.getVersion()); + } + + @Test + public void testWebapp_2_2() throws Exception { + Digester digester = + DigesterFactory.newDigester(true, true, new WebRuleSet(false)); + digester.push(new WebXml()); + WebXml desc = (WebXml) digester.parse( + new File("test/webapp-2.2/WEB-INF/web.xml")); + Assert.assertEquals("2.2", desc.getVersion()); + Assert.assertEquals(XmlIdentifiers.WEB_22_PUBLIC, desc.getPublicId()); + } + + @Test + public void testWebapp_2_3() throws Exception { + Digester digester = + DigesterFactory.newDigester(true, true, new WebRuleSet(false)); + digester.push(new WebXml()); + WebXml desc = (WebXml) digester.parse( + new File("test/webapp-2.3/WEB-INF/web.xml")); + Assert.assertEquals("2.3", desc.getVersion()); + Assert.assertEquals(XmlIdentifiers.WEB_23_PUBLIC, desc.getPublicId()); + } + + @Test + public void testWebapp_2_4() throws Exception { + Digester digester = + DigesterFactory.newDigester(true, true, new WebRuleSet(false)); + digester.push(new WebXml()); + WebXml desc = (WebXml) digester.parse( + new File("test/webapp-2.4/WEB-INF/web.xml")); + Assert.assertEquals("2.4", desc.getVersion()); + } + + @Test + public void testWebapp_2_5() throws Exception { + Digester digester = + DigesterFactory.newDigester(true, true, new WebRuleSet(false)); + digester.push(new WebXml()); + WebXml desc = (WebXml) digester.parse( + new File("test/webapp-2.5/WEB-INF/web.xml")); + Assert.assertEquals("2.5", desc.getVersion()); + } + + @Test + public void testWebapp_3_0() throws Exception { + Digester digester = + DigesterFactory.newDigester(true, true, new WebRuleSet(false)); + digester.push(new WebXml()); + WebXml desc = (WebXml) digester.parse( + new File("test/webapp-3.0/WEB-INF/web.xml")); + Assert.assertEquals("3.0", desc.getVersion()); + } + + @Test + public void testWebapp_3_1() throws Exception { + Digester digester = + DigesterFactory.newDigester(true, true, new WebRuleSet(false)); + digester.push(new WebXml()); + WebXml desc = (WebXml) digester.parse( + new File("test/webapp-3.1/WEB-INF/web.xml")); + Assert.assertEquals("3.1", desc.getVersion()); + } +} Propchange: tomcat/trunk/test/javax/servlet/resources/TestSchemaValidation.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/test/org/apache/tomcat/util/descriptor/web/TestWebXml.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/descriptor/web/TestWebXml.java?rev=1501176&r1=1501175&r2=1501176&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/util/descriptor/web/TestWebXml.java (original) +++ tomcat/trunk/test/org/apache/tomcat/util/descriptor/web/TestWebXml.java Tue Jul 9 10:07:23 2013 @@ -23,6 +23,9 @@ import java.util.Set; import org.junit.Assert; import org.junit.Test; +import org.apache.tomcat.util.descriptor.XmlIdentifiers; + + /** * Test case for {@link WebXml}. */ @@ -42,38 +45,15 @@ public class TestWebXml { Assert.assertEquals(2, webxml.getMajorVersion()); Assert.assertEquals(5, webxml.getMinorVersion()); - // Reset + // unknown input should be ignored webxml.setVersion("0.0"); - Assert.assertEquals(0, webxml.getMajorVersion()); - Assert.assertEquals(0, webxml.getMinorVersion()); + Assert.assertEquals(2, webxml.getMajorVersion()); + Assert.assertEquals(5, webxml.getMinorVersion()); // null input should be ignored webxml.setVersion(null); - Assert.assertEquals(0, webxml.getMajorVersion()); - Assert.assertEquals(0, webxml.getMinorVersion()); - - // major only - webxml.setVersion("3"); - Assert.assertEquals(3, webxml.getMajorVersion()); - Assert.assertEquals(0, webxml.getMinorVersion()); - - // no minor digit - webxml.setVersion("0.0"); // reset - webxml.setVersion("3."); - Assert.assertEquals(3, webxml.getMajorVersion()); - Assert.assertEquals(0, webxml.getMinorVersion()); - - // minor only - webxml.setVersion("0.0"); // reset - webxml.setVersion(".5"); - Assert.assertEquals(0, webxml.getMajorVersion()); - Assert.assertEquals(5, webxml.getMinorVersion()); - - // leading & training zeros - webxml.setVersion("0.0"); // reset - webxml.setVersion("002.500"); Assert.assertEquals(2, webxml.getMajorVersion()); - Assert.assertEquals(500, webxml.getMinorVersion()); + Assert.assertEquals(5, webxml.getMinorVersion()); } @Test @@ -81,8 +61,7 @@ public class TestWebXml { WebXml webxml = new WebXml(); - webxml.setPublicId( - org.apache.catalina.startup.Constants.WebDtdPublicId_22); + webxml.setPublicId(XmlIdentifiers.WEB_22_PUBLIC); Assert.assertEquals(2, webxml.getMajorVersion()); Assert.assertEquals(2, webxml.getMinorVersion()); Assert.assertEquals("2.2", webxml.getVersion()); @@ -93,56 +72,51 @@ public class TestWebXml { WebXml webxml = new WebXml(); - webxml.setPublicId( - org.apache.catalina.startup.Constants.WebDtdPublicId_23); + webxml.setPublicId(XmlIdentifiers.WEB_23_PUBLIC); Assert.assertEquals(2, webxml.getMajorVersion()); Assert.assertEquals(3, webxml.getMinorVersion()); Assert.assertEquals("2.3", webxml.getVersion()); } @Test - public void testParsePublicIdVersion24() { + public void testParseVersion24() { WebXml webxml = new WebXml(); - webxml.setPublicId( - org.apache.catalina.startup.Constants.WebSchemaPublicId_24); + webxml.setVersion("2.4"); Assert.assertEquals(2, webxml.getMajorVersion()); Assert.assertEquals(4, webxml.getMinorVersion()); Assert.assertEquals("2.4", webxml.getVersion()); } @Test - public void testParsePublicIdVersion25() { + public void testParseVersion25() { WebXml webxml = new WebXml(); - webxml.setPublicId( - org.apache.catalina.startup.Constants.WebSchemaPublicId_25); + webxml.setVersion("2.5"); Assert.assertEquals(2, webxml.getMajorVersion()); Assert.assertEquals(5, webxml.getMinorVersion()); Assert.assertEquals("2.5", webxml.getVersion()); } @Test - public void testParsePublicIdVersion30() { + public void testParseVersion30() { WebXml webxml = new WebXml(); - webxml.setPublicId( - org.apache.catalina.startup.Constants.WebSchemaPublicId_30); + webxml.setVersion("3.0"); Assert.assertEquals(3, webxml.getMajorVersion()); Assert.assertEquals(0, webxml.getMinorVersion()); Assert.assertEquals("3.0", webxml.getVersion()); } @Test - public void testParsePublicIdVersion31() { + public void testParseVersion31() { WebXml webxml = new WebXml(); - webxml.setPublicId( - org.apache.catalina.startup.Constants.WebSchemaPublicId_31); + webxml.setVersion("3.1"); Assert.assertEquals(3, webxml.getMajorVersion()); Assert.assertEquals(1, webxml.getMinorVersion()); Assert.assertEquals("3.1", webxml.getVersion()); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org