1 /* 2 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 @bug 4922813 26 @summary Check the new impl of encodePath will not cause regression 27 */ 28 29 import java.util.BitSet; 30 import java.io.File; 31 import java.util.Random; 32 import sun.net.www.ParseUtil; 33 34 public class ParseUtil_4922813 { 35 public static void main(String[] argv) throws Exception { 36 37 int num = 400; 38 while (num-- >= 0) { 39 String source = getTestSource(); 40 String ec = sun.net.www.ParseUtil.encodePath(source); 41 String v117 = ParseUtil_V117.encodePath(source); 42 if (!ec.equals(v117)) { 43 throw new RuntimeException("Test Failed for : \n" 44 + " source =<" 45 + getUnicodeString(source) 46 + ">"); 47 } 48 49 } 50 } 51 52 static int maxCharCount = 200; 53 static int maxCodePoint = 0x10ffff; 54 static Random random; 55 static String getTestSource() { 56 if (random == null) { 57 long seed = System.currentTimeMillis(); 58 random = new Random(seed); 59 } 60 String source = ""; 61 int i = 0; 62 int count = random.nextInt(maxCharCount) + 1; 63 while (i < count) { 64 int codepoint = random.nextInt(127); 65 source = source + String.valueOf((char)codepoint); 66 67 codepoint = random.nextInt(0x7ff); 68 source = source + String.valueOf((char)codepoint); 69 70 codepoint = random.nextInt(maxCodePoint); 71 source = source + new String(Character.toChars(codepoint)); 72 73 i += 3; 74 } 75 return source; 76 } 77 78 static String getUnicodeString(String s){ 79 String unicodeString = ""; 80 for(int j=0; j< s.length(); j++){ 81 unicodeString += "0x"+ Integer.toString(s.charAt(j), 16); 82 } 83 return unicodeString; 84 } 85 } 86 class ParseUtil_V117 { 87 static BitSet encodedInPath; 88 static { 89 encodedInPath = new BitSet(256); 90 91 // Set the bits corresponding to characters that are encoded in the 92 // path component of a URI. 93 94 // These characters are reserved in the path segment as described in 95 // RFC2396 section 3.3. 96 encodedInPath.set('='); 97 encodedInPath.set(';'); 98 encodedInPath.set('?'); 99 encodedInPath.set('/'); 100 101 // These characters are defined as excluded in RFC2396 section 2.4.3 102 // and must be escaped if they occur in the data part of a URI. 103 encodedInPath.set('#'); 104 encodedInPath.set(' '); 105 encodedInPath.set('<'); 106 encodedInPath.set('>'); 107 encodedInPath.set('%'); 108 encodedInPath.set('"'); 109 encodedInPath.set('{'); 110 encodedInPath.set('}'); 111 encodedInPath.set('|'); 112 encodedInPath.set('\\'); 113 encodedInPath.set('^'); 114 encodedInPath.set('['); 115 encodedInPath.set(']'); 116 encodedInPath.set('`'); 117 118 // US ASCII control characters 00-1F and 7F. 119 for (int i=0; i<32; i++) 120 encodedInPath.set(i); 121 encodedInPath.set(127); 122 } 123 /** 124 * Constructs an encoded version of the specified path string suitable 125 * for use in the construction of a URL. 126 * 127 * A path separator is replaced by a forward slash. The string is UTF8 128 * encoded. The % escape sequence is used for characters that are above 129 * 0x7F or those defined in RFC2396 as reserved or excluded in the path 130 * component of a URL. 131 */ 132 public static String encodePath(String path) { 133 StringBuffer sb = new StringBuffer(); 134 int n = path.length(); 135 for (int i=0; i<n; i++) { 136 char c = path.charAt(i); 137 if (c == File.separatorChar) 138 sb.append('/'); 139 else { 140 if (c <= 0x007F) { 141 if (encodedInPath.get(c)) 142 escape(sb, c); 143 else 144 sb.append(c); 145 } else if (c > 0x07FF) { 146 escape(sb, (char)(0xE0 | ((c >> 12) & 0x0F))); 147 escape(sb, (char)(0x80 | ((c >> 6) & 0x3F))); 148 escape(sb, (char)(0x80 | ((c >> 0) & 0x3F))); 149 } else { 150 escape(sb, (char)(0xC0 | ((c >> 6) & 0x1F))); 151 escape(sb, (char)(0x80 | ((c >> 0) & 0x3F))); 152 } 153 } 154 } 155 return sb.toString(); 156 } 157 158 /** 159 * Appends the URL escape sequence for the specified char to the 160 * specified StringBuffer. 161 */ 162 private static void escape(StringBuffer s, char c) { 163 s.append('%'); 164 s.append(Character.forDigit((c >> 4) & 0xF, 16)); 165 s.append(Character.forDigit(c & 0xF, 16)); 166 } 167 }