WICKET-4844 AbstractResourceReferenceMapper doesn't escape separators in 
style/variation names


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/1f44cb30
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/1f44cb30
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/1f44cb30

Branch: refs/heads/master
Commit: 1f44cb3078e8f80b43e3ff5fc3d3a9c4739b6d63
Parents: d5720e6
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Mon Oct 29 16:31:26 2012 +0200
Committer: Martin Tzvetanov Grigorov <[email protected]>
Committed: Mon Oct 29 16:34:40 2012 +0200

----------------------------------------------------------------------
 .../mapper/AbstractResourceReferenceMapper.java    |   54 +++++++++----
 .../AbstractResourceReferenceMapperOwnTest.java    |   66 +++++++++++++++
 2 files changed, 105 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/1f44cb30/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapper.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapper.java
 
b/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapper.java
index 65e5efb..f95ca9e 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapper.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapper.java
@@ -19,7 +19,6 @@ package org.apache.wicket.core.request.mapper;
 import java.util.Locale;
 
 import org.apache.wicket.request.Url;
-import org.apache.wicket.request.Url.QueryParameter;
 import org.apache.wicket.request.resource.ResourceReference;
 import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.string.Strings;
@@ -31,9 +30,35 @@ import org.apache.wicket.util.string.Strings;
  */
 public abstract class AbstractResourceReferenceMapper extends 
AbstractComponentMapper
 {
+       /**
+        * Escapes any occurrences of <em>-</em> character in the style and 
variation
+        * attributes with <em>~</em>. Any occurrence of <em>~</em> is encoded 
as <em>~~</em>.
+        *
+        * @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, "-", "~");
+       }
+
+       /**
+        * Reverts the escaping applied by {@linkplain 
#escapeAttributesSeparator(String)} - unescapes
+        * occurrences of <em>~</em> character in the style and variation 
attributes with <em>-</em>.
+        *
+        * @param attribute
+        *      the attribute to unescape
+        * @return the attribute with escaped separator character
+        */
+       public static String unescapeAttributesSeparator(String attribute)
+       {
+               String tmp = attribute.replaceAll("(\\w)~(\\w)", "$1-$2");
+               return Strings.replaceAll(tmp, "~~", "~").toString();
+       }
 
-       protected final String encodeResourceReferenceAttributes(
-               ResourceReference.UrlAttributes attributes)
+       protected final String 
encodeResourceReferenceAttributes(ResourceReference.UrlAttributes attributes)
        {
                if (attributes == null ||
                        (attributes.getLocale() == null && 
attributes.getStyle() == null && attributes.getVariation() == null))
@@ -42,16 +67,16 @@ public abstract class AbstractResourceReferenceMapper 
extends AbstractComponentM
                }
                else
                {
-                       StringBuilder res = new StringBuilder();
+                       StringBuilder res = new StringBuilder(32);
                        if (attributes.getLocale() != null)
                        {
-                               res.append(attributes.getLocale().toString());
+                               res.append(attributes.getLocale());
                        }
                        boolean styleEmpty = 
Strings.isEmpty(attributes.getStyle());
                        if (!styleEmpty)
                        {
                                res.append('-');
-                               res.append(attributes.getStyle());
+                               
res.append(escapeAttributesSeparator(attributes.getStyle()));
                        }
                        if (!Strings.isEmpty(attributes.getVariation()))
                        {
@@ -63,7 +88,7 @@ public abstract class AbstractResourceReferenceMapper extends 
AbstractComponentM
                                {
                                        res.append('-');
                                }
-                               res.append(attributes.getVariation());
+                               
res.append(escapeAttributesSeparator(attributes.getVariation()));
                        }
                        return res.toString();
                }
@@ -81,25 +106,24 @@ public abstract class AbstractResourceReferenceMapper 
extends AbstractComponentM
                }
        }
 
-       protected final ResourceReference.UrlAttributes 
decodeResourceReferenceAttributes(
-               String attributes)
+       protected final ResourceReference.UrlAttributes 
decodeResourceReferenceAttributes(String attributes)
        {
                Locale locale = null;
                String style = null;
                String variation = null;
 
-               if (!Strings.isEmpty(attributes))
+               if (Strings.isEmpty(attributes) == false)
                {
-                       String split[] = attributes.split("-", 3);
+                       String split[] = Strings.split(attributes, '-');
                        locale = parseLocale(split[0]);
                        if (split.length == 2)
                        {
-                               style = nonEmpty(split[1]);
+                               style = 
nonEmpty(unescapeAttributesSeparator(split[1]));
                        }
                        else if (split.length == 3)
                        {
-                               style = nonEmpty(split[1]);
-                               variation = nonEmpty(split[2]);
+                               style = 
nonEmpty(unescapeAttributesSeparator(split[1]));
+                               variation = 
nonEmpty(unescapeAttributesSeparator(split[2]));
                        }
                }
                return new ResourceReference.UrlAttributes(locale, style, 
variation);
@@ -148,7 +172,7 @@ public abstract class AbstractResourceReferenceMapper 
extends AbstractComponentM
 
                if (url.getQueryParameters().size() > 0)
                {
-                       QueryParameter param = url.getQueryParameters().get(0);
+                       Url.QueryParameter param = 
url.getQueryParameters().get(0);
                        if (Strings.isEmpty(param.getValue()))
                        {
                                return 
decodeResourceReferenceAttributes(param.getName());

http://git-wip-us.apache.org/repos/asf/wicket/blob/1f44cb30/wicket-core/src/test/java/org/apache/wicket/request/mapper/AbstractResourceReferenceMapperOwnTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/request/mapper/AbstractResourceReferenceMapperOwnTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/request/mapper/AbstractResourceReferenceMapperOwnTest.java
new file mode 100644
index 0000000..8e73a5d
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/request/mapper/AbstractResourceReferenceMapperOwnTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.request.mapper;
+
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.Request;
+import org.apache.wicket.request.Url;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests for AbstractResourceReferenceMapper's own methods
+ */
+public class AbstractResourceReferenceMapperOwnTest extends Assert
+{
+       @Test
+       public void testEscapeAttributesSeparator() throws Exception
+       {
+               AbstractResourceReferenceMapper mapper = new Mapper();
+               CharSequence escaped = 
mapper.escapeAttributesSeparator("my-style~is~~cool");
+               assertEquals("my~style~~is~~~~cool", escaped.toString());
+       }
+
+       @Test
+       public void testUnescapeAttributesSeparator() throws Exception
+       {
+               AbstractResourceReferenceMapper mapper = new Mapper();
+               CharSequence escaped = 
mapper.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;
+               }
+       }
+}

Reply via email to