Revised Charset handling and common StringUtils.uriDecode delegate
Issue: SPR-14492
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -690,6 +692,59 @@ public abstract class StringUtils {
|
||||
return cleanPath(path1).equals(cleanPath(path2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the given encoded URI component value. Based on the following rules:
|
||||
* <ul>
|
||||
* <li>Alphanumeric characters {@code "a"} through {@code "z"}, {@code "A"} through {@code "Z"},
|
||||
* and {@code "0"} through {@code "9"} stay the same.</li>
|
||||
* <li>Special characters {@code "-"}, {@code "_"}, {@code "."}, and {@code "*"} stay the same.</li>
|
||||
* <li>A sequence "{@code %<i>xy</i>}" is interpreted as a hexadecimal representation of the character.</li>
|
||||
* </ul>
|
||||
* @param source the encoded String (may be {@code null})
|
||||
* @param charset the character set
|
||||
* @return the decoded value
|
||||
* @throws IllegalArgumentException when the given source contains invalid encoded sequences
|
||||
* @since 5.0
|
||||
* @see java.net.URLDecoder#decode(String, String)
|
||||
*/
|
||||
public static String uriDecode(String source, Charset charset) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
int length = source.length();
|
||||
if (length == 0) {
|
||||
return source;
|
||||
}
|
||||
Assert.notNull(charset, "Charset must not be null");
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(length);
|
||||
boolean changed = false;
|
||||
for (int i = 0; i < length; i++) {
|
||||
int ch = source.charAt(i);
|
||||
if (ch == '%') {
|
||||
if (i + 2 < length) {
|
||||
char hex1 = source.charAt(i + 1);
|
||||
char hex2 = source.charAt(i + 2);
|
||||
int u = Character.digit(hex1, 16);
|
||||
int l = Character.digit(hex2, 16);
|
||||
if (u == -1 || l == -1) {
|
||||
throw new IllegalArgumentException("Invalid encoded sequence \"" + source.substring(i) + "\"");
|
||||
}
|
||||
bos.write((char) ((u << 4) + l));
|
||||
i += 2;
|
||||
changed = true;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid encoded sequence \"" + source.substring(i) + "\"");
|
||||
}
|
||||
}
|
||||
else {
|
||||
bos.write(ch);
|
||||
}
|
||||
}
|
||||
return (changed ? new String(bos.toByteArray(), charset) : source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given {@code localeString} value into a {@link Locale}.
|
||||
* <p>This is the inverse operation of {@link Locale#toString Locale's toString}.
|
||||
|
||||
Reference in New Issue
Block a user