Revision: 1168
          http://stripes.svn.sourceforge.net/stripes/?rev=1168&view=rev
Author:   bengunter
Date:     2009-10-16 20:18:51 +0000 (Fri, 16 Oct 2009)

Log Message:
-----------
Fixed STS-680: Anchors are not URL encoded when generated with s:link anchor 
attribute. Anchors are now encoded as a URI fragment according to my 
interpretation of RFC 3986.

Modified Paths:
--------------
    branches/1.5.x/stripes/src/net/sourceforge/stripes/util/StringUtil.java
    branches/1.5.x/stripes/src/net/sourceforge/stripes/util/UrlBuilder.java

Modified: 
branches/1.5.x/stripes/src/net/sourceforge/stripes/util/StringUtil.java
===================================================================
--- branches/1.5.x/stripes/src/net/sourceforge/stripes/util/StringUtil.java     
2009-10-16 17:53:35 UTC (rev 1167)
+++ branches/1.5.x/stripes/src/net/sourceforge/stripes/util/StringUtil.java     
2009-10-16 20:18:51 UTC (rev 1168)
@@ -4,6 +4,7 @@
 import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.util.Arrays;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import net.sourceforge.stripes.exception.StripesRuntimeException;
@@ -22,6 +23,14 @@
     private static final Pattern STANDARD_SPLIT = Pattern.compile("[\\s,]+");
 
     /**
+     * A regular expression that matches characters that are not explicitly 
allowed in the fragment
+     * part of a URI according to RFC 3986. This does not include the percent 
sign (%), which is
+     * actually allowed but only as an escape character for percent-encoded 
characters.
+     */
+    private static final Pattern URI_FRAGMENT_DISALLOWED_CHARACTERS = Pattern
+            .compile("[^\\p{Alnum}._~!$&'()*+,;=:@/?-]");
+
+    /**
      * Splits apart the input String on any whitespace and/or commas. Leading 
and trailing
      * whitespace are ignored. If a null String is provided as input a zero 
length array
      * will be returned.
@@ -84,4 +93,38 @@
             throw new StripesRuntimeException("Unsupported encoding?  UTF-8?  
That's unpossible.");
         }
     }
+
+    /**
+     * Encode a URI fragment as required by RFC 3986. The fragment is allowed 
to contain a different
+     * set of characters than other parts of the URI, and characters that are 
allowed in the
+     * fragment must not be encoded.
+     * 
+     * @param value The string to encode
+     * @return The encoded string
+     */
+    public static String uriFragmentEncode(String value) {
+        Matcher matcher = URI_FRAGMENT_DISALLOWED_CHARACTERS.matcher(value);
+
+        StringBuilder buf = null;
+        int end = 0;
+        while (matcher.find()) {
+            if (buf == null) {
+                buf = new StringBuilder(value.length() * 2);
+            }
+
+            buf.append(value.substring(end, matcher.start())).append(
+                    String.format("%%%02X", (int) matcher.group().charAt(0)));
+            end = matcher.end();
+        }
+
+        // No match, return input unchanged
+        if (buf == null)
+            return value;
+
+        // Append tail
+        if (end < value.length())
+            buf.append(value.substring(end));
+
+        return buf.toString();
+    }
 }

Modified: 
branches/1.5.x/stripes/src/net/sourceforge/stripes/util/UrlBuilder.java
===================================================================
--- branches/1.5.x/stripes/src/net/sourceforge/stripes/util/UrlBuilder.java     
2009-10-16 17:53:35 UTC (rev 1167)
+++ branches/1.5.x/stripes/src/net/sourceforge/stripes/util/UrlBuilder.java     
2009-10-16 20:18:51 UTC (rev 1168)
@@ -303,7 +303,7 @@
             url = build();
         }
         if (this.anchor != null && this.anchor.length() > 0) {
-            return url + "#" + this.anchor;
+            return url + "#" + StringUtil.uriFragmentEncode(this.anchor);
         }
         else {
             return url;


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to