* Issue #5093 Static UrlEncoded Updated UrlEncoded to static only class with no synchronization * Fixed additional tests * fixed formatting Signed-off-by: gregw <gregw@webtide.com>
This commit is contained in:
parent
aa3bd243b4
commit
7adbf247ec
|
@ -57,6 +57,7 @@ import org.eclipse.jetty.server.handler.ContextHandler;
|
|||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.UrlEncoded;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
@ -834,14 +835,14 @@ public class DispatcherTest
|
|||
assertEquals(null, request.getPathInfo());
|
||||
assertEquals(null, request.getPathTranslated());
|
||||
|
||||
UrlEncoded query = new UrlEncoded();
|
||||
query.decode(request.getQueryString());
|
||||
MultiMap<String> query = new MultiMap<>();
|
||||
UrlEncoded.decodeTo(request.getQueryString(), query, UrlEncoded.ENCODING);
|
||||
assertThat(query.getString("do"), is("end"));
|
||||
|
||||
// Russian for "selected=Temperature"
|
||||
UrlEncoded q2 = new UrlEncoded();
|
||||
q2.decode(query.getString("else"));
|
||||
String russian = q2.encode();
|
||||
MultiMap<String> q2 = new MultiMap<>();
|
||||
UrlEncoded.decodeTo(query.getString("else"), q2, UrlEncoded.ENCODING);
|
||||
String russian = UrlEncoded.encode(q2, UrlEncoded.ENCODING, false);
|
||||
assertThat(russian, is("%D0%B2%D1%8B%D0%B1%D1%80%D0%B0%D0%BD%D0%BE=%D0%A2%D0%B5%D0%BC%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D1%83%D1%80%D0%B0"));
|
||||
assertThat(query.containsKey("test"), is(false));
|
||||
assertThat(query.containsKey("foreign"), is(false));
|
||||
|
|
|
@ -44,19 +44,11 @@ import static org.eclipse.jetty.util.TypeUtil.convertHexDigit;
|
|||
* passing a parameter or setting the "org.eclipse.jetty.util.UrlEncoding.charset"
|
||||
* System property.
|
||||
* </p>
|
||||
* <p>
|
||||
* The hashtable either contains String single values, vectors
|
||||
* of String or arrays of Strings.
|
||||
* </p>
|
||||
* <p>
|
||||
* This class is only partially synchronised. In particular, simple
|
||||
* get operations are not protected from concurrent updates.
|
||||
* </p>
|
||||
*
|
||||
* @see java.net.URLEncoder
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class UrlEncoded extends MultiMap<String> implements Cloneable
|
||||
public class UrlEncoded
|
||||
{
|
||||
static final Logger LOG = LoggerFactory.getLogger(UrlEncoded.class);
|
||||
|
||||
|
@ -87,62 +79,8 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
ENCODING = encoding;
|
||||
}
|
||||
|
||||
public UrlEncoded(UrlEncoded url)
|
||||
private UrlEncoded()
|
||||
{
|
||||
super(url);
|
||||
}
|
||||
|
||||
public UrlEncoded()
|
||||
{
|
||||
}
|
||||
|
||||
public UrlEncoded(String query)
|
||||
{
|
||||
decodeTo(query, this, ENCODING);
|
||||
}
|
||||
|
||||
public void decode(String query)
|
||||
{
|
||||
decodeTo(query, this, ENCODING);
|
||||
}
|
||||
|
||||
public void decode(String query, Charset charset)
|
||||
{
|
||||
decodeTo(query, this, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode MultiMap with % encoding for UTF8 sequences.
|
||||
*
|
||||
* @return the MultiMap as a string with % encoding
|
||||
*/
|
||||
public String encode()
|
||||
{
|
||||
return encode(ENCODING, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode MultiMap with % encoding for arbitrary Charset sequences.
|
||||
*
|
||||
* @param charset the charset to use for encoding
|
||||
* @return the MultiMap as a string encoded with % encodings
|
||||
*/
|
||||
public String encode(Charset charset)
|
||||
{
|
||||
return encode(charset, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode MultiMap with % encoding.
|
||||
*
|
||||
* @param charset the charset to encode with
|
||||
* @param equalsForNullValue if True, then an '=' is always used, even
|
||||
* for parameters without a value. e.g. <code>"blah?a=&b=&c="</code>.
|
||||
* @return the MultiMap as a string encoded with % encodings
|
||||
*/
|
||||
public synchronized String encode(Charset charset, boolean equalsForNullValue)
|
||||
{
|
||||
return encode(this, charset, equalsForNullValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,11 +128,10 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
|
||||
if (val != null)
|
||||
{
|
||||
String str = val;
|
||||
if (str.length() > 0)
|
||||
if (val.length() > 0)
|
||||
{
|
||||
result.append('=');
|
||||
result.append(encodeString(str, charset));
|
||||
result.append(encodeString(val, charset));
|
||||
}
|
||||
else if (equalsForNullValue)
|
||||
result.append('=');
|
||||
|
@ -228,6 +165,18 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
* @param charset the charset to use for decoding
|
||||
*/
|
||||
public static void decodeTo(String content, MultiMap<String> map, Charset charset)
|
||||
{
|
||||
decodeTo(content, map, charset, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decoded parameters to Map.
|
||||
*
|
||||
* @param content the string containing the encoded parameters
|
||||
* @param map the MultiMap to put parsed query parameters into
|
||||
* @param charset the charset to use for decoding
|
||||
*/
|
||||
public static void decodeTo(String content, MultiMap<String> map, Charset charset, int maxKeys)
|
||||
{
|
||||
if (charset == null)
|
||||
charset = ENCODING;
|
||||
|
@ -238,64 +187,62 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
return;
|
||||
}
|
||||
|
||||
synchronized (map)
|
||||
String key = null;
|
||||
String value;
|
||||
int mark = -1;
|
||||
boolean encoded = false;
|
||||
for (int i = 0; i < content.length(); i++)
|
||||
{
|
||||
String key = null;
|
||||
String value;
|
||||
int mark = -1;
|
||||
boolean encoded = false;
|
||||
for (int i = 0; i < content.length(); i++)
|
||||
char c = content.charAt(i);
|
||||
switch (c)
|
||||
{
|
||||
char c = content.charAt(i);
|
||||
switch (c)
|
||||
{
|
||||
case '&':
|
||||
int l = i - mark - 1;
|
||||
value = l == 0 ? "" : (encoded ? decodeString(content, mark + 1, l, charset) : content.substring(mark + 1, i));
|
||||
mark = i;
|
||||
encoded = false;
|
||||
if (key != null)
|
||||
{
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (value != null && value.length() > 0)
|
||||
{
|
||||
map.add(value, "");
|
||||
}
|
||||
key = null;
|
||||
value = null;
|
||||
case '&':
|
||||
int l = i - mark - 1;
|
||||
value = l == 0 ? "" : (encoded ? decodeString(content, mark + 1, l, charset) : content.substring(mark + 1, i));
|
||||
mark = i;
|
||||
encoded = false;
|
||||
if (key != null)
|
||||
{
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (value != null && value.length() > 0)
|
||||
{
|
||||
map.add(value, "");
|
||||
}
|
||||
checkMaxKeys(map, maxKeys);
|
||||
key = null;
|
||||
value = null;
|
||||
break;
|
||||
case '=':
|
||||
if (key != null)
|
||||
break;
|
||||
case '=':
|
||||
if (key != null)
|
||||
break;
|
||||
key = encoded ? decodeString(content, mark + 1, i - mark - 1, charset) : content.substring(mark + 1, i);
|
||||
mark = i;
|
||||
encoded = false;
|
||||
break;
|
||||
case '+':
|
||||
encoded = true;
|
||||
break;
|
||||
case '%':
|
||||
encoded = true;
|
||||
break;
|
||||
}
|
||||
key = encoded ? decodeString(content, mark + 1, i - mark - 1, charset) : content.substring(mark + 1, i);
|
||||
mark = i;
|
||||
encoded = false;
|
||||
break;
|
||||
case '+':
|
||||
case '%':
|
||||
encoded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (key != null)
|
||||
if (key != null)
|
||||
{
|
||||
int l = content.length() - mark - 1;
|
||||
value = l == 0 ? "" : (encoded ? decodeString(content, mark + 1, l, charset) : content.substring(mark + 1));
|
||||
map.add(key, value);
|
||||
checkMaxKeys(map, maxKeys);
|
||||
}
|
||||
else if (mark < content.length())
|
||||
{
|
||||
key = encoded
|
||||
? decodeString(content, mark + 1, content.length() - mark - 1, charset)
|
||||
: content.substring(mark + 1);
|
||||
if (key != null && key.length() > 0)
|
||||
{
|
||||
int l = content.length() - mark - 1;
|
||||
value = l == 0 ? "" : (encoded ? decodeString(content, mark + 1, l, charset) : content.substring(mark + 1));
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (mark < content.length())
|
||||
{
|
||||
key = encoded
|
||||
? decodeString(content, mark + 1, content.length() - mark - 1, charset)
|
||||
: content.substring(mark + 1);
|
||||
if (key != null && key.length() > 0)
|
||||
{
|
||||
map.add(key, "");
|
||||
}
|
||||
map.add(key, "");
|
||||
checkMaxKeys(map, maxKeys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -316,76 +263,73 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
public static void decodeUtf8To(String query, int offset, int length, MultiMap<String> map)
|
||||
{
|
||||
Utf8StringBuilder buffer = new Utf8StringBuilder();
|
||||
synchronized (map)
|
||||
String key = null;
|
||||
String value;
|
||||
|
||||
int end = offset + length;
|
||||
for (int i = offset; i < end; i++)
|
||||
{
|
||||
String key = null;
|
||||
String value = null;
|
||||
|
||||
int end = offset + length;
|
||||
for (int i = offset; i < end; i++)
|
||||
char c = query.charAt(i);
|
||||
switch (c)
|
||||
{
|
||||
char c = query.charAt(i);
|
||||
switch (c)
|
||||
{
|
||||
case '&':
|
||||
value = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
if (key != null)
|
||||
{
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (value != null && value.length() > 0)
|
||||
{
|
||||
map.add(value, "");
|
||||
}
|
||||
key = null;
|
||||
value = null;
|
||||
break;
|
||||
case '&':
|
||||
value = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
if (key != null)
|
||||
{
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (value != null && value.length() > 0)
|
||||
{
|
||||
map.add(value, "");
|
||||
}
|
||||
key = null;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
if (key != null)
|
||||
{
|
||||
buffer.append(c);
|
||||
break;
|
||||
}
|
||||
key = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
break;
|
||||
|
||||
case '+':
|
||||
buffer.append((byte)' ');
|
||||
break;
|
||||
|
||||
case '%':
|
||||
if (i + 2 < end)
|
||||
{
|
||||
char hi = query.charAt(++i);
|
||||
char lo = query.charAt(++i);
|
||||
buffer.append(decodeHexByte(hi, lo));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Utf8Appendable.NotUtf8Exception("Incomplete % encoding");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case '=':
|
||||
if (key != null)
|
||||
{
|
||||
buffer.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
key = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
break;
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
value = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (buffer.length() > 0)
|
||||
{
|
||||
map.add(buffer.toReplacedString(), "");
|
||||
case '+':
|
||||
buffer.append((byte)' ');
|
||||
break;
|
||||
|
||||
case '%':
|
||||
if (i + 2 < end)
|
||||
{
|
||||
char hi = query.charAt(++i);
|
||||
char lo = query.charAt(++i);
|
||||
buffer.append(decodeHexByte(hi, lo));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Utf8Appendable.NotUtf8Exception("Incomplete % encoding");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
buffer.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
value = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (buffer.length() > 0)
|
||||
{
|
||||
map.add(buffer.toReplacedString(), "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -400,74 +344,70 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
public static void decode88591To(InputStream in, MultiMap<String> map, int maxLength, int maxKeys)
|
||||
throws IOException
|
||||
{
|
||||
synchronized (map)
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
String key = null;
|
||||
String value;
|
||||
|
||||
int b;
|
||||
|
||||
int totalLength = 0;
|
||||
while ((b = in.read()) >= 0)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
String key = null;
|
||||
String value = null;
|
||||
|
||||
int b;
|
||||
|
||||
int totalLength = 0;
|
||||
while ((b = in.read()) >= 0)
|
||||
switch ((char)b)
|
||||
{
|
||||
switch ((char)b)
|
||||
{
|
||||
case '&':
|
||||
value = buffer.length() == 0 ? "" : buffer.toString();
|
||||
buffer.setLength(0);
|
||||
if (key != null)
|
||||
{
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (value.length() > 0)
|
||||
{
|
||||
map.add(value, "");
|
||||
}
|
||||
key = null;
|
||||
value = null;
|
||||
checkMaxKeys(map, maxKeys);
|
||||
break;
|
||||
case '&':
|
||||
value = buffer.length() == 0 ? "" : buffer.toString();
|
||||
buffer.setLength(0);
|
||||
if (key != null)
|
||||
{
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (value.length() > 0)
|
||||
{
|
||||
map.add(value, "");
|
||||
}
|
||||
key = null;
|
||||
checkMaxKeys(map, maxKeys);
|
||||
break;
|
||||
|
||||
case '=':
|
||||
if (key != null)
|
||||
{
|
||||
buffer.append((char)b);
|
||||
break;
|
||||
}
|
||||
key = buffer.toString();
|
||||
buffer.setLength(0);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
buffer.append(' ');
|
||||
break;
|
||||
|
||||
case '%':
|
||||
int code0 = in.read();
|
||||
int code1 = in.read();
|
||||
buffer.append(decodeHexChar(code0, code1));
|
||||
break;
|
||||
|
||||
default:
|
||||
case '=':
|
||||
if (key != null)
|
||||
{
|
||||
buffer.append((char)b);
|
||||
break;
|
||||
}
|
||||
checkMaxLength(++totalLength, maxLength);
|
||||
}
|
||||
}
|
||||
key = buffer.toString();
|
||||
buffer.setLength(0);
|
||||
break;
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
value = buffer.length() == 0 ? "" : buffer.toString();
|
||||
buffer.setLength(0);
|
||||
map.add(key, value);
|
||||
case '+':
|
||||
buffer.append(' ');
|
||||
break;
|
||||
|
||||
case '%':
|
||||
int code0 = in.read();
|
||||
int code1 = in.read();
|
||||
buffer.append(decodeHexChar(code0, code1));
|
||||
break;
|
||||
|
||||
default:
|
||||
buffer.append((char)b);
|
||||
break;
|
||||
}
|
||||
else if (buffer.length() > 0)
|
||||
{
|
||||
map.add(buffer.toString(), "");
|
||||
}
|
||||
checkMaxKeys(map, maxKeys);
|
||||
checkMaxLength(++totalLength, maxLength);
|
||||
}
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
value = buffer.length() == 0 ? "" : buffer.toString();
|
||||
buffer.setLength(0);
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (buffer.length() > 0)
|
||||
{
|
||||
map.add(buffer.toString(), "");
|
||||
}
|
||||
checkMaxKeys(map, maxKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -482,74 +422,70 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
public static void decodeUtf8To(InputStream in, MultiMap<String> map, int maxLength, int maxKeys)
|
||||
throws IOException
|
||||
{
|
||||
synchronized (map)
|
||||
Utf8StringBuilder buffer = new Utf8StringBuilder();
|
||||
String key = null;
|
||||
String value;
|
||||
|
||||
int b;
|
||||
|
||||
int totalLength = 0;
|
||||
while ((b = in.read()) >= 0)
|
||||
{
|
||||
Utf8StringBuilder buffer = new Utf8StringBuilder();
|
||||
String key = null;
|
||||
String value = null;
|
||||
|
||||
int b;
|
||||
|
||||
int totalLength = 0;
|
||||
while ((b = in.read()) >= 0)
|
||||
switch ((char)b)
|
||||
{
|
||||
switch ((char)b)
|
||||
{
|
||||
case '&':
|
||||
value = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
if (key != null)
|
||||
{
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (value != null && value.length() > 0)
|
||||
{
|
||||
map.add(value, "");
|
||||
}
|
||||
key = null;
|
||||
value = null;
|
||||
checkMaxKeys(map, maxKeys);
|
||||
break;
|
||||
case '&':
|
||||
value = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
if (key != null)
|
||||
{
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (value != null && value.length() > 0)
|
||||
{
|
||||
map.add(value, "");
|
||||
}
|
||||
key = null;
|
||||
checkMaxKeys(map, maxKeys);
|
||||
break;
|
||||
|
||||
case '=':
|
||||
if (key != null)
|
||||
{
|
||||
buffer.append((byte)b);
|
||||
break;
|
||||
}
|
||||
key = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
break;
|
||||
|
||||
case '+':
|
||||
buffer.append((byte)' ');
|
||||
break;
|
||||
|
||||
case '%':
|
||||
char code0 = (char)in.read();
|
||||
char code1 = (char)in.read();
|
||||
buffer.append(decodeHexByte(code0, code1));
|
||||
break;
|
||||
|
||||
default:
|
||||
case '=':
|
||||
if (key != null)
|
||||
{
|
||||
buffer.append((byte)b);
|
||||
break;
|
||||
}
|
||||
checkMaxLength(++totalLength, maxLength);
|
||||
}
|
||||
}
|
||||
key = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
break;
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
value = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
map.add(key, value);
|
||||
case '+':
|
||||
buffer.append((byte)' ');
|
||||
break;
|
||||
|
||||
case '%':
|
||||
char code0 = (char)in.read();
|
||||
char code1 = (char)in.read();
|
||||
buffer.append(decodeHexByte(code0, code1));
|
||||
break;
|
||||
|
||||
default:
|
||||
buffer.append((byte)b);
|
||||
break;
|
||||
}
|
||||
else if (buffer.length() > 0)
|
||||
{
|
||||
map.add(buffer.toReplacedString(), "");
|
||||
}
|
||||
checkMaxKeys(map, maxKeys);
|
||||
checkMaxLength(++totalLength, maxLength);
|
||||
}
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
value = buffer.toReplacedString();
|
||||
buffer.reset();
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (buffer.length() > 0)
|
||||
{
|
||||
map.add(buffer.toReplacedString(), "");
|
||||
}
|
||||
checkMaxKeys(map, maxKeys);
|
||||
}
|
||||
|
||||
public static void decodeUtf16To(InputStream in, MultiMap<String> map, int maxLength, int maxKeys) throws IOException
|
||||
|
@ -558,8 +494,7 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
StringWriter buf = new StringWriter(8192);
|
||||
IO.copy(input, buf, maxLength);
|
||||
|
||||
// TODO implement maxKeys
|
||||
decodeTo(buf.getBuffer().toString(), map, StandardCharsets.UTF_16);
|
||||
decodeTo(buf.getBuffer().toString(), map, StandardCharsets.UTF_16, maxKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -627,77 +562,73 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
return;
|
||||
}
|
||||
|
||||
synchronized (map)
|
||||
String key = null;
|
||||
String value;
|
||||
|
||||
int c;
|
||||
|
||||
int totalLength = 0;
|
||||
|
||||
try (ByteArrayOutputStream2 output = new ByteArrayOutputStream2())
|
||||
{
|
||||
String key = null;
|
||||
String value = null;
|
||||
int size;
|
||||
|
||||
int c;
|
||||
|
||||
int totalLength = 0;
|
||||
|
||||
try (ByteArrayOutputStream2 output = new ByteArrayOutputStream2())
|
||||
while ((c = in.read()) > 0)
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
while ((c = in.read()) > 0)
|
||||
switch ((char)c)
|
||||
{
|
||||
switch ((char)c)
|
||||
{
|
||||
case '&':
|
||||
size = output.size();
|
||||
value = size == 0 ? "" : output.toString(charset);
|
||||
output.setCount(0);
|
||||
if (key != null)
|
||||
{
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (value != null && value.length() > 0)
|
||||
{
|
||||
map.add(value, "");
|
||||
}
|
||||
key = null;
|
||||
value = null;
|
||||
checkMaxKeys(map, maxKeys);
|
||||
break;
|
||||
case '=':
|
||||
if (key != null)
|
||||
{
|
||||
output.write(c);
|
||||
break;
|
||||
}
|
||||
size = output.size();
|
||||
key = size == 0 ? "" : output.toString(charset);
|
||||
output.setCount(0);
|
||||
break;
|
||||
case '+':
|
||||
output.write(' ');
|
||||
break;
|
||||
case '%':
|
||||
int code0 = in.read();
|
||||
int code1 = in.read();
|
||||
output.write(decodeHexChar(code0, code1));
|
||||
break;
|
||||
default:
|
||||
case '&':
|
||||
size = output.size();
|
||||
value = size == 0 ? "" : output.toString(charset);
|
||||
output.setCount(0);
|
||||
if (key != null)
|
||||
{
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (value != null && value.length() > 0)
|
||||
{
|
||||
map.add(value, "");
|
||||
}
|
||||
key = null;
|
||||
checkMaxKeys(map, maxKeys);
|
||||
break;
|
||||
case '=':
|
||||
if (key != null)
|
||||
{
|
||||
output.write(c);
|
||||
break;
|
||||
}
|
||||
checkMaxLength(++totalLength, maxLength);
|
||||
}
|
||||
size = output.size();
|
||||
key = size == 0 ? "" : output.toString(charset);
|
||||
output.setCount(0);
|
||||
break;
|
||||
case '+':
|
||||
output.write(' ');
|
||||
break;
|
||||
case '%':
|
||||
int code0 = in.read();
|
||||
int code1 = in.read();
|
||||
output.write(decodeHexChar(code0, code1));
|
||||
break;
|
||||
default:
|
||||
output.write(c);
|
||||
break;
|
||||
}
|
||||
|
||||
size = output.size();
|
||||
if (key != null)
|
||||
{
|
||||
value = size == 0 ? "" : output.toString(charset);
|
||||
output.setCount(0);
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (size > 0)
|
||||
{
|
||||
map.add(output.toString(charset), "");
|
||||
}
|
||||
checkMaxKeys(map, maxKeys);
|
||||
checkMaxLength(++totalLength, maxLength);
|
||||
}
|
||||
|
||||
size = output.size();
|
||||
if (key != null)
|
||||
{
|
||||
value = size == 0 ? "" : output.toString(charset);
|
||||
output.setCount(0);
|
||||
map.add(key, value);
|
||||
}
|
||||
else if (size > 0)
|
||||
{
|
||||
map.add(output.toString(charset), "");
|
||||
}
|
||||
checkMaxKeys(map, maxKeys);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -747,7 +678,7 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
char c = encoded.charAt(offset + i);
|
||||
if (c < 0 || c > 0xff)
|
||||
if (c > 0xff)
|
||||
{
|
||||
if (buffer == null)
|
||||
{
|
||||
|
@ -808,7 +739,7 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
char c = encoded.charAt(offset + i);
|
||||
if (c < 0 || c > 0xff)
|
||||
if (c > 0xff)
|
||||
{
|
||||
if (buffer == null)
|
||||
{
|
||||
|
@ -838,7 +769,7 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
|
||||
byte[] ba = new byte[length];
|
||||
int n = 0;
|
||||
while (c >= 0 && c <= 0xff)
|
||||
while (c <= 0xff)
|
||||
{
|
||||
if (c == '%')
|
||||
{
|
||||
|
@ -935,18 +866,15 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
{
|
||||
if (charset == null)
|
||||
charset = ENCODING;
|
||||
byte[] bytes = null;
|
||||
byte[] bytes;
|
||||
bytes = string.getBytes(charset);
|
||||
|
||||
int len = bytes.length;
|
||||
byte[] encoded = new byte[bytes.length * 3];
|
||||
int n = 0;
|
||||
boolean noEncode = true;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
for (byte b : bytes)
|
||||
{
|
||||
byte b = bytes[i];
|
||||
|
||||
if (b == ' ')
|
||||
{
|
||||
noEncode = false;
|
||||
|
@ -981,10 +909,4 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
|
||||
return new String(encoded, 0, n, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone()
|
||||
{
|
||||
return new UrlEncoded(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,15 +24,21 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
|
||||
|
||||
|
@ -49,97 +55,97 @@ public class URLEncodedTest
|
|||
|
||||
tests.add(dynamicTest("Initially not empty", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
assertEquals(0, urlEncoded.size());
|
||||
}));
|
||||
|
||||
tests.add(dynamicTest("Not empty after decode(\"\")", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("");
|
||||
UrlEncoded.decodeTo("", urlEncoded, UrlEncoded.ENCODING);
|
||||
assertEquals(0, urlEncoded.size());
|
||||
}));
|
||||
|
||||
tests.add(dynamicTest("Simple encode", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("Name1=Value1");
|
||||
UrlEncoded.decodeTo("Name1=Value1", urlEncoded, UrlEncoded.ENCODING);
|
||||
assertEquals(1, urlEncoded.size(), "simple param size");
|
||||
assertEquals("Name1=Value1", urlEncoded.encode(), "simple encode");
|
||||
assertEquals("Name1=Value1", UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false), "simple encode");
|
||||
assertEquals("Value1", urlEncoded.getString("Name1"), "simple get");
|
||||
}));
|
||||
|
||||
tests.add(dynamicTest("Dangling param", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("Name2=");
|
||||
UrlEncoded.decodeTo("Name2=", urlEncoded, UrlEncoded.ENCODING);
|
||||
assertEquals(1, urlEncoded.size(), "dangling param size");
|
||||
assertEquals("Name2", urlEncoded.encode(), "dangling encode");
|
||||
assertEquals("Name2", UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false), "dangling encode");
|
||||
assertEquals("", urlEncoded.getString("Name2"), "dangling get");
|
||||
}));
|
||||
|
||||
tests.add(dynamicTest("noValue param", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("Name3");
|
||||
UrlEncoded.decodeTo("Name3", urlEncoded, UrlEncoded.ENCODING);
|
||||
assertEquals(1, urlEncoded.size(), "noValue param size");
|
||||
assertEquals("Name3", urlEncoded.encode(), "noValue encode");
|
||||
assertEquals("Name3", UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false), "noValue encode");
|
||||
assertEquals("", urlEncoded.getString("Name3"), "noValue get");
|
||||
}));
|
||||
|
||||
tests.add(dynamicTest("badly encoded param", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("Name4=V\u0629lue+4%21");
|
||||
UrlEncoded.decodeTo("Name4=V\u0629lue+4%21", urlEncoded, UrlEncoded.ENCODING);
|
||||
assertEquals(1, urlEncoded.size(), "encoded param size");
|
||||
assertEquals("Name4=V%D8%A9lue+4%21", urlEncoded.encode(), "encoded encode");
|
||||
assertEquals("Name4=V%D8%A9lue+4%21", UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false), "encoded encode");
|
||||
assertEquals("V\u0629lue 4!", urlEncoded.getString("Name4"), "encoded get");
|
||||
}));
|
||||
|
||||
tests.add(dynamicTest("encoded param 1", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("Name4=Value%2B4%21");
|
||||
UrlEncoded.decodeTo("Name4=Value%2B4%21", urlEncoded, UrlEncoded.ENCODING);
|
||||
assertEquals(1, urlEncoded.size(), "encoded param size");
|
||||
assertEquals("Name4=Value%2B4%21", urlEncoded.encode(), "encoded encode");
|
||||
assertEquals("Name4=Value%2B4%21", UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false), "encoded encode");
|
||||
assertEquals("Value+4!", urlEncoded.getString("Name4"), "encoded get");
|
||||
}));
|
||||
|
||||
tests.add(dynamicTest("encoded param 2", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("Name4=Value+4%21%20%214");
|
||||
UrlEncoded.decodeTo("Name4=Value+4%21%20%214", urlEncoded, UrlEncoded.ENCODING);
|
||||
assertEquals(1, urlEncoded.size(), "encoded param size");
|
||||
assertEquals("Name4=Value+4%21+%214", urlEncoded.encode(), "encoded encode");
|
||||
assertEquals("Name4=Value+4%21+%214", UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false), "encoded encode");
|
||||
assertEquals("Value 4! !4", urlEncoded.getString("Name4"), "encoded get");
|
||||
}));
|
||||
|
||||
tests.add(dynamicTest("multi param", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("Name5=aaa&Name6=bbb");
|
||||
UrlEncoded.decodeTo("Name5=aaa&Name6=bbb", urlEncoded, UrlEncoded.ENCODING);
|
||||
assertEquals(2, urlEncoded.size(), "multi param size");
|
||||
assertTrue(urlEncoded.encode().equals("Name5=aaa&Name6=bbb") ||
|
||||
urlEncoded.encode().equals("Name6=bbb&Name5=aaa"),
|
||||
"multi encode " + urlEncoded.encode());
|
||||
assertTrue(UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false).equals("Name5=aaa&Name6=bbb") ||
|
||||
UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false).equals("Name6=bbb&Name5=aaa"),
|
||||
"multi encode " + UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false));
|
||||
assertEquals("aaa", urlEncoded.getString("Name5"), "multi get");
|
||||
assertEquals("bbb", urlEncoded.getString("Name6"), "multi get");
|
||||
}));
|
||||
|
||||
tests.add(dynamicTest("multiple value encoded", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("Name7=aaa&Name7=b%2Cb&Name7=ccc");
|
||||
assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", urlEncoded.encode(), "multi encode");
|
||||
UrlEncoded.decodeTo("Name7=aaa&Name7=b%2Cb&Name7=ccc", urlEncoded, UrlEncoded.ENCODING);
|
||||
assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false), "multi encode");
|
||||
assertEquals("aaa,b,b,ccc", urlEncoded.getString("Name7"), "list get all");
|
||||
assertEquals("aaa", urlEncoded.getValues("Name7").get(0), "list get");
|
||||
assertEquals("b,b", urlEncoded.getValues("Name7").get(1), "list get");
|
||||
|
@ -148,11 +154,11 @@ public class URLEncodedTest
|
|||
|
||||
tests.add(dynamicTest("encoded param", () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("Name8=xx%2C++yy++%2Czz");
|
||||
UrlEncoded.decodeTo("Name8=xx%2C++yy++%2Czz", urlEncoded, UrlEncoded.ENCODING);
|
||||
assertEquals(1, urlEncoded.size(), "encoded param size");
|
||||
assertEquals("Name8=xx%2C++yy++%2Czz", urlEncoded.encode(), "encoded encode");
|
||||
assertEquals("Name8=xx%2C++yy++%2Czz", UrlEncoded.encode(urlEncoded,UrlEncoded.ENCODING, false), "encoded encode");
|
||||
assertEquals("xx, yy ,zz", urlEncoded.getString("Name8"), "encoded get");
|
||||
}));
|
||||
|
||||
|
@ -219,7 +225,7 @@ public class URLEncodedTest
|
|||
{
|
||||
try (ByteArrayInputStream in3 = new ByteArrayInputStream("name=libell%E9".getBytes(StringUtil.__ISO_8859_1)))
|
||||
{
|
||||
MultiMap m3 = new MultiMap();
|
||||
MultiMap<String> m3 = new MultiMap<>();
|
||||
Charset nullCharset = null; // use the one from the system property
|
||||
UrlEncoded.decodeTo(in3, m3, nullCharset, -1, -1);
|
||||
assertEquals("libell\u00E9", m3.getString("name"), "stream name");
|
||||
|
@ -230,11 +236,11 @@ public class URLEncodedTest
|
|||
public void testUtf8()
|
||||
throws Exception
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
assertEquals(0, urlEncoded.size(), "Empty");
|
||||
|
||||
urlEncoded.clear();
|
||||
urlEncoded.decode("text=%E0%B8%9F%E0%B8%AB%E0%B8%81%E0%B8%A7%E0%B8%94%E0%B8%B2%E0%B9%88%E0%B8%81%E0%B8%9F%E0%B8%A7%E0%B8%AB%E0%B8%AA%E0%B8%94%E0%B8%B2%E0%B9%88%E0%B8%AB%E0%B8%9F%E0%B8%81%E0%B8%A7%E0%B8%94%E0%B8%AA%E0%B8%B2%E0%B8%9F%E0%B8%81%E0%B8%AB%E0%B8%A3%E0%B8%94%E0%B9%89%E0%B8%9F%E0%B8%AB%E0%B8%99%E0%B8%81%E0%B8%A3%E0%B8%94%E0%B8%B5&Action=Submit");
|
||||
UrlEncoded.decodeTo("text=%E0%B8%9F%E0%B8%AB%E0%B8%81%E0%B8%A7%E0%B8%94%E0%B8%B2%E0%B9%88%E0%B8%81%E0%B8%9F%E0%B8%A7%E0%B8%AB%E0%B8%AA%E0%B8%94%E0%B8%B2%E0%B9%88%E0%B8%AB%E0%B8%9F%E0%B8%81%E0%B8%A7%E0%B8%94%E0%B8%AA%E0%B8%B2%E0%B8%9F%E0%B8%81%E0%B8%AB%E0%B8%A3%E0%B8%94%E0%B9%89%E0%B8%9F%E0%B8%AB%E0%B8%99%E0%B8%81%E0%B8%A3%E0%B8%94%E0%B8%B5&Action=Submit", urlEncoded, UrlEncoded.ENCODING);
|
||||
|
||||
String hex = "E0B89FE0B8ABE0B881E0B8A7E0B894E0B8B2E0B988E0B881E0B89FE0B8A7E0B8ABE0B8AAE0B894E0B8B2E0B988E0B8ABE0B89FE0B881E0B8A7E0B894E0B8AAE0B8B2E0B89FE0B881E0B8ABE0B8A3E0B894E0B989E0B89FE0B8ABE0B899E0B881E0B8A3E0B894E0B8B5";
|
||||
String expected = new String(TypeUtil.fromHexString(hex), "utf-8");
|
||||
|
@ -245,8 +251,8 @@ public class URLEncodedTest
|
|||
public void testUtf8MultiByteCodePoint()
|
||||
{
|
||||
String input = "text=test%C3%A4";
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
urlEncoded.decode(input);
|
||||
MultiMap<String> urlEncoded = new MultiMap<>();
|
||||
UrlEncoded.decodeTo(input, urlEncoded, UrlEncoded.ENCODING);
|
||||
|
||||
// http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=00e4&mode=hex
|
||||
// Should be "testä"
|
||||
|
@ -255,4 +261,50 @@ public class URLEncodedTest
|
|||
String expected = "test\u00e4";
|
||||
assertThat(urlEncoded.getString("text"), is(expected));
|
||||
}
|
||||
|
||||
public static Stream<Arguments> invalidTestData()
|
||||
{
|
||||
ArrayList<Arguments> data = new ArrayList<>();
|
||||
data.add(Arguments.of("Name=xx%zzyy", UTF_8, IllegalArgumentException.class));
|
||||
data.add(Arguments.of("Name=%FF%FF%FF", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
data.add(Arguments.of("Name=%EF%EF%EF", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
data.add(Arguments.of("Name=%E%F%F", UTF_8, IllegalArgumentException.class));
|
||||
data.add(Arguments.of("Name=x%", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
data.add(Arguments.of("Name=x%2", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
data.add(Arguments.of("Name=xxx%", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
data.add(Arguments.of("name=X%c0%afZ", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
return data.stream();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidTestData")
|
||||
public void testInvalidDecode(String inputString, Charset charset, Class<? extends Throwable> expectedThrowable)
|
||||
{
|
||||
assertThrows(expectedThrowable, () ->
|
||||
{
|
||||
UrlEncoded.decodeTo(inputString, new MultiMap<>(), charset);
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidTestData")
|
||||
public void testInvalidDecodeUtf8ToMap(String inputString, Charset charset, Class<? extends Throwable> expectedThrowable)
|
||||
{
|
||||
assertThrows(expectedThrowable, () ->
|
||||
{
|
||||
MultiMap<String> map = new MultiMap<>();
|
||||
UrlEncoded.decodeUtf8To(inputString, map);
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidTestData")
|
||||
public void testInvalidDecodeTo(String inputString, Charset charset, Class<? extends Throwable> expectedThrowable)
|
||||
{
|
||||
assertThrows(expectedThrowable, () ->
|
||||
{
|
||||
MultiMap<String> map = new MultiMap<>();
|
||||
UrlEncoded.decodeTo(inputString, map, charset);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under
|
||||
// the terms of the Eclipse Public License 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// This Source Code may also be made available under the following
|
||||
// Secondary Licenses when the conditions for such availability set
|
||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||
// the Apache License v2.0 which is available at
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class UrlEncodedInvalidEncodingTest
|
||||
{
|
||||
public static Stream<Arguments> data()
|
||||
{
|
||||
ArrayList<Arguments> data = new ArrayList<>();
|
||||
data.add(Arguments.of("Name=xx%zzyy", UTF_8, IllegalArgumentException.class));
|
||||
data.add(Arguments.of("Name=%FF%FF%FF", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
data.add(Arguments.of("Name=%EF%EF%EF", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
data.add(Arguments.of("Name=%E%F%F", UTF_8, IllegalArgumentException.class));
|
||||
data.add(Arguments.of("Name=x%", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
data.add(Arguments.of("Name=x%2", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
data.add(Arguments.of("Name=xxx%", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
data.add(Arguments.of("name=X%c0%afZ", UTF_8, Utf8Appendable.NotUtf8Exception.class));
|
||||
return data.stream();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testDecode(String inputString, Charset charset, Class<? extends Throwable> expectedThrowable)
|
||||
{
|
||||
assertThrows(expectedThrowable, () ->
|
||||
{
|
||||
UrlEncoded urlEncoded = new UrlEncoded();
|
||||
urlEncoded.decode(inputString, charset);
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testDecodeUtf8ToMap(String inputString, Charset charset, Class<? extends Throwable> expectedThrowable)
|
||||
{
|
||||
assertThrows(expectedThrowable, () ->
|
||||
{
|
||||
MultiMap<String> map = new MultiMap<>();
|
||||
UrlEncoded.decodeUtf8To(inputString, map);
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testDecodeTo(String inputString, Charset charset, Class<? extends Throwable> expectedThrowable)
|
||||
{
|
||||
assertThrows(expectedThrowable, () ->
|
||||
{
|
||||
MultiMap<String> map = new MultiMap<>();
|
||||
UrlEncoded.decodeTo(inputString, map, charset);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -79,7 +79,7 @@ public class SessionDump extends HttpServlet
|
|||
session = request.getSession(true);
|
||||
session.setAttribute("test", "value");
|
||||
session.setAttribute("obj", new ObjectAttributeValue(System.currentTimeMillis()));
|
||||
session.setAttribute("WEBCL", new MultiMap());
|
||||
session.setAttribute("WEBCL", new MultiMap<>());
|
||||
}
|
||||
else if (session != null)
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ public class SessionDump extends HttpServlet
|
|||
else
|
||||
{
|
||||
if (session.getAttribute("WEBCL") == null)
|
||||
session.setAttribute("WEBCL", new MultiMap());
|
||||
session.setAttribute("WEBCL", new MultiMap<>());
|
||||
try
|
||||
{
|
||||
out.println("<b>ID:</b> " + session.getId() + "<br/>");
|
||||
|
|
Loading…
Reference in New Issue