You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@velocity.apache.org by nb...@apache.org on 2009/05/11 22:31:31 UTC
svn commit: r773678 - in /velocity/tools/trunk/src:
main/java/org/apache/velocity/tools/generic/LinkTool.java
test/java/org/apache/velocity/tools/LinkToolTests.java
Author: nbubna
Date: Mon May 11 20:31:31 2009
New Revision: 773678
URL: http://svn.apache.org/viewvc?rev=773678&view=rev
Log:
fix double escaping of query strings
Modified:
velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/LinkTool.java
velocity/tools/trunk/src/test/java/org/apache/velocity/tools/LinkToolTests.java
Modified: velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/LinkTool.java
URL: http://svn.apache.org/viewvc/velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/LinkTool.java?rev=773678&r1=773677&r2=773678&view=diff
==============================================================================
--- velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/LinkTool.java (original)
+++ velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/LinkTool.java Mon May 11 20:31:31 2009
@@ -1618,7 +1618,80 @@
{
return null;
}
- return uri.toString();
+ return decodeQueryPercents(uri.toString());
+ }
+
+ /**
+ * This is an ugly (but fast) hack that's needed because URI encodes
+ * things that we don't need encoded while not encoding things
+ * that we do need encoded. So, we have to encode query data
+ * before creating the URI to ensure they are properly encoded,
+ * but then URI encodes all the % from that encoding. Here,
+ * we isolate the query data and manually decode the encoded
+ * %25 in that section back to %, without decoding anything else.
+ */
+ protected String decodeQueryPercents(String url)
+ {
+ StringBuilder out = new StringBuilder(url.length());
+ boolean inQuery = false, havePercent = false, haveTwo = false;
+ for (int i=0; i<url.length(); i++)
+ {
+ char c = url.charAt(i);
+ if (inQuery)
+ {
+ if (havePercent)
+ {
+ if (haveTwo)
+ {
+ out.append('%');
+ if (c != '5')
+ {
+ out.append('2').append(c);
+ }
+ havePercent = haveTwo = false;
+ }
+ else if (c == '2')
+ {
+ haveTwo = true;
+ }
+ else
+ {
+ out.append('%').append(c);
+ havePercent = false;
+ }
+ }
+ else if (c == '%')
+ {
+ havePercent = true;
+ }
+ else
+ {
+ out.append(c);
+ }
+ if (c == '#')
+ {
+ inQuery = false;
+ }
+ }
+ else
+ {
+ out.append(c);
+ if (c == '?')
+ {
+ inQuery = true;
+ }
+ }
+ }
+ // if things ended part way
+ if (havePercent)
+ {
+ out.append('%');
+ if (haveTwo)
+ {
+ out.append('2');
+ }
+ }
+ return out.toString();
}
/**
Modified: velocity/tools/trunk/src/test/java/org/apache/velocity/tools/LinkToolTests.java
URL: http://svn.apache.org/viewvc/velocity/tools/trunk/src/test/java/org/apache/velocity/tools/LinkToolTests.java?rev=773678&r1=773677&r2=773678&view=diff
==============================================================================
--- velocity/tools/trunk/src/test/java/org/apache/velocity/tools/LinkToolTests.java (original)
+++ velocity/tools/trunk/src/test/java/org/apache/velocity/tools/LinkToolTests.java Mon May 11 20:31:31 2009
@@ -633,6 +633,8 @@
assertEquals("x=1", link.toQuery('x', 1));
assertEquals("true=false", link.toQuery(true, false));
assertEquals("path=%2Ffoo+bar%2Fnew", link.toQuery("path", "/foo bar/new"));
+ // try all URI reserved chars
+ assertEquals("x=%2C%3B%3A%24%26%2B%3D%3F%2F%5B%5D%40", link.toQuery('x', ",;:$&+=?/[]@"));
}
public @Test void methodSetParam_ObjectObjectboolean() throws Exception
@@ -830,5 +832,17 @@
assertEquals("#42", link.anchor(42).toString());
}
+ public @Test void methodNoDoubleEncode() throws Exception
+ {
+ LinkTool link = newInstance().relative("/foo");
+ assertEquals("/foo", link.toString());
+ link = link.param("q","a:b c");
+ assertEquals("/foo?q=a%3Ab+c", link.toString());
+ link = link.anchor("a(b, c)");
+ assertEquals("/foo?q=a%3Ab+c#a(b,%20c)", link.toString());
+ link = link.param("evil","%25%24%").anchor(null);
+ assertEquals("/foo?q=a%3Ab+c&evil=%2525%2524%25", link.toString());
+ }
+
}
\ No newline at end of file