Author: markt
Date: Tue Sep 6 21:26:17 2016
New Revision: 1759516
URL: http://svn.apache.org/viewvc?rev=1759516&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=60013
Implement B and NE. Update unit tests to use B and/or NE where required.
Also make minor modifications to align unit tests with expected
behaviour of httpd.
Modified:
tomcat/trunk/java/org/apache/catalina/valves/rewrite/Resolver.java
tomcat/trunk/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
tomcat/trunk/java/org/apache/catalina/valves/rewrite/RewriteRule.java
tomcat/trunk/java/org/apache/catalina/valves/rewrite/RewriteValve.java
tomcat/trunk/java/org/apache/catalina/valves/rewrite/Substitution.java
tomcat/trunk/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
Modified: tomcat/trunk/java/org/apache/catalina/valves/rewrite/Resolver.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/rewrite/Resolver.java?rev=1759516&r1=1759515&r2=1759516&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/rewrite/Resolver.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/valves/rewrite/Resolver.java Tue Sep
6 21:26:17 2016
@@ -33,4 +33,6 @@ public abstract class Resolver {
public abstract String resolveHttp(String key);
public abstract boolean resolveResource(int type, String name);
+
+ public abstract String getUriEncoding();
}
Modified: tomcat/trunk/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/rewrite/ResolverImpl.java?rev=1759516&r1=1759515&r2=1759516&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/valves/rewrite/ResolverImpl.java Tue
Sep 6 21:26:17 2016
@@ -177,4 +177,9 @@ public class ResolverImpl extends Resolv
return value;
}
}
+
+ @Override
+ public String getUriEncoding() {
+ return request.getConnector().getURIEncoding();
+ }
}
Modified: tomcat/trunk/java/org/apache/catalina/valves/rewrite/RewriteRule.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/rewrite/RewriteRule.java?rev=1759516&r1=1759515&r2=1759516&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/rewrite/RewriteRule.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/valves/rewrite/RewriteRule.java Tue
Sep 6 21:26:17 2016
@@ -37,6 +37,8 @@ public class RewriteRule {
substitution = new Substitution();
substitution.setSub(substitutionString);
substitution.parse(maps);
+ substitution.setEscapeBackReferences(isEscapeBackReferences());
+ substitution.setNoEscape(isNoescape());
}
// Parse the pattern
int flags = 0;
@@ -151,7 +153,7 @@ public class RewriteRule {
}
- private boolean escapeBackreferences = false;
+ private boolean escapeBackReferences = false;
/**
* This flag chains the current rule with the next rule (which itself
@@ -328,11 +330,11 @@ public class RewriteRule {
protected boolean type = false;
protected String typeValue = null;
- public boolean isEscapeBackreferences() {
- return escapeBackreferences;
+ public boolean isEscapeBackReferences() {
+ return escapeBackReferences;
}
- public void setEscapeBackreferences(boolean escapeBackreferences) {
- this.escapeBackreferences = escapeBackreferences;
+ public void setEscapeBackReferences(boolean escapeBackReferences) {
+ this.escapeBackReferences = escapeBackReferences;
}
public boolean isChain() {
return chain;
Modified: tomcat/trunk/java/org/apache/catalina/valves/rewrite/RewriteValve.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/rewrite/RewriteValve.java?rev=1759516&r1=1759515&r2=1759516&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/rewrite/RewriteValve.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/valves/rewrite/RewriteValve.java Tue
Sep 6 21:26:17 2016
@@ -44,10 +44,10 @@ import org.apache.catalina.Pipeline;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
-import org.apache.catalina.util.URLEncoder;
import org.apache.catalina.valves.ValveBase;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.buf.UDecoder;
import org.apache.tomcat.util.buf.UriUtil;
import org.apache.tomcat.util.http.RequestUtil;
@@ -439,7 +439,7 @@ public class RewriteValve extends ValveB
if (context) {
chunk.append(contextPath);
}
- chunk.append(URLEncoder.DEFAULT.encode(urlString,
"UTF-8"));
+ chunk.append(urlString);
request.getCoyoteRequest().requestURI().toChars();
// Decoded and normalized URI
request.getCoyoteRequest().decodedURI().setString(null);
@@ -448,7 +448,8 @@ public class RewriteValve extends ValveB
if (context) {
chunk.append(contextPath);
}
- chunk.append(RequestUtil.normalize(urlString));
+ chunk.append(RequestUtil.normalize(UDecoder.URLDecode(
+ urlString,
request.getConnector().getURIEncoding())));
request.getCoyoteRequest().decodedURI().toChars();
// Set the new Query if there is one
if (queryString != null) {
@@ -641,7 +642,7 @@ public class RewriteValve extends ValveB
*/
protected static void parseRuleFlag(String line, RewriteRule rule, String
flag) {
if (flag.equals("B")) {
- rule.setEscapeBackreferences(true);
+ rule.setEscapeBackReferences(true);
} else if (flag.equals("chain") || flag.equals("C")) {
rule.setChain(true);
} else if (flag.startsWith("cookie=") || flag.startsWith("CO=")) {
Modified: tomcat/trunk/java/org/apache/catalina/valves/rewrite/Substitution.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/rewrite/Substitution.java?rev=1759516&r1=1759515&r2=1759516&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/rewrite/Substitution.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/valves/rewrite/Substitution.java Tue
Sep 6 21:26:17 2016
@@ -20,8 +20,25 @@ import java.util.ArrayList;
import java.util.Map;
import java.util.regex.Matcher;
+import org.apache.catalina.util.URLEncoder;
+
public class Substitution {
+ private static URLEncoder STATIC_ENCODER = new URLEncoder();
+ static {
+ // Defaults
+ STATIC_ENCODER.addSafeCharacter('~');
+ STATIC_ENCODER.addSafeCharacter('-');
+ STATIC_ENCODER.addSafeCharacter('_');
+ STATIC_ENCODER.addSafeCharacter('.');
+ STATIC_ENCODER.addSafeCharacter('*');
+ STATIC_ENCODER.addSafeCharacter('/');
+ // httpd doesn't encode these either
+ STATIC_ENCODER.addSafeCharacter('?');
+ STATIC_ENCODER.addSafeCharacter('=');
+ }
+
+
public abstract class SubstitutionElement {
public abstract String evaluate(Matcher rule, Matcher cond, Resolver
resolver);
}
@@ -31,7 +48,11 @@ public class Substitution {
@Override
public String evaluate(Matcher rule, Matcher cond, Resolver resolver) {
- return value;
+ if (noEscape) {
+ return value;
+ } else {
+ return STATIC_ENCODER.encode(value, resolver.getUriEncoding());
+ }
}
}
@@ -40,7 +61,15 @@ public class Substitution {
public int n;
@Override
public String evaluate(Matcher rule, Matcher cond, Resolver resolver) {
- return rule.group(n);
+ if (escapeBackReferences) {
+ // Note: This should be consistent with the way httpd behaves.
+ // We might want to consider providing a dedicated
decoder
+ // with an option to add additional safe characters to
+ // provide users with more flexibility
+ return URLEncoder.DEFAULT.encode(rule.group(n),
resolver.getUriEncoding());
+ } else {
+ return rule.group(n);
+ }
}
}
@@ -105,6 +134,16 @@ public class Substitution {
public String getSub() { return sub; }
public void setSub(String sub) { this.sub = sub; }
+ private boolean escapeBackReferences;
+ void setEscapeBackReferences(boolean escapeBackReferences) {
+ this.escapeBackReferences = escapeBackReferences;
+ }
+
+ private boolean noEscape;
+ void setNoEscape(boolean noEscape) {
+ this.noEscape = noEscape;
+ }
+
public void parse(Map<String, RewriteMap> maps) {
ArrayList<SubstitutionElement> elements = new ArrayList<>();
Modified:
tomcat/trunk/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java?rev=1759516&r1=1759515&r2=1759516&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
(original)
+++ tomcat/trunk/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
Tue Sep 6 21:26:17 2016
@@ -41,17 +41,17 @@ public class TestRewriteValve extends To
@Test
public void testNoopRewrite() throws Exception {
- doTestRewrite("RewriteRule ^(.*) $1", "/a/%255A", "/a/%255A");
+ doTestRewrite("RewriteRule ^(.*) $1 [B]", "/a/%255A", "/a/%255A");
}
@Test
public void testPathRewrite() throws Exception {
- doTestRewrite("RewriteRule ^/b(.*) /a$1", "/b/%255A", "/a/%255A");
+ doTestRewrite("RewriteRule ^/b(.*) /a$1 [B]", "/b/%255A", "/a/%255A");
}
@Test
public void testNonNormalizedPathRewrite() throws Exception {
- doTestRewrite("RewriteRule ^/b/(.*) /b/../a/$1", "/b/%255A",
"/b/../a/%255A");
+ doTestRewrite("RewriteRule ^/b/(.*) /b/../a/$1 [B]", "/b/%255A",
"/b/../a/%255A");
}
// BZ 57863
@@ -116,13 +116,13 @@ public class TestRewriteValve extends To
@Test
public void testNonAsciiPath() throws Exception {
- doTestRewrite("RewriteRule ^/b/(.*) /c/$1",
"/b/%E5%9C%A8%E7%BA%BF%E6%B5%8B%E8%AF%95",
+ doTestRewrite("RewriteRule ^/b/(.*) /c/$1 [B]",
"/b/%E5%9C%A8%E7%BA%BF%E6%B5%8B%E8%AF%95",
"/c/%E5%9C%A8%E7%BA%BF%E6%B5%8B%E8%AF%95");
}
@Test
public void testNonAsciiPathRedirect() throws Exception {
- doTestRewrite("RewriteRule ^/b/(.*) /c/$1 [R]",
+ doTestRewrite("RewriteRule ^/b/(.*) /c/$1 [R,B]",
"/b/%E5%9C%A8%E7%BA%BF%E6%B5%8B%E8%AF%95",
"/c/%E5%9C%A8%E7%BA%BF%E6%B5%8B%E8%AF%95");
}
@@ -134,21 +134,23 @@ public class TestRewriteValve extends To
@Test
public void testNonAsciiQueryString() throws Exception {
- doTestRewrite("RewriteRule ^/b/(.*) /c?$1",
"/b/id=%E5%9C%A8%E7%BA%BF%E6%B5%8B%E8%AF%95",
+ doTestRewrite("RewriteRule ^/b/id=(.*) /c?id=$1 [B]",
+ "/b/id=%E5%9C%A8%E7%BA%BF%E6%B5%8B%E8%AF%95",
"/c", "id=%E5%9C%A8%E7%BA%BF%E6%B5%8B%E8%AF%95");
}
@Test
public void testNonAsciiQueryStringAndPath() throws Exception {
- doTestRewrite("RewriteRule ^/b/(.*)/(.*) /c/$1?$2",
"/b/%E5%9C%A8%E7%BA%BF/id=%E6%B5%8B%E8%AF%95",
+ doTestRewrite("RewriteRule ^/b/(.*)/id=(.*) /c/$1?id=$2 [B]",
+ "/b/%E5%9C%A8%E7%BA%BF/id=%E6%B5%8B%E8%AF%95",
"/c/%E5%9C%A8%E7%BA%BF", "id=%E6%B5%8B%E8%AF%95");
}
@Test
public void testNonAsciiQueryStringRedirect() throws Exception {
- doTestRewrite("RewriteRule ^/b/(.*) /c?$1 [R]",
+ doTestRewrite("RewriteRule ^/b/id=(.*) /c?id=$1 [R,B]",
"/b/id=%E5%9C%A8%E7%BA%BF%E6%B5%8B%E8%AF%95",
"/c", "id=%E5%9C%A8%E7%BA%BF%E6%B5%8B%E8%AF%95");
}
@@ -156,7 +158,7 @@ public class TestRewriteValve extends To
@Test
public void testNonAsciiQueryStringAndRedirectPath() throws Exception {
- doTestRewrite("RewriteRule ^/b/(.*)/(.*) /c/$1?$2 [R]",
+ doTestRewrite("RewriteRule ^/b/(.*)/id=(.*) /c/$1?id=$2 [R,B]",
"/b/%E5%9C%A8%E7%BA%BF/id=%E6%B5%8B%E8%AF%95",
"/c/%E5%9C%A8%E7%BA%BF", "id=%E6%B5%8B%E8%AF%95");
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]