Skip to content

Commit

Permalink
* Bugfix: MatchResultSubstitution,当出现很长的变量$xxxxxxxx...时,发生溢出错误,导致<rew…
Browse files Browse the repository at this point in the history
…rite>功能出错。

* Bugfix: 在<rewrite><condition test="%{VAR}">中,避免%{VAR}中出现的$或%被解析。
  • Loading branch information
Michael Zhou committed Nov 28, 2013
1 parent df2a73f commit 8ec590c
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -404,3 +404,5 @@

-- Changes in 3.0.13

* Bugfix: MatchResultSubstitution,当出现很长的变量$xxxxxxxx...时,发生溢出错误,导致<rewrite>功能出错。
* Bugfix: 在<rewrite><condition test="%{VAR}">中,避免%{VAR}中出现的$或%被解析。
2 changes: 2 additions & 0 deletions CHANGES_SINCE_3.1.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,5 @@

-- Changes in 3.1.5

* Bugfix: MatchResultSubstitution,当出现很长的变量$xxxxxxxx...时,发生溢出错误,导致<rewrite>功能出错。
* Bugfix: 在<rewrite><condition test="%{VAR}">中,避免%{VAR}中出现的$或%被解析。
2 changes: 2 additions & 0 deletions CHANGES_SINCE_3.2.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,5 @@

-- Changes in 3.2.3

* Bugfix: MatchResultSubstitution,当出现很长的变量$xxxxxxxx...时,发生溢出错误,导致<rewrite>功能出错。
* Bugfix: 在<rewrite><condition test="%{VAR}">中,避免%{VAR}中出现的$或%被解析。
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public MatchResult getMatch(int index) {
protected String group(int index, int groupNumber) {
MatchResult result = getMatch(index);

if (groupNumber <= result.groupCount()) {
if (0 <= groupNumber && groupNumber <= result.groupCount()) {
return result.group(groupNumber);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ public void matchNormal() {
assertEquals("xxaayy$2zz", subs.substitute("xx$1yy$2zz"));
}

@Test
public void matchOverflowNumber() {
Substitution subs = new MatchResultSubstitution(r1);
// Number $12345678901234567890 exceeds the integer range, which causes a negative number
assertEquals("xx$12345678901234567890yy$2zz", subs.substitute("xx$12345678901234567890yy$2zz"));
}

@Test
public void matchMulti() {
Substitution subs = new MatchResultSubstitution("$%", r1, r2);
Expand All @@ -116,9 +123,9 @@ public void matchMulti() {
r1 = getMatchResult("\\.(\\w+)\\.com/(.*)", "www.taobao.com/test.htm");
r2 = getMatchResult("a=(\\d+)&b=(\\d+)", "a=1&b=2&c=3");

assertEquals("$1, $x, .taobao.com/test.htm, taobao, test.htm, $3, %1, %x, a=1&b=2, 1, 2, %3",
assertEquals("\\taobao, $1, $x, .taobao.com/test.htm, taobao, test.htm, $3, %1, %x, a=1&b=2, 1, 2, %3, \\",
new MatchResultSubstitution("$%", r1, r2)
.substitute("\\$1, $x, $0, $1, $2, $3, \\%1, %x, %0, %1, %2, %3"));
.substitute("\\\\$1, \\$1, $x, $0, $1, $2, $3, \\%1, %x, %0, %1, %2, %3, \\"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ protected static String eval(String expr, HttpServletRequest request) {
case '}':

String varName = varNameBuffer.toString();
String varNameExpanded = expand(varName, request);
String varNameExpanded = expandAndEscape(varName, request);

if (varNameExpanded == null) {
resultBuffer.append("%{").append(varName).append("}");
resultBuffer.append("\\%{").append(varName).append("}");
} else {
resultBuffer.append(varNameExpanded);
}
Expand All @@ -124,7 +124,7 @@ protected static String eval(String expr, HttpServletRequest request) {
break;

default:
charBuffer.append(ch);
charBuffer.append('%').append(ch);
}
} else {
charBuffer.append(ch);
Expand All @@ -146,6 +146,51 @@ protected static String eval(String expr, HttpServletRequest request) {
return resultBuffer.toString();
}

/**
* 展开变量,并对其中的特殊字符进行处理,避免其被解析。
*
* @return 注意,如果返回null,表示按原样显示,例如:%{XYZ}
*/
private static String expandAndEscape(String varName, HttpServletRequest request) {
String value = expand(varName, request);

if (value != null) {
int length = value.length();
StringBuilder buf = new StringBuilder(length + 10);
boolean changed = false;

for (int i = 0; i < length; i++) {
char ch = value.charAt(i);

switch (ch) {
case '\\':
buf.append("\\\\");
changed = true;
break;

case '$':
buf.append("\\$");
changed = true;
break;

case '%':
buf.append("\\%");
changed = true;
break;

default:
buf.append(ch);
}
}

if (changed) {
value = buf.toString();
}
}

return value;
}

/**
* 展开变量。
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,11 @@ public static void initFactory() {

@Test
public void _eval() throws Exception {
invokeNoopServlet("/servlet/hello.htm?a=1&b=2&c=3");
invokeNoopServlet("/servlet/hello.htm?a=1&b=2&c=3&e=%5C$12%2534");
initRequestContext();

HttpServletRequest wrappedRequest = requestContext.getWrappedRequestContext().getRequest();

assertEquals("", eval("", wrappedRequest));
assertEquals("%{}", eval("%{}", wrappedRequest));

// =====================================================
// Client side of the IP connection
// =====================================================
Expand All @@ -51,7 +48,7 @@ public void _eval() throws Exception {
assertEquals("127.0.0.1", eval("%{REMOTE_ADDR}", wrappedRequest));
assertEquals("", eval("%{REMOTE_USER}", wrappedRequest));
assertEquals("GET", eval("%{REQUEST_METHOD}", wrappedRequest));
assertEquals("a=1&b=2&c=3", eval("%{QUERY_STRING}", wrappedRequest));
assertEquals("a=1&b=2&c=3&e=\\%5C\\$12\\%2534", eval("%{QUERY_STRING}", wrappedRequest));
assertEquals("1", eval("%{QUERY:a}", wrappedRequest));
assertEquals("2", eval("%{QUERY:b}", wrappedRequest));
assertEquals("", eval("%{QUERY:d}", wrappedRequest));
Expand Down Expand Up @@ -80,5 +77,16 @@ public void _eval() throws Exception {
// =====================================================

assertEquals("/servlet/hello.htm", eval("%{REQUEST_URI}", wrappedRequest));

// =====================================================
// Special cases
// =====================================================
assertEquals("", eval("", wrappedRequest));
assertEquals("\\%{}", eval("%{}", wrappedRequest));
assertEquals("%{", eval("%{", wrappedRequest));
assertEquals("\\%{} %", eval("%{} %", wrappedRequest));

assertEquals("\\%{INVALID} %{HTTP_HOST} %1 %{INCOMPLETED", eval("%{INVALID} %%{HTTP_HOST} %1 %{INCOMPLETED", wrappedRequest));
assertEquals("$1 \\\\\\$12\\%34 %2", eval("$1 %{QUERY:e} %2", wrappedRequest));
}
}

0 comments on commit 8ec590c

Please sign in to comment.