Added support for plusToSpace decoding

This commit is contained in:
Geert Bevin 2023-01-06 13:58:41 -05:00
parent b8322bfe9f
commit 844db85cbe
2 changed files with 36 additions and 9 deletions

View file

@ -69,6 +69,20 @@ public final class UrlEncoder {
* @since 1.0 * @since 1.0
*/ */
public static String decode(String source) { public static String decode(String source) {
return decode(source, false);
}
/**
* Transforms a provided <code>String</code> URL into a new string,
* containing decoded URL characters in the UTF-8 encoding.
*
* @param source The string URL that has to be decoded
* @param plusToSpace Convert any {@code +} to space.
* @return The decoded <code>String</code> object.
* @see #encode(String, String)
* @since 1.0
*/
public static String decode(String source, boolean plusToSpace) {
if (source == null || source.isEmpty()) { if (source == null || source.isEmpty()) {
return source; return source;
} }
@ -83,10 +97,7 @@ public final class UrlEncoder {
ch = source.charAt(i); ch = source.charAt(i);
if (ch == '%') { if (ch == '%') {
if (out == null) { out = startConstructingIfNeeded(out, source, i);
out = new StringBuilder(length);
out.append(source, 0, i);
}
if (bytes_buffer == null) { if (bytes_buffer == null) {
// the remaining characters divided by the length // the remaining characters divided by the length
@ -119,7 +130,10 @@ public final class UrlEncoder {
bytes_pos = 0; bytes_pos = 0;
} }
if (out != null) { if (plusToSpace && ch == '+') {
out = startConstructingIfNeeded(out, source, i);
out.append(" ");
} else if (out != null) {
out.append(ch); out.append(ch);
} }
@ -138,6 +152,14 @@ public final class UrlEncoder {
return out.toString(); return out.toString();
} }
private static StringBuilder startConstructingIfNeeded(StringBuilder out, String source, int currentSourcePosition) {
if (out == null) {
out = new StringBuilder(source.length());
out.append(source, 0, currentSourcePosition);
}
return out;
}
/** /**
* Transforms a provided <code>String</code> object into a new string, * Transforms a provided <code>String</code> object into a new string,
* containing only valid URL characters in the UTF-8 encoding. * containing only valid URL characters in the UTF-8 encoding.
@ -210,10 +232,8 @@ public final class UrlEncoder {
} }
i += 1; i += 1;
} else { } else {
if (out == null) { out = startConstructingIfNeeded(out, source, i);
out = new StringBuilder(source.length());
out.append(source, 0, i);
}
var cp = source.codePointAt(i); var cp = source.codePointAt(i);
if (cp < 0x80) { if (cp < 0x80) {
if (spaceToPlus && ch == ' ') { if (spaceToPlus && ch == ' ') {

View file

@ -101,6 +101,13 @@ class UrlEncoderTest {
assertEquals("foo bar", UrlEncoder.encode("foo bar", " ", true)); assertEquals("foo bar", UrlEncoder.encode("foo bar", " ", true));
} }
@Test
void testDecodePlusToSpace() {
assertEquals("foo bar", UrlEncoder.decode("foo+bar", true));
assertEquals("foo bar foo", UrlEncoder.decode("foo+bar++foo", true));
assertEquals("foo bar foo", UrlEncoder.decode("foo+%20bar%20+foo", true));
}
@ParameterizedTest(name = "processMain(-d {1}) should be {0}") @ParameterizedTest(name = "processMain(-d {1}) should be {0}")
@MethodSource("validMap") @MethodSource("validMap")
void testMainDecode(String expected, String source) { void testMainDecode(String expected, String source) {