Author: markt Date: Wed Jun 27 10:16:33 2018 New Revision: 1834490 URL: http://svn.apache.org/viewvc?rev=1834490&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=53387 Add support for regular expression capture groups to the SSI servlet and filter.
Added: tomcat/trunk/test/org/apache/catalina/ssi/TestRegExpCapture.java (with props) tomcat/trunk/test/webapp/bug5nnnn/bug53387.shtml Modified: tomcat/trunk/java/org/apache/catalina/ssi/ExpressionParseTree.java tomcat/trunk/java/org/apache/catalina/ssi/SSIMediator.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/ssi/ExpressionParseTree.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ssi/ExpressionParseTree.java?rev=1834490&r1=1834489&r2=1834490&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/ssi/ExpressionParseTree.java (original) +++ tomcat/trunk/java/org/apache/catalina/ssi/ExpressionParseTree.java Wed Jun 27 10:16:33 2018 @@ -20,6 +20,7 @@ package org.apache.catalina.ssi; import java.text.ParseException; import java.util.LinkedList; import java.util.List; +import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; /** @@ -368,11 +369,14 @@ public class ExpressionParseTree { val2.charAt(val2Len - 1) == '/') { // Treat as a regular expression String expr = val2.substring(1, val2Len - 1); + ssiMediator.clearMatchGroups(); try { Pattern pattern = Pattern.compile(expr); // Regular expressions will only ever be used with EqualNode // so return zero for equal and non-zero for not equal - if (pattern.matcher(val1).find()) { + Matcher matcher = pattern.matcher(val1); + if (matcher.find()) { + ssiMediator.populateMatchGroups(matcher); return 0; } else { return -1; Modified: tomcat/trunk/java/org/apache/catalina/ssi/SSIMediator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ssi/SSIMediator.java?rev=1834490&r1=1834489&r2=1834490&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/ssi/SSIMediator.java (original) +++ tomcat/trunk/java/org/apache/catalina/ssi/SSIMediator.java Wed Jun 27 10:16:33 2018 @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.Locale; import java.util.Set; import java.util.TimeZone; +import java.util.regex.Matcher; import org.apache.catalina.util.Strftime; import org.apache.catalina.util.URLEncoder; @@ -52,6 +53,7 @@ public class SSIMediator { protected final long lastModifiedDate; protected Strftime strftime; protected final SSIConditionalState conditionalState = new SSIConditionalState(); + protected int lastMatchCount = 0; public SSIMediator(SSIExternalResolver ssiExternalResolver, @@ -332,4 +334,24 @@ public class SSIMediator { retVal); } } + + + protected void clearMatchGroups() { + for (int i = 1; i <= lastMatchCount; i++) { + setVariableValue(Integer.toString(i), ""); + } + lastMatchCount = 0; + } + + + protected void populateMatchGroups(Matcher matcher) { + lastMatchCount = matcher.groupCount(); + // $0 is not used + if (lastMatchCount == 0) { + return; + } + for (int i = 1; i <= lastMatchCount; i++) { + setVariableValue(Integer.toString(i), matcher.group(i)); + } + } } \ No newline at end of file Added: tomcat/trunk/test/org/apache/catalina/ssi/TestRegExpCapture.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/ssi/TestRegExpCapture.java?rev=1834490&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/catalina/ssi/TestRegExpCapture.java (added) +++ tomcat/trunk/test/org/apache/catalina/ssi/TestRegExpCapture.java Wed Jun 27 10:16:33 2018 @@ -0,0 +1,96 @@ +/* + * 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 org.apache.catalina.ssi; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import org.apache.catalina.Context; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.tomcat.util.buf.ByteChunk; +import org.apache.tomcat.util.descriptor.web.FilterDef; +import org.apache.tomcat.util.descriptor.web.FilterMap; + +@RunWith(Parameterized.class) +public class TestRegExpCapture extends TomcatBaseTest { + + @Parameters(name = "{index}: [{0}]") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + + // d is always the empty string + // Neither a nor b are set, c is empty + parameterSets.add(new Object[] { "", "<p>a(none)b(none)cd</p>" }); + // a is set, b is not, c is empty + parameterSets.add(new Object[] { "?a=1", "<p>a1b(none)cd</p>" }); + // a is not set, b is set, c is the same as b + parameterSets.add(new Object[] { "?b=1", "<p>a(none)b1c1d</p>" }); + + return parameterSets; + } + + private final String queryString; + private final String expectedInBody; + + + public TestRegExpCapture(String queryString, String expectedInBody) { + this.queryString = queryString; + this.expectedInBody = expectedInBody; + } + + @Test + public void testBug53387() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + File appDir = new File("test/webapp"); + Context ctx = tomcat.addWebapp(null, "/test", appDir.getAbsolutePath()); + + // SSI requires a privileged Context + ctx.setPrivileged(true); + + FilterDef ssiFilter = new FilterDef(); + ssiFilter.setFilterName("ssiFilter"); + ssiFilter.setFilterClass(SSIFilter.class.getName()); + FilterMap ssiFilterMap = new FilterMap(); + ssiFilterMap.setFilterName("ssiFilter"); + ssiFilterMap.addURLPatternDecoded("*.shtml"); + ctx.addFilterDef(ssiFilter); + ctx.addFilterMap(ssiFilterMap); + + ctx.addMimeMapping("shtml", "text/x-server-parsed-html"); + + tomcat.start(); + + ByteChunk body = new ByteChunk(); + int rc = getUrl("http://localhost:" + getPort() + + "/test/bug5nnnn/bug53387.shtml" + queryString, body, null); + + Assert.assertEquals(200, rc); + + String text = body.toString(); + Assert.assertTrue(text, text.contains(expectedInBody)); + } +} Propchange: tomcat/trunk/test/org/apache/catalina/ssi/TestRegExpCapture.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/test/webapp/bug5nnnn/bug53387.shtml URL: http://svn.apache.org/viewvc/tomcat/trunk/test/webapp/bug5nnnn/bug53387.shtml?rev=1834490&view=auto ============================================================================== --- tomcat/trunk/test/webapp/bug5nnnn/bug53387.shtml (added) +++ tomcat/trunk/test/webapp/bug5nnnn/bug53387.shtml Wed Jun 27 10:16:33 2018 @@ -0,0 +1,27 @@ +<!-- + 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. +--> +<p>Before</p> +<!--#set var="d" value="$1" --> +<!--#if expr="$QUERY_STRING = /a=(.*)/" --> + <!--#set var="a" value="$1" --> +<!--#endif --> +<!--#if expr="$QUERY_STRING = /b=(.*)/" --> + <!--#set var="b" value="$1" --> +<!--#endif --> +<!--#set var="c" value="$1" --> +<p>a<!--#echo var="a" -->b<!--#echo var="b" -->c<!--#echo var="c" -->d<!--#echo var="d" --></p> +<p>After</p> \ No newline at end of file Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1834490&r1=1834489&r2=1834490&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Wed Jun 27 10:16:33 2018 @@ -51,6 +51,10 @@ Make the <code>isLocked()</code> method of the <code>LockOutRealm</code> public and expose the method via JMX. (markt) </add> + <add> + <bug>53387</bug>: Add support for regular expression capture groups to + the SSI servlet and filter. (markt) + </add> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org