From f3173094e597be21ed14cbc3037e0fb4eaa4933c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rg=20Prante?= Date: Tue, 17 Sep 2019 20:24:23 +0200 Subject: [PATCH] fix query parameter charset encoding --- gradle.properties | 4 +-- .../java/org/xbib/net/PercentDecoder.java | 2 ++ .../java/org/xbib/net/PercentEncoder.java | 2 ++ .../java/org/xbib/net/QueryParameters.java | 36 ++++++++++++++++--- net-url/src/main/java/org/xbib/net/URL.java | 13 ++++--- .../test/java/org/xbib/net/URLParserTest.java | 10 ++++++ .../java/org/xbib/net/body/ParseBodyTest.java | 4 +-- 7 files changed, 57 insertions(+), 14 deletions(-) diff --git a/gradle.properties b/gradle.properties index 9d7acb6..281a156 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ group = org.xbib name = net -version = 2.0.1 +version = 2.0.2 # test junit.version = 5.5.1 @@ -9,5 +9,3 @@ jackson.version = 2.9.9 # doc asciidoclet.version = 1.5.4 - -org.gradle.warning.mode = all diff --git a/net-url/src/main/java/org/xbib/net/PercentDecoder.java b/net-url/src/main/java/org/xbib/net/PercentDecoder.java index cfc37b9..c807f3b 100644 --- a/net-url/src/main/java/org/xbib/net/PercentDecoder.java +++ b/net-url/src/main/java/org/xbib/net/PercentDecoder.java @@ -11,6 +11,8 @@ import java.nio.charset.UnmappableCharacterException; /** * Decodes percent-encoded strings. + * + * This class is not thread-safe. */ public class PercentDecoder { diff --git a/net-url/src/main/java/org/xbib/net/PercentEncoder.java b/net-url/src/main/java/org/xbib/net/PercentEncoder.java index 68677de..41a625b 100644 --- a/net-url/src/main/java/org/xbib/net/PercentEncoder.java +++ b/net-url/src/main/java/org/xbib/net/PercentEncoder.java @@ -13,6 +13,8 @@ import java.util.BitSet; * * This is typically done when encoding components of URLs. See {@link PercentEncoders} for pre-configured * PercentEncoder instances. + * + * This class is not thread-safe. */ public class PercentEncoder { diff --git a/net-url/src/main/java/org/xbib/net/QueryParameters.java b/net-url/src/main/java/org/xbib/net/QueryParameters.java index ef06ec0..c322228 100644 --- a/net-url/src/main/java/org/xbib/net/QueryParameters.java +++ b/net-url/src/main/java/org/xbib/net/QueryParameters.java @@ -1,6 +1,9 @@ package org.xbib.net; +import java.nio.charset.Charset; +import java.nio.charset.CodingErrorAction; import java.nio.charset.MalformedInputException; +import java.nio.charset.StandardCharsets; import java.nio.charset.UnmappableCharacterException; import java.util.ArrayList; import java.util.List; @@ -25,8 +28,27 @@ public class QueryParameters extends ArrayList> { } public QueryParameters(int max) { + this(StandardCharsets.UTF_8, max); + } + + public QueryParameters(Charset charset) { + this(charset, 1024); + } + + public QueryParameters(Charset charset, int max) { + this(new PercentDecoder(charset.newDecoder() + .onUnmappableCharacter(CodingErrorAction.REPLACE) + .onMalformedInput(CodingErrorAction.REPLACE)), max); + } + + + public QueryParameters(PercentDecoder percentDecoder) { + this(percentDecoder, 1024); + } + + public QueryParameters(PercentDecoder percentDecoder, int max) { + this.percentDecoder = percentDecoder; this.max = max; - this.percentDecoder = new PercentDecoder(); } public List get(String key) { @@ -51,14 +73,20 @@ public class QueryParameters extends ArrayList> { return o instanceof QueryParameters && super.equals(o); } - public QueryParameters addPercentEncodedBody(String body) throws MalformedInputException, UnmappableCharacterException { + public QueryParameters addPercentEncodedBody(String body) { String s = body; while (s != null) { Pair pairs = indexOf(AMPERSAND_CHAR, s); Pair pair = indexOf(EQUAL_CHAR, pairs.getFirst()); if (!isNullOrEmpty(pair.getFirst())) { - add(percentDecoder.decode(pair.getFirst()), - percentDecoder.decode(pair.getSecond())); + try { + add(percentDecoder.decode(pair.getFirst()), + percentDecoder.decode(pair.getSecond())); + } catch (MalformedInputException e) { + // never thrown + } catch (UnmappableCharacterException e) { + // never thrown + } } s = pairs.getSecond(); } diff --git a/net-url/src/main/java/org/xbib/net/URL.java b/net-url/src/main/java/org/xbib/net/URL.java index 1ae655d..16a6d5e 100755 --- a/net-url/src/main/java/org/xbib/net/URL.java +++ b/net-url/src/main/java/org/xbib/net/URL.java @@ -11,6 +11,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; import java.nio.charset.CodingErrorAction; import java.nio.charset.MalformedInputException; import java.nio.charset.StandardCharsets; @@ -825,7 +826,7 @@ public class URL implements Comparable { private PercentDecoder percentDecoder; - private final QueryParameters queryParams; + private QueryParameters queryParams; private final List pathSegments; @@ -854,22 +855,24 @@ public class URL implements Comparable { private boolean fatalResolveErrorsEnabled; private Builder() { - this.queryParams = new QueryParameters(); this.pathSegments = new ArrayList<>(); charset(StandardCharsets.UTF_8, CodingErrorAction.REPLACE); } /** * Set the character set of the URL. Default is UTF-8. - * @param charset the chaarcter set + * @param charset the character set + * @param codingErrorAction the coding error action * @return this builder */ public Builder charset(Charset charset, CodingErrorAction codingErrorAction) { this.charset = charset; this.codingErrorAction = codingErrorAction; this.regNameEncoder = PercentEncoders.getRegNameEncoder(charset); - this.percentDecoder = new PercentDecoder(charset.newDecoder() - .onUnmappableCharacter(codingErrorAction)); + CharsetDecoder charsetDecoder = charset.newDecoder() + .onUnmappableCharacter(codingErrorAction); + this.percentDecoder = new PercentDecoder(charsetDecoder); + this.queryParams = new QueryParameters(percentDecoder); return this; } diff --git a/net-url/src/test/java/org/xbib/net/URLParserTest.java b/net-url/src/test/java/org/xbib/net/URLParserTest.java index 52d1868..803b17b 100644 --- a/net-url/src/test/java/org/xbib/net/URLParserTest.java +++ b/net-url/src/test/java/org/xbib/net/URLParserTest.java @@ -434,6 +434,16 @@ class URLParserTest { assertEquals("http://library.fes.de/library/journals/de-part/das-rote-blättla/index.html", url.toString()); } + @Test + void testPathQueryFragmentFromPath(){ + URL url = URL.builder() + .path("/a/b?c=d#e") + .build(); + assertEquals("/a/b", url.getPath()); + assertEquals("c=d", url.getQuery()); + assertEquals("e", url.getFragment()); + } + private void assertUrlCompatibility(String url) throws Exception { String s = URL.from(url).toExternalForm(); assertEquals(s, URL.from(s).toExternalForm()); diff --git a/net-url/src/test/java/org/xbib/net/body/ParseBodyTest.java b/net-url/src/test/java/org/xbib/net/body/ParseBodyTest.java index be3f1ea..383afd5 100644 --- a/net-url/src/test/java/org/xbib/net/body/ParseBodyTest.java +++ b/net-url/src/test/java/org/xbib/net/body/ParseBodyTest.java @@ -13,7 +13,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class ParseBodyTest { @Test - void testSimpleParse() throws MalformedInputException, UnmappableCharacterException { + void testSimpleParse() { QueryParameters queryParameters = new QueryParameters(); String body = "a=b&c=d&e=f"; queryParameters.addPercentEncodedBody(body); @@ -23,7 +23,7 @@ class ParseBodyTest { } @Test - void testManyParse() throws MalformedInputException, UnmappableCharacterException { + void testManyParse() { QueryParameters queryParameters = new QueryParameters(100); List list = new ArrayList<>(); for (int i = 0; i < 200; i++) {