This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new 114054ba26 Ensure URL encoding issues trigger errors.
114054ba26 is described below
commit 114054ba2622b5a07bbacbf14178ec776c686989
Author: Mark Thomas <[email protected]>
AuthorDate: Mon Jan 19 10:08:32 2026 +0000
Ensure URL encoding issues trigger errors.
Should be a NO-OP unless someone has a Rewrite valve configuration that
is inconsistent with the Connector's URI encoding - in which case the
new IAE will highlight this.
Originated from a report from OSS-Fuzz that found some cases where a
round-trip encode/decode have the same result as the input.
---
java/org/apache/catalina/util/URLEncoder.java | 14 +++++++++---
test/org/apache/catalina/util/TestURLEncoder.java | 28 +++++++++++++++++++++++
webapps/docs/changelog.xml | 4 ++++
3 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/java/org/apache/catalina/util/URLEncoder.java
b/java/org/apache/catalina/util/URLEncoder.java
index 0e0f9737d9..1f031058f1 100644
--- a/java/org/apache/catalina/util/URLEncoder.java
+++ b/java/org/apache/catalina/util/URLEncoder.java
@@ -20,6 +20,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
+import java.nio.charset.CodingErrorAction;
import java.util.BitSet;
/**
@@ -146,7 +147,15 @@ public final class URLEncoder implements Cloneable {
int maxBytesPerChar = 10;
StringBuilder rewrittenPath = new StringBuilder(path.length());
ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar);
- OutputStreamWriter writer = new OutputStreamWriter(buf, charset);
+ /*
+ * Most calls to this method use UTF-8 where malformed input and
unmappable character issues are not expected to
+ * happen. The only Tomcat code that currently (January 2026) might
call this method with something other than
+ * UTF-8 is the rewrite valve. In that case, the rewrite rules should
be consistent with the configured URI
+ * encoding on the Connector. Given all of this, the IAE is only
expected to be thrown as a result of
+ * configuration errors.
+ */
+ OutputStreamWriter writer = new OutputStreamWriter(buf,
charset.newEncoder()
+
.onMalformedInput(CodingErrorAction.REPORT).onUnmappableCharacter(CodingErrorAction.REPORT));
for (int i = 0; i < path.length(); i++) {
int c = path.charAt(i);
@@ -160,8 +169,7 @@ public final class URLEncoder implements Cloneable {
writer.write((char) c);
writer.flush();
} catch (IOException ioe) {
- buf.reset();
- continue;
+ throw new IllegalArgumentException(ioe);
}
byte[] ba = buf.toByteArray();
for (byte toEncode : ba) {
diff --git a/test/org/apache/catalina/util/TestURLEncoder.java
b/test/org/apache/catalina/util/TestURLEncoder.java
index dbef0fb60e..47fc3ede15 100644
--- a/test/org/apache/catalina/util/TestURLEncoder.java
+++ b/test/org/apache/catalina/util/TestURLEncoder.java
@@ -16,11 +16,14 @@
*/
package org.apache.catalina.util;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.junit.Assert;
import org.junit.Test;
+import org.apache.tomcat.util.buf.UDecoder;
+
public class TestURLEncoder {
private static final String SPACE = " ";
@@ -53,4 +56,29 @@ public class TestURLEncoder {
xml.removeSafeCharacter('&');
Assert.assertEquals(AMPERSAND_ENCODED, xml.encode(AMPERSAND,
StandardCharsets.UTF_8));
}
+
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testOssFuzz01() {
+ /*
+ * Round-trip URL encoding with ASCII only works for valid ASCII
characters.
+ */
+ testRoundTrip("\uFFFD", StandardCharsets.US_ASCII);
+ }
+
+
+ @Test
+ public void testOssFuzz02() {
+ testRoundTrip("\uFFFD", StandardCharsets.UTF_8);
+ }
+
+
+ private void testRoundTrip(String input, Charset charset) {
+ URLEncoder encoder = new URLEncoder();
+
+ String encoded = encoder.encode(input, charset);
+ String decoded = UDecoder.URLDecode(encoded, charset);
+
+ Assert.assertEquals(input, decoded);
+ }
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 7d3cd847c9..d8fd5a4238 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -132,6 +132,10 @@
Authenticators that provides a per Authenticator override of the SSO
Valve <code>requireReauthentication</code> attribute. (markt)
</add>
+ <fix>
+ Ensure URL encoding errors in the Rewrite Valve trigger an exception
+ rather than silently using a replacement character. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]