Skip to content

Commit

Permalink
Fix URI parsing with encodedSolidusHandling="passthrough"
Browse files Browse the repository at this point in the history
Based on a pull request by willmeck.
  • Loading branch information
markt-asf committed Oct 9, 2020
1 parent dda893d commit 791ef21
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 1 deletion.
4 changes: 3 additions & 1 deletion java/org/apache/tomcat/util/buf/UDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ private void convert(ByteChunk mb, boolean query, EncodedSolidusHandling encoded
throw EXCEPTION_SLASH;
}
case PASS_THROUGH: {
idx += 2;
buff[idx++] = buff[j-2];
buff[idx++] = buff[j-1];
buff[idx] = buff[j];
}
}
} else {
Expand Down
147 changes: 147 additions & 0 deletions test/org/apache/tomcat/util/buf/TestUDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.apache.tomcat.util.buf;

import java.io.CharConversionException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

import org.junit.Assert;
Expand Down Expand Up @@ -99,4 +101,149 @@ public void testURLDecodeStringNonAsciiValidUtf8() {
String result = UDecoder.URLDecode("\u00ea%c3%aa", StandardCharsets.UTF_8);
Assert.assertEquals("\u00ea\u00ea", result);
}


@Test
public void testURLDecodeStringSolidus01() throws IOException {
doTestSolidus("xxxxxx", "xxxxxx");
}


@Test
public void testURLDecodeStringSolidus02() throws IOException {
doTestSolidus("%20xxxx", " xxxx");
}


@Test
public void testURLDecodeStringSolidus03() throws IOException {
doTestSolidus("xx%20xx", "xx xx");
}


@Test
public void testURLDecodeStringSolidus04() throws IOException {
doTestSolidus("xxxx%20", "xxxx ");
}


@Test(expected = CharConversionException.class)
public void testURLDecodeStringSolidus05a() throws IOException {
doTestSolidus("%2fxxxx", EncodedSolidusHandling.REJECT);
}


@Test
public void testURLDecodeStringSolidus05b() throws IOException {
String result = doTestSolidus("%2fxxxx", EncodedSolidusHandling.PASS_THROUGH);
Assert.assertEquals("%2fxxxx", result);
}


@Test
public void testURLDecodeStringSolidus05c() throws IOException {
String result = doTestSolidus("%2fxxxx", EncodedSolidusHandling.DECODE);
Assert.assertEquals("/xxxx", result);
}


@Test(expected = CharConversionException.class)
public void testURLDecodeStringSolidus06a() throws IOException {
doTestSolidus("%2fxx%20xx", EncodedSolidusHandling.REJECT);
}


@Test
public void testURLDecodeStringSolidus06b() throws IOException {
String result = doTestSolidus("%2fxx%20xx", EncodedSolidusHandling.PASS_THROUGH);
Assert.assertEquals("%2fxx xx", result);
}


@Test
public void testURLDecodeStringSolidus06c() throws IOException {
String result = doTestSolidus("%2fxx%20xx", EncodedSolidusHandling.DECODE);
Assert.assertEquals("/xx xx", result);
}


@Test(expected = CharConversionException.class)
public void testURLDecodeStringSolidus07a() throws IOException {
doTestSolidus("xx%2f%20xx", EncodedSolidusHandling.REJECT);
}


@Test
public void testURLDecodeStringSolidus07b() throws IOException {
String result = doTestSolidus("xx%2f%20xx", EncodedSolidusHandling.PASS_THROUGH);
Assert.assertEquals("xx%2f xx", result);
}


@Test
public void testURLDecodeStringSolidus07c() throws IOException {
String result = doTestSolidus("xx%2f%20xx", EncodedSolidusHandling.DECODE);
Assert.assertEquals("xx/ xx", result);
}


@Test(expected = CharConversionException.class)
public void testURLDecodeStringSolidus08a() throws IOException {
doTestSolidus("xx%20%2fxx", EncodedSolidusHandling.REJECT);
}


@Test
public void testURLDecodeStringSolidus08b() throws IOException {
String result = doTestSolidus("xx%20%2fxx", EncodedSolidusHandling.PASS_THROUGH);
Assert.assertEquals("xx %2fxx", result);
}


@Test
public void testURLDecodeStringSolidus08c() throws IOException {
String result = doTestSolidus("xx%20%2fxx", EncodedSolidusHandling.DECODE);
Assert.assertEquals("xx /xx", result);
}


@Test(expected = CharConversionException.class)
public void testURLDecodeStringSolidus09a() throws IOException {
doTestSolidus("xx%20xx%2f", EncodedSolidusHandling.REJECT);
}


@Test
public void testURLDecodeStringSolidus09b() throws IOException {
String result = doTestSolidus("xx%20xx%2f", EncodedSolidusHandling.PASS_THROUGH);
Assert.assertEquals("xx xx%2f", result);
}


@Test
public void testURLDecodeStringSolidus09c() throws IOException {
String result = doTestSolidus("xx%20xx%2f", EncodedSolidusHandling.DECODE);
Assert.assertEquals("xx xx/", result);
}


private void doTestSolidus(String input, String expected) throws IOException {
for (EncodedSolidusHandling solidusHandling : EncodedSolidusHandling.values()) {
String result = doTestSolidus(input, solidusHandling);
Assert.assertEquals(expected, result);
}
}


private String doTestSolidus(String input, EncodedSolidusHandling solidusHandling) throws IOException {
byte[] b = input.getBytes(StandardCharsets.UTF_8);
ByteChunk bc = new ByteChunk(16);
bc.setBytes(b, 0, b.length);
bc.setCharset(StandardCharsets.UTF_8);

UDecoder udecoder = new UDecoder();
udecoder.convert(bc, solidusHandling);

return bc.toString();
}
}
6 changes: 6 additions & 0 deletions webapps/docs/changelog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@
ensure that the connection window is correctly updated after a data
frame with zero length padding is received. (markt)
</fix>
<fix>
Fix processing of URIs with %nn encoded solidus characters when
<code>encodedSolidusHandling</code> was set to <code>passthrough</code>
and the encoded solidus was preceeded by other %nn encoded characters.
Based on a pull request by willmeck. (markt)
</fix>
</changelog>
</subseciton>
<subsection name="Jasper">
Expand Down

0 comments on commit 791ef21

Please sign in to comment.