Skip to content

Commit

Permalink
Merge pull request #46252 from luisRubiera/fix-url-decoding-exception
Browse files Browse the repository at this point in the history
Throw IllegalArgumentException on failed URL decoding
  • Loading branch information
gsmet authored Feb 13, 2025
2 parents cda43af + ed6ec4b commit 6adbc78
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ public static String decode(String s, Charset enc, boolean decodeSlash, boolean
return s;
}

private static RuntimeException failedToDecodeURL(String s, Charset enc, Throwable o) {
return new RuntimeException("Failed to decode URL " + s + " to " + enc, o);
private static IllegalArgumentException failedToDecodeURL(String s, Charset enc, Throwable o) {
return new IllegalArgumentException("Failed to decode URL " + s + " to " + enc, o);
}

private static byte[] expandBytes(byte[] bytes) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.jboss.resteasy.reactive.common.util;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.nio.charset.StandardCharsets;

import org.junit.jupiter.api.Test;

class URLUtilsTest {
@Test
void decodeInvalidPercentEncoding() {
String incomplete = "invalid%2";
String invalidHex = "invalid%zz";

assertThrows(IllegalArgumentException.class,
() -> URLUtils.decode(incomplete, StandardCharsets.UTF_8, true, new StringBuilder()));
assertThrows(IllegalArgumentException.class,
() -> URLUtils.decode(invalidHex, StandardCharsets.UTF_8, true, new StringBuilder()));
}

@Test
void decodeGrayAreaInvalidUtf8() {
String invalidUtf8 = "invalid%80";

// This is a gray area: %80 is not valid in UTF-8 as a standalone byte,
// but Java's default decoding behavior does not throw an exception.
// Instead, it replaces it with a special character (�).
//
// To enforce strict decoding, CharsetDecoder with CodingErrorAction.REPORT
// should be used inside URLUtils.decode.
String decoded = URLUtils.decode(invalidUtf8, StandardCharsets.UTF_8, true, new StringBuilder());

assertEquals("invalid�", decoded); // Note: This may vary depending on the JVM.
}

@Test
void decodeValidValues() {
String path = "test%20path";
String formEncoded = "test+path";
String japanese = "%E3%83%86%E3%82%B9%E3%83%88"; // テスト

assertEquals("test path",
URLUtils.decode(path, StandardCharsets.UTF_8, true, new StringBuilder()));
assertEquals("test path",
URLUtils.decode(formEncoded, StandardCharsets.UTF_8, true, true, new StringBuilder()));
assertEquals("テスト",
URLUtils.decode(japanese, StandardCharsets.UTF_8, true, new StringBuilder()));
}
}

0 comments on commit 6adbc78

Please sign in to comment.