/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package freenet.support; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import freenet.test.*; import junit.framework.TestCase; /** * Test case for {@link freenet.support.URLEncoder} and * {@link freenet.support.URLDecoder} classes. * * @author Alberto Bacchelli <sback@freenetproject.org> */ public class URLEncoderDecoderTest extends TestCase { public static final String prtblAscii = new String(UTFUtil.PRINTABLE_ASCII); public static final String stressedUTF_8Chars = new String(UTFUtil.STRESSED_UTF); public static final String allCharsExceptNull = new String(UTFUtil.ALL_CHARACTERS).replace("\u0000", ""); public static final String allChars = new String(UTFUtil.ALL_CHARACTERS); /** * Encodes a string of ALL unicode characters except the 0-character and tests whether it is decoded correctly. */ public void testEncodeDecodeString_allChars() throws URLEncodedFormatException { assertTrue(areCorrectlyEncodedDecoded(new String[] { allCharsExceptNull }, true)); assertTrue(areCorrectlyEncodedDecoded(new String[] { allCharsExceptNull }, false)); } /** * Tests if URLEncode.encode(String) and * URLDecode.decode(String,boolean) methods * work correctly together, both with safe * characters and not safe "base" (i.e. ASCII) chars . */ public void testEncodeDecodeString_notSafeBaseChars() { String[] toEncode = { //safe chars URLEncoder.safeURLCharacters, prtblAscii, //triple % char, if badly encoded it will generate an exception "%%%", //no chars ""}; try { assertTrue(areCorrectlyEncodedDecoded(toEncode, true)); assertTrue(areCorrectlyEncodedDecoded(toEncode, false)); } catch (URLEncodedFormatException anException) { fail("Not expected exception thrown : " + anException.getMessage()); } } /** * Tests if URLEncode.encode(String) and * URLDecode.decode(String,boolean) methods * work correctly together, both with safe * characters and not safe "advanced" (i.e. not ASCII) chars . */ public void testEncodeDecodeString_notSafeAdvChars() { String[] toEncode = {stressedUTF_8Chars}; try { assertTrue(areCorrectlyEncodedDecoded(toEncode, true)); assertTrue(areCorrectlyEncodedDecoded(toEncode, false)); } catch (URLEncodedFormatException anException) { fail("Not expected exception thrown : " + anException.getMessage()); } } /** * Verifies if a string is the same after * being processed by encoding and * decoding methods * @param toEncode String to Encode * @return true means to be tolerant of bogus escapes * @throws URLEncodedFormatException */ private boolean areCorrectlyEncodedDecoded(String[] toEncode, boolean withLetters) throws URLEncodedFormatException { String[] encoded = new String[toEncode.length]; //encoding for (int i = 0; i < encoded.length; i++) encoded[i] = URLEncoder.encode(toEncode[i],withLetters); //decoding for (int i = 0; i < encoded.length; i++) { final String orig = toEncode[i]; final String coded = encoded[i]; final String decoded = URLDecoder.decode(coded,withLetters); if(orig.equals(decoded) == false) { for(int c = 0; c < orig.length(); ++c) { final char origChar = orig.charAt(c); final char decodedChar = decoded.charAt(c); if(c > decoded.length() || origChar != decodedChar) return false; // Set your debugger breakpoint here } return false; } } return true; } /** * Tests encode(String,String,boolean) method * to verify if the force parameter is * well-managed for each safeURLCharacter, * with both true and false ascii-flag. */ public void testEncodeForced() { String toEncode,expectedResult; char eachChar; for(int i=0; i<URLEncoder.safeURLCharacters.length(); i++) { eachChar = URLEncoder.safeURLCharacters.charAt(i); toEncode = String.valueOf(eachChar); try { expectedResult = "%"+ HexUtil.bytesToHex( //since safe chars are only US-ASCII toEncode.getBytes("US-ASCII")); assertEquals(URLEncoder.encode(toEncode,toEncode,false), expectedResult); assertEquals(URLEncoder.encode(toEncode,toEncode,true), expectedResult); } catch (UnsupportedEncodingException anException) { fail("Not expected exception thrown : " + anException.getMessage()); } } } /** * Verifies if a URLEncodedFormatException is raised * when decoding the provided String * @param toDecode the String to decode * @param tolerant whether the decoding should be tolerant with * @return */ private boolean isDecodeRaisingEncodedException(String toDecode, boolean tolerant) { boolean retValue = false; try { System.out.println(URLDecoder.decode(toDecode,false)); } catch (URLEncodedFormatException anException) { retValue = true; } return retValue; } /** * Tests decode(String,boolean) method * using not valid encoded String to * verifies if it raises an exception */ public void testDecodeWrongString() { String toDecode = "%00"; assertTrue(isDecodeRaisingEncodedException(toDecode,false)); } /** * Tests decode(String,boolean) method * using not valid hex values String to * verifies if it raises an exception */ public void testDecodeWrongHex() { String toDecode = "123456789abcde"+prtblAscii+stressedUTF_8Chars; for (int i = 0; i<toDecode.length(); i++) assertTrue( isDecodeRaisingEncodedException("%"+toDecode.substring(i,i+1),false)); } /** * Tests decode(String,boolean) method * trying the boolean argument, to verify * if it work correctly as a hack to allow users * to paste in URLs containing %'s. */ public void testTolerantDecoding() { String toDecode = "%%%"; try { assertEquals(URLDecoder.decode(toDecode,true),toDecode); } catch (URLEncodedFormatException anException) { fail("Not expected exception thrown : " + anException.getMessage()); } } /** * Tests whether all URL-encoded characters are acceptable to the java.net.URI constructor. */ public void testEncodedUsableInURI() { try { new URI("#" + URLEncoder.encode(allChars, false)); } catch (URISyntaxException e) { fail("URLEncoder output rejected by URI constructor"); } } }