From 29bd0899b8350d3af96b151e2727ad8e428ffcdb Mon Sep 17 00:00:00 2001 From: Peter Lamby Date: Thu, 30 Jun 2022 12:47:33 +0200 Subject: [PATCH 1/7] WICKET-6993 - Add test to confirm the bug --- .../apache/wicket/resource/ResourceUtilTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java b/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java index 92b84bac256..5d1c39ab024 100644 --- a/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java @@ -97,6 +97,21 @@ void encodeResourceReferenceAttributes() throws Exception assertEquals("--variation", ResourceUtil.encodeResourceReferenceAttributes(attributes)); } + @Test + void encodeAndDecodeVariationShouldBeEqual() throws Exception + { + String[] variations = new String[] {"double--separator", "single-e-inside", "-", "--", "~", "~~"}; + + for (String variation : variations) { + UrlAttributes attributes = new UrlAttributes(null, null, variation); + String encoded = ResourceUtil.encodeResourceReferenceAttributes(attributes); + + attributes = ResourceUtil.decodeResourceReferenceAttributes(encoded); + + assertEquals(variation, attributes.getVariation()); + } + } + @Test void encodeResourceReferenceAttributesWithResource() throws Exception { From 0246fa059f483fdf62f7dabbd86a16a77220132e Mon Sep 17 00:00:00 2001 From: Peter Lamby Date: Thu, 30 Jun 2022 14:54:11 +0200 Subject: [PATCH 2/7] WICKET-6993 - Add new escape methods We prepare the refactor of the resource encoding by adding new methods for encoding and decoding the parts of an resource --- .../apache/wicket/resource/ResourceUtil.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java b/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java index 28ed7e2562e..b2709d240ec 100644 --- a/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java +++ b/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; +import java.util.ArrayList; import java.util.Locale; import java.util.regex.Pattern; @@ -39,6 +40,10 @@ public class ResourceUtil { + /** + * Used to denote {@code null} in encoded strings. + */ + private static final String NULL_VALUE = "null"; private static final Pattern ESCAPED_ATTRIBUTE_PATTERN = Pattern.compile("(\\w)~(\\w)"); /** @@ -281,6 +286,62 @@ public static String unescapeAttributesSeparator(String attribute) return Strings.replaceAll(tmp, "~~", "~").toString(); } + /** + * Encode the {@code part} in the format ~. + * + * If the {@code part} is {@code null} the special value {@link #NULL_VALUE} is returned; + * + * @param part + * The string to encode + * @return The encoded string + */ + static String encodeStringPart(String part) + { + if (part == null) { + return NULL_VALUE; + } + + int length = part.length(); + return length + "~" + part; + } + + /** + * Decodes the {@code encoded} parts of a string decoded by {@link #encodeStringPart(String)}. + * + * @param encoded + * @return An array containing the parts of {@code encoded}. + * The array can contain {@code null} but is itself never {@code null} + */ + static String[] decodeStringParts(String encoded) + { + ArrayList result = new ArrayList<>(); + + StringBuilder lengthString = new StringBuilder(); + char[] chars = encoded.toCharArray(); + for (int i = 0; i < chars.length; i++) + { + boolean isAtStartOfPart = lengthString.length() == 0; + if (isAtStartOfPart && chars.length >= i + NULL_VALUE.length() && + String.valueOf(chars, i, NULL_VALUE.length()).equals(NULL_VALUE)) { + result.add(null); + i += NULL_VALUE.length() - 1; + continue; + } + + char c = chars[i]; + if (c >= '0' && c <= '9') { + lengthString.append(c); + } else { + int length = Integer.parseInt(lengthString.toString()); + lengthString.setLength(0); // reset the length buffer + result.add(String.valueOf(chars, i + 1, length)); + i += length; + } + } + + return result.toArray(String[]::new); + } + private ResourceUtil() { // no-op From 5e68af1e179e47c5620d32ae93c97efe06ee2dda Mon Sep 17 00:00:00 2001 From: Peter Lamby Date: Thu, 30 Jun 2022 14:55:40 +0200 Subject: [PATCH 3/7] WICKET-6993 - Use new encoding mechanism We can now use the encoding mechanism introduced in the previous commit to simplify the encoding and decoding of the entire resource attributes. --- .../apache/wicket/resource/ResourceUtil.java | 61 ++++++------------- 1 file changed, 17 insertions(+), 44 deletions(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java b/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java index b2709d240ec..7aac09a6d57 100644 --- a/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java +++ b/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java @@ -57,24 +57,12 @@ public class ResourceUtil */ public static ResourceReference.UrlAttributes decodeResourceReferenceAttributes(String encodedAttributes) { - Locale locale = null; - String style = null; - String variation = null; + String[] decodeAttributes = decodeStringParts(encodedAttributes); + + Locale locale = decodeAttributes.length > 0 ? parseLocale(decodeAttributes[0]) : null; + String style = decodeAttributes.length > 1 ? decodeAttributes[1] : null; + String variation = decodeAttributes.length > 2 ? decodeAttributes[2] : null; - if (Strings.isEmpty(encodedAttributes) == false) - { - String split[] = Strings.split(encodedAttributes, '-'); - locale = parseLocale(split[0]); - if (split.length == 2) - { - style = Strings.defaultIfEmpty(unescapeAttributesSeparator(split[1]), null); - } - else if (split.length == 3) - { - style = Strings.defaultIfEmpty(unescapeAttributesSeparator(split[1]), null); - variation = Strings.defaultIfEmpty(unescapeAttributesSeparator(split[2]), null); - } - } return new ResourceReference.UrlAttributes(locale, style, variation); } @@ -114,37 +102,18 @@ public static ResourceReference.UrlAttributes decodeResourceReferenceAttributes( public static String encodeResourceReferenceAttributes(ResourceReference.UrlAttributes attributes) { if (attributes == null || - (attributes.getLocale() == null && attributes.getStyle() == null && attributes.getVariation() == null)) - { - return null; - } - else - { - StringBuilder res = new StringBuilder(32); - if (attributes.getLocale() != null) - { - res.append(attributes.getLocale()); - } - boolean styleEmpty = Strings.isEmpty(attributes.getStyle()); - if (!styleEmpty) + (attributes.getLocale() == null && attributes.getStyle() == null && attributes.getVariation() == null)) { - res.append('-'); - res.append(escapeAttributesSeparator(attributes.getStyle())); + return null; } - if (!Strings.isEmpty(attributes.getVariation())) + else { - if (styleEmpty) - { - res.append("--"); - } - else - { - res.append('-'); - } - res.append(escapeAttributesSeparator(attributes.getVariation())); + StringBuilder res = new StringBuilder(32); + res.append(encodeStringPart(attributes.getLocale() == null ? null : attributes.getLocale().toString())); + res.append(encodeStringPart(attributes.getStyle())); + res.append(encodeStringPart(attributes.getVariation())); + return res.toString(); } - return res.toString(); - } } /** @@ -332,6 +301,10 @@ static String[] decodeStringParts(String encoded) if (c >= '0' && c <= '9') { lengthString.append(c); } else { + if (isAtStartOfPart || c != '~') { // Not a (valid) resource attribute string + return new String[0]; + } + int length = Integer.parseInt(lengthString.toString()); lengthString.setLength(0); // reset the length buffer result.add(String.valueOf(chars, i + 1, length)); From af1c7ee3d432c92bfcee19582877c907dc4226b7 Mon Sep 17 00:00:00 2001 From: Peter Lamby Date: Thu, 30 Jun 2022 15:00:12 +0200 Subject: [PATCH 4/7] WICKET-6993 - Remove outdated test This test is the only usage in the code of the old escape methods. We remove it in preparation for the next commit which removes the old escape methods entirely. --- ...bstractResourceReferenceMapperOwnTest.java | 68 ------------------- 1 file changed, 68 deletions(-) delete mode 100644 wicket-core/src/test/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapperOwnTest.java diff --git a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapperOwnTest.java b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapperOwnTest.java deleted file mode 100644 index 104d2f90408..00000000000 --- a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapperOwnTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.wicket.core.request.mapper; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.apache.wicket.request.IRequestHandler; -import org.apache.wicket.request.Request; -import org.apache.wicket.request.Url; -import org.apache.wicket.resource.ResourceUtil; -import org.junit.jupiter.api.Test; - -/** - * Tests for AbstractResourceReferenceMapper's own methods - */ -class AbstractResourceReferenceMapperOwnTest -{ - @Test - void testEscapeAttributesSeparator() throws Exception - { - AbstractResourceReferenceMapper mapper = new Mapper(); - CharSequence escaped = ResourceUtil.escapeAttributesSeparator("my-style~is~~cool"); - assertEquals("my~style~~is~~~~cool", escaped.toString()); - } - - @Test - void testUnescapeAttributesSeparator() throws Exception - { - AbstractResourceReferenceMapper mapper = new Mapper(); - CharSequence escaped = ResourceUtil.unescapeAttributesSeparator("my~style~~is~~~~cool"); - assertEquals("my-style~is~~cool", escaped.toString()); - } - - /** - * A non-abstract class used for the tests - */ - private static class Mapper extends AbstractResourceReferenceMapper - { - public IRequestHandler mapRequest(Request request) - { - return null; - } - - public int getCompatibilityScore(Request request) - { - return 0; - } - - public Url mapHandler(IRequestHandler requestHandler) - { - return null; - } - } -} From bbcacd8f217dea9aff18968c6f0a336c375fd599 Mon Sep 17 00:00:00 2001 From: Peter Lamby Date: Thu, 30 Jun 2022 14:58:04 +0200 Subject: [PATCH 5/7] WICKET-6993 - Get rid of unused old escape methods These are not used in the code anymore --- .../apache/wicket/resource/ResourceUtil.java | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java b/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java index 7aac09a6d57..b77630a42a7 100644 --- a/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java +++ b/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java @@ -21,7 +21,6 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Locale; -import java.util.regex.Pattern; import org.apache.wicket.WicketRuntimeException; import org.apache.wicket.request.Url; @@ -44,7 +43,6 @@ public class ResourceUtil * Used to denote {@code null} in encoded strings. */ private static final String NULL_VALUE = "null"; - private static final Pattern ESCAPED_ATTRIBUTE_PATTERN = Pattern.compile("(\\w)~(\\w)"); /** * Reads resource reference attributes (style, locale, variation) encoded in the given string. @@ -138,20 +136,6 @@ public static void encodeResourceReferenceAttributes(Url url, ResourceReference } } - /** - * Escapes any occurrences of - character in the style and variation - * attributes with ~. Any occurrence of ~ is encoded as ~~. - * - * @param attribute - * the attribute to escape - * @return the attribute with escaped separator character - */ - public static CharSequence escapeAttributesSeparator(String attribute) - { - CharSequence tmp = Strings.replaceAll(attribute, "~", "~~"); - return Strings.replaceAll(tmp, "-", "~"); - } - /** * Parses the string representation of a {@link java.util.Locale} (for example 'en_GB'). * @@ -241,20 +225,6 @@ public static String readString(IResourceStream resourceStream, Charset charset) } } - /** - * Reverts the escaping applied by {@linkplain #escapeAttributesSeparator(String)} - unescapes - * occurrences of ~ character in the style and variation attributes with -. - * - * @param attribute - * the attribute to unescape - * @return the attribute with escaped separator character - */ - public static String unescapeAttributesSeparator(String attribute) - { - String tmp = ESCAPED_ATTRIBUTE_PATTERN.matcher(attribute).replaceAll("$1-$2"); - return Strings.replaceAll(tmp, "~~", "~").toString(); - } - /** * Encode the {@code part} in the format ~. * From 8537a97ecbeba072c89697d4a8a8b465ebf2abcc Mon Sep 17 00:00:00 2001 From: Peter Lamby Date: Thu, 30 Jun 2022 15:32:21 +0200 Subject: [PATCH 6/7] WICKET-6993 - Adjust test cases for new format --- .../BasicResourceReferenceMapperTest.java | 38 +++++++++---------- .../form/imagebutton/ImageButtonTest.java | 10 ++--- .../wicket/markup/html/image/ImageTest.java | 10 ++--- .../link/AutolinkPageExpectedResult_1.html | 6 +-- .../wicket/resource/ResourceUtilTest.java | 22 +++++------ 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java index def27a40688..d6dd3e5fbc8 100644 --- a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java @@ -83,7 +83,7 @@ void decode1() @Test void decode1A() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference1?en"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference1?2~ennullnull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); // assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); // TODO use hamcrest or assertj ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -120,7 +120,7 @@ void decode2() @Test void decode2A() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference1?-style&p1=v1&p2=v2"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference1?null5~stylenull&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -139,7 +139,7 @@ void decode2A() @Test void decode3() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?en_EN"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?5~en_ENnullnull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); @@ -158,7 +158,7 @@ void decode3() @Test void decode3A() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?en_EN-style"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?5~en_EN5~stylenull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -188,7 +188,7 @@ void decode3B() void decode4() { Url url = Url - .parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?en_EN&p1=v1&p2=v2"); + .parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?5~en_ENnullnull&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -206,7 +206,7 @@ void decode4() @Test void decode5() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference3?-style"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference3?null5~stylenull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -224,7 +224,7 @@ void decode5() @Test void decode6() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference3?-style&p1=v1&p2=v2"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference3?null5~stylenull&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -244,7 +244,7 @@ void decode6() @Test void decode7() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?en-style"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?2~en5~stylenull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -262,7 +262,7 @@ void decode7() @Test void decode7A() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?sk"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?2~sknullnull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertNull(handler); } @@ -273,7 +273,7 @@ void decode7A() @Test void decode8() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?en-style&p1=v1&p2=v2"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?2~en5~stylenull&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -293,7 +293,7 @@ void decode8() void decode9() { Url url = Url.parse("wicket/resource/" + CLASS_NAME - + "/reference5?en--variation&p1=v1&p2=v2"); + + "/reference5?2~ennull9~variation&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -313,7 +313,7 @@ void decode9() void decode10() { Url url = Url.parse("wicket/resource/" + CLASS_NAME - + "/reference6?en-style-variation&p1=v1&p2=v2"); + + "/reference6?2~en5~style9~variation&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -375,7 +375,7 @@ void encode3() ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference2, null); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference2/name2?en_EN", url.toString()); + assertEquals("wicket/resource/" + CLASS_NAME + "/reference2/name2?5~en_ENnullnull", url.toString()); } /** @@ -392,7 +392,7 @@ void encode4() parameters); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference2/name2?en_EN&p1=v1&p2=v2", + assertEquals("wicket/resource/" + CLASS_NAME + "/reference2/name2?5~en_ENnullnull&p1=v1&p2=v2", url.toString()); } @@ -405,7 +405,7 @@ void encode5() ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference3, null); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference3?-style", url.toString()); + assertEquals("wicket/resource/" + CLASS_NAME + "/reference3?null5~stylenull", url.toString()); } /** @@ -422,7 +422,7 @@ void encode6() parameters); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference3?-style&p1=v1&p2=v2", + assertEquals("wicket/resource/" + CLASS_NAME + "/reference3?null5~stylenull&p1=v1&p2=v2", url.toString()); } @@ -435,7 +435,7 @@ void encode7() ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference4, null); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference4?en-style", url.toString()); + assertEquals("wicket/resource/" + CLASS_NAME + "/reference4?2~en5~stylenull", url.toString()); } /** @@ -452,7 +452,7 @@ void encode8() parameters); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference4?en-style&p1=v1&p2=v2", + assertEquals("wicket/resource/" + CLASS_NAME + "/reference4?2~en5~stylenull&p1=v1&p2=v2", url.toString()); } @@ -466,7 +466,7 @@ void encode9() null); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference5?en--variation", url.toString()); + assertEquals("wicket/resource/" + CLASS_NAME + "/reference5?2~ennull9~variation", url.toString()); } /** diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/imagebutton/ImageButtonTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/imagebutton/ImageButtonTest.java index 7e7ffae0304..5403b627119 100644 --- a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/imagebutton/ImageButtonTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/imagebutton/ImageButtonTest.java @@ -38,19 +38,19 @@ void imageButton() throws Exception tester.startPage(Home.class); tester.clickLink("goCanadian"); - tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?en_CA\""); + tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?5~en_CAnullnull\""); tester.clickLink("goChinese"); - tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?zh_CN\""); + tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?5~zh_CNnullnull\""); tester.clickLink("goDanish"); - tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?da_DK\""); + tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?5~da_DKnullnull\""); tester.clickLink("goDutch"); - tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?nl_NL\""); + tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?5~nl_NLnullnull\""); tester.clickLink("goGerman"); - tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?de_DE\""); + tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?5~de_DEnullnull\""); tester.clickLink("goUS"); tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\""); diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageTest.java index 04e8ad94e6b..9b87d7eca4d 100644 --- a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageTest.java @@ -38,19 +38,19 @@ void test_1() throws Exception tester.startPage(Home.class); tester.clickLink("goCanadian"); - tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?en_CA\""); + tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?5~en_CAnullnull\""); tester.clickLink("goChinese"); - tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?zh_CN\""); + tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?5~zh_CNnullnull\""); tester.clickLink("goDanish"); - tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?da_DK\""); + tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?5~da_DKnullnull\""); tester.clickLink("goDutch"); - tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?nl_NL\""); + tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?5~nl_NLnullnull\""); tester.clickLink("goGerman"); - tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?de_DE\""); + tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?5~de_DEnullnull\""); tester.clickLink("goUS"); tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\""); diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/link/AutolinkPageExpectedResult_1.html b/wicket-core/src/test/java/org/apache/wicket/markup/html/link/AutolinkPageExpectedResult_1.html index fcf1cade818..4e00ff16e50 100644 --- a/wicket-core/src/test/java/org/apache/wicket/markup/html/link/AutolinkPageExpectedResult_1.html +++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/link/AutolinkPageExpectedResult_1.html @@ -25,9 +25,9 @@ Home - - - + + + Home Home Google diff --git a/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java b/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java index 5d1c39ab024..7a4fe9f74fd 100644 --- a/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java @@ -32,30 +32,30 @@ class ResourceUtilTest @Test void decodeResourceReferenceAttributesWithString() throws Exception { - String urlParameter = "en_GB-style-variation"; + String urlParameter = "5~en_GB5~style9~variation"; UrlAttributes attributes = ResourceUtil.decodeResourceReferenceAttributes(urlParameter); assertEquals(Locale.UK, attributes.getLocale()); assertEquals("style", attributes.getStyle()); assertEquals("variation", attributes.getVariation()); - attributes = ResourceUtil.decodeResourceReferenceAttributes("it_IT"); + attributes = ResourceUtil.decodeResourceReferenceAttributes("5~it_ITnullnull"); assertEquals(Locale.ITALY, attributes.getLocale()); assertNull(attributes.getStyle()); assertNull(attributes.getVariation()); - attributes = ResourceUtil.decodeResourceReferenceAttributes("-style-variation"); + attributes = ResourceUtil.decodeResourceReferenceAttributes("null5~style9~variation"); assertNull(attributes.getLocale()); assertEquals("style", attributes.getStyle()); assertEquals("variation", attributes.getVariation()); - attributes = ResourceUtil.decodeResourceReferenceAttributes("--variation"); + attributes = ResourceUtil.decodeResourceReferenceAttributes("nullnull9~variation"); assertNull(attributes.getLocale()); assertNull(attributes.getStyle()); assertEquals("variation", attributes.getVariation()); - attributes = ResourceUtil.decodeResourceReferenceAttributes("-style"); + attributes = ResourceUtil.decodeResourceReferenceAttributes("null5~stylenull"); assertNull(attributes.getLocale()); assertEquals("style", attributes.getStyle()); assertNull(attributes.getVariation()); @@ -69,13 +69,13 @@ void decodeResourceReferenceAttributesWithUrl() throws Exception assertEquals(new UrlAttributes(null, null, null), attributes); - url = Url.parse("www.funny.url/?de_DE"); + url = Url.parse("www.funny.url/?5~de_DEnullnull"); attributes = ResourceUtil.decodeResourceReferenceAttributes(url); assertEquals(Locale.GERMANY, attributes.getLocale()); assertNull(attributes.getStyle()); assertNull(attributes.getVariation()); - url = Url.parse("www.funny.url/?-style"); + url = Url.parse("www.funny.url/?null5~stylenull"); attributes = ResourceUtil.decodeResourceReferenceAttributes(url); assertNull(attributes.getLocale()); assertEquals("style", attributes.getStyle()); @@ -90,11 +90,11 @@ void encodeResourceReferenceAttributes() throws Exception attributes = new UrlAttributes(Locale.CANADA_FRENCH, "style", "variation"); - assertEquals("fr_CA-style-variation", ResourceUtil.encodeResourceReferenceAttributes(attributes)); + assertEquals("5~fr_CA5~style9~variation", ResourceUtil.encodeResourceReferenceAttributes(attributes)); attributes = new UrlAttributes(null, null, "variation"); - assertEquals("--variation", ResourceUtil.encodeResourceReferenceAttributes(attributes)); + assertEquals("nullnull9~variation", ResourceUtil.encodeResourceReferenceAttributes(attributes)); } @Test @@ -136,7 +136,7 @@ void encodeResourceReferenceAttributesWithResource() throws Exception Mockito.when(resourceReference.getUrlAttributes()).thenReturn(attributes); ResourceUtil.encodeResourceReferenceAttributes(url, resourceReference); - assertEquals(urlString + "?fr_CA-style-variation", url.toString()); + assertEquals(urlString + "?5~fr_CA5~style9~variation", url.toString()); Mockito.reset(resourceReference); @@ -147,6 +147,6 @@ void encodeResourceReferenceAttributesWithResource() throws Exception Mockito.when(resourceReference.getUrlAttributes()).thenReturn(attributes); ResourceUtil.encodeResourceReferenceAttributes(url, resourceReference); - assertEquals(urlString + "?--variation", url.toString()); + assertEquals(urlString + "?nullnull9~variation", url.toString()); } } From f1b5bb2b69cc2c936532f848095608193589898f Mon Sep 17 00:00:00 2001 From: Peter Lamby Date: Mon, 4 Jul 2022 08:41:57 +0200 Subject: [PATCH 7/7] WICKET-6993 - Use buffer to avoid temporary strings --- .../apache/wicket/resource/ResourceUtil.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java b/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java index b77630a42a7..ce5a22a406b 100644 --- a/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java +++ b/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java @@ -106,11 +106,11 @@ public static String encodeResourceReferenceAttributes(ResourceReference.UrlAttr } else { - StringBuilder res = new StringBuilder(32); - res.append(encodeStringPart(attributes.getLocale() == null ? null : attributes.getLocale().toString())); - res.append(encodeStringPart(attributes.getStyle())); - res.append(encodeStringPart(attributes.getVariation())); - return res.toString(); + StringBuilder buffer = new StringBuilder(32); + encodeStringPart(attributes.getLocale() == null ? null : attributes.getLocale().toString(), buffer); + encodeStringPart(attributes.getStyle(), buffer); + encodeStringPart(attributes.getVariation(), buffer); + return buffer.toString(); } } @@ -228,20 +228,22 @@ public static String readString(IResourceStream resourceStream, Charset charset) /** * Encode the {@code part} in the format ~. * - * If the {@code part} is {@code null} the special value {@link #NULL_VALUE} is returned; + * If the {@code part} is {@code null} the special value {@link #NULL_VALUE} is used; * * @param part - * The string to encode - * @return The encoded string + * The string to encode. + * @param buffer + * The buffer into which the {@code part} is encoded. + * @return The {@code buffer} for chaining. */ - static String encodeStringPart(String part) + static StringBuilder encodeStringPart(String part, StringBuilder buffer) { if (part == null) { - return NULL_VALUE; + return buffer.append(NULL_VALUE); } int length = part.length(); - return length + "~" + part; + return buffer.append(length).append('~').append(part); } /**