1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.cts; 18 19 import java.util.List; 20 import java.util.Set; 21 import android.net.UrlQuerySanitizer; 22 import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; 23 import android.net.UrlQuerySanitizer.ParameterValuePair; 24 import android.net.UrlQuerySanitizer.ValueSanitizer; 25 import android.test.AndroidTestCase; 26 import dalvik.annotation.TestLevel; 27 import dalvik.annotation.TestTargetClass; 28 import dalvik.annotation.TestTargetNew; 29 import dalvik.annotation.TestTargets; 30 31 @TestTargetClass(UrlQuerySanitizer.class) 32 public class UrlQuerySanitizerTest extends AndroidTestCase { 33 private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK; 34 35 // URL for test. 36 private static final String TEST_URL = "http://example.com/?name=Joe+User&age=20&height=175"; 37 38 // Default sanitizer's change when "+". 39 private static final String EXPECTED_UNDERLINE_NAME = "Joe_User"; 40 41 // IllegalCharacterValueSanitizer sanitizer's change when "+". 42 private static final String EXPECTED_SPACE_NAME = "Joe User"; 43 private static final String EXPECTED_AGE = "20"; 44 private static final String EXPECTED_HEIGHT = "175"; 45 private static final String NAME = "name"; 46 private static final String AGE = "age"; 47 private static final String HEIGHT = "height"; 48 49 @TestTargets({ 50 @TestTargetNew( 51 level = TestLevel.COMPLETE, 52 method = "UrlQuerySanitizer", 53 args = {} 54 ), 55 @TestTargetNew( 56 level = TestLevel.COMPLETE, 57 method = "UrlQuerySanitizer", 58 args = {String.class} 59 ), 60 @TestTargetNew( 61 level = TestLevel.COMPLETE, 62 method = "parseUrl", 63 args = {String.class} 64 ), 65 @TestTargetNew( 66 level = TestLevel.COMPLETE, 67 method = "parseQuery", 68 args = {String.class} 69 ), 70 @TestTargetNew( 71 level = TestLevel.COMPLETE, 72 method = "parseEntry", 73 args = {String.class, String.class} 74 ), 75 @TestTargetNew( 76 level = TestLevel.COMPLETE, 77 method = "getValue", 78 args = {String.class} 79 ), 80 @TestTargetNew( 81 level = TestLevel.COMPLETE, 82 method = "addSanitizedEntry", 83 args = {String.class, String.class} 84 ), 85 @TestTargetNew( 86 level = TestLevel.COMPLETE, 87 method = "hasParameter", 88 args = {String.class} 89 ), 90 @TestTargetNew( 91 level = TestLevel.COMPLETE, 92 method = "getParameterSet", 93 args = {} 94 ), 95 @TestTargetNew( 96 level = TestLevel.COMPLETE, 97 method = "getParameterList", 98 args = {} 99 ), 100 @TestTargetNew( 101 level = TestLevel.COMPLETE, 102 method = "setUnregisteredParameterValueSanitizer", 103 args = {ValueSanitizer.class} 104 ), 105 @TestTargetNew( 106 level = TestLevel.COMPLETE, 107 method = "getUnregisteredParameterValueSanitizer", 108 args = {} 109 ), 110 @TestTargetNew( 111 level = TestLevel.COMPLETE, 112 method = "getAllButNulAndAngleBracketsLegal", 113 args = {} 114 ), 115 @TestTargetNew( 116 level = TestLevel.COMPLETE, 117 method = "getAllButNulLegal", 118 args = {} 119 ), 120 @TestTargetNew( 121 level = TestLevel.COMPLETE, 122 method = "getAllButWhitespaceLegal", 123 args = {} 124 ), 125 @TestTargetNew( 126 level = TestLevel.COMPLETE, 127 method = "getAllIllegal", 128 args = {} 129 ), 130 @TestTargetNew( 131 level = TestLevel.COMPLETE, 132 method = "getAmpAndSpaceLegal", 133 args = {} 134 ), 135 @TestTargetNew( 136 level = TestLevel.COMPLETE, 137 method = "getAmpLegal", 138 args = {} 139 ), 140 @TestTargetNew( 141 level = TestLevel.COMPLETE, 142 method = "getSpaceLegal", 143 args = {} 144 ), 145 @TestTargetNew( 146 level = TestLevel.COMPLETE, 147 method = "getUrlAndSpaceLegal", 148 args = {} 149 ), 150 @TestTargetNew( 151 level = TestLevel.COMPLETE, 152 method = "getUrlLegal", 153 args = {} 154 ), 155 @TestTargetNew( 156 level = TestLevel.COMPLETE, 157 method = "unescape", 158 args = {String.class} 159 ), 160 @TestTargetNew( 161 level = TestLevel.COMPLETE, 162 method = "isHexDigit", 163 args = {char.class} 164 ), 165 @TestTargetNew( 166 level = TestLevel.COMPLETE, 167 method = "decodeHexDigit", 168 args = {char.class} 169 ), 170 @TestTargetNew( 171 level = TestLevel.COMPLETE, 172 method = "setAllowUnregisteredParamaters", 173 args = {boolean.class} 174 ), 175 @TestTargetNew( 176 level = TestLevel.COMPLETE, 177 method = "getAllowUnregisteredParamaters", 178 args = {} 179 ), 180 @TestTargetNew( 181 level = TestLevel.COMPLETE, 182 method = "registerParameter", 183 args = {String.class, ValueSanitizer.class} 184 ), 185 @TestTargetNew( 186 level = TestLevel.COMPLETE, 187 method = "registerParameters", 188 args = {String[].class, ValueSanitizer.class} 189 ), 190 @TestTargetNew( 191 level = TestLevel.COMPLETE, 192 method = "getEffectiveValueSanitizer", 193 args = {String.class} 194 ), 195 @TestTargetNew( 196 level = TestLevel.COMPLETE, 197 method = "getValueSanitizer", 198 args = {String.class} 199 ), 200 @TestTargetNew( 201 level = TestLevel.COMPLETE, 202 method = "clear", 203 args = {} 204 ), 205 @TestTargetNew( 206 level = TestLevel.COMPLETE, 207 method = "setPreferFirstRepeatedParameter", 208 args = {boolean.class} 209 ), 210 @TestTargetNew( 211 level = TestLevel.COMPLETE, 212 method = "getPreferFirstRepeatedParameter", 213 args = {} 214 ) 215 }) 216 public void testUrlQuerySanitizer() { 217 MockUrlQuerySanitizer uqs = new MockUrlQuerySanitizer(); 218 assertFalse(uqs.getAllowUnregisteredParamaters()); 219 220 final String query = "book=thinking in java&price=108"; 221 final String book = "book"; 222 final String bookName = "thinking in java"; 223 final String price = "price"; 224 final String bookPrice = "108"; 225 final String notExistPar = "notExistParameter"; 226 uqs.registerParameters(new String[]{book, price}, UrlQuerySanitizer.getSpaceLegal()); 227 uqs.parseQuery(query); 228 assertTrue(uqs.hasParameter(book)); 229 assertTrue(uqs.hasParameter(price)); 230 assertFalse(uqs.hasParameter(notExistPar)); 231 assertEquals(bookName, uqs.getValue(book)); 232 assertEquals(bookPrice, uqs.getValue(price)); 233 assertNull(uqs.getValue(notExistPar)); 234 uqs.clear(); 235 assertFalse(uqs.hasParameter(book)); 236 assertFalse(uqs.hasParameter(price)); 237 238 uqs.parseEntry(book, bookName); 239 assertTrue(uqs.hasParameter(book)); 240 assertEquals(bookName, uqs.getValue(book)); 241 uqs.parseEntry(price, bookPrice); 242 assertTrue(uqs.hasParameter(price)); 243 assertEquals(bookPrice, uqs.getValue(price)); 244 assertFalse(uqs.hasParameter(notExistPar)); 245 assertNull(uqs.getValue(notExistPar)); 246 247 uqs = new MockUrlQuerySanitizer(TEST_URL); 248 assertTrue(uqs.getAllowUnregisteredParamaters()); 249 250 assertTrue(uqs.hasParameter(NAME)); 251 assertTrue(uqs.hasParameter(AGE)); 252 assertTrue(uqs.hasParameter(HEIGHT)); 253 assertFalse(uqs.hasParameter(notExistPar)); 254 255 assertEquals(EXPECTED_UNDERLINE_NAME, uqs.getValue(NAME)); 256 assertEquals(EXPECTED_AGE, uqs.getValue(AGE)); 257 assertEquals(EXPECTED_HEIGHT, uqs.getValue(HEIGHT)); 258 assertNull(uqs.getValue(notExistPar)); 259 260 final int ContainerLen = 3; 261 Set<String> urlSet = uqs.getParameterSet(); 262 assertEquals(ContainerLen, urlSet.size()); 263 assertTrue(urlSet.contains(NAME)); 264 assertTrue(urlSet.contains(AGE)); 265 assertTrue(urlSet.contains(HEIGHT)); 266 assertFalse(urlSet.contains(notExistPar)); 267 268 List<ParameterValuePair> urlList = uqs.getParameterList(); 269 assertEquals(ContainerLen, urlList.size()); 270 ParameterValuePair pvp = urlList.get(0); 271 assertEquals(NAME, pvp.mParameter); 272 assertEquals(EXPECTED_UNDERLINE_NAME, pvp.mValue); 273 pvp = urlList.get(1); 274 assertEquals(AGE, pvp.mParameter); 275 assertEquals(EXPECTED_AGE, pvp.mValue); 276 pvp = urlList.get(2); 277 assertEquals(HEIGHT, pvp.mParameter); 278 assertEquals(EXPECTED_HEIGHT, pvp.mValue); 279 280 assertFalse(uqs.getPreferFirstRepeatedParameter()); 281 uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT + 1); 282 assertEquals(ContainerLen, urlSet.size()); 283 assertEquals(ContainerLen + 1, urlList.size()); 284 assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT)); 285 286 uqs.setPreferFirstRepeatedParameter(true); 287 assertTrue(uqs.getPreferFirstRepeatedParameter()); 288 uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT); 289 assertEquals(ContainerLen, urlSet.size()); 290 assertEquals(ContainerLen + 2, urlList.size()); 291 assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT)); 292 293 uqs.registerParameter(NAME, null); 294 assertNull(uqs.getValueSanitizer(NAME)); 295 assertNotNull(uqs.getEffectiveValueSanitizer(NAME)); 296 297 uqs.setAllowUnregisteredParamaters(false); 298 assertFalse(uqs.getAllowUnregisteredParamaters()); 299 uqs.registerParameter(NAME, null); 300 assertNull(uqs.getEffectiveValueSanitizer(NAME)); 301 302 ValueSanitizer vs = new IllegalCharacterValueSanitizer(ALL_OK); 303 uqs.registerParameter(NAME, vs); 304 uqs.parseUrl(TEST_URL); 305 assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME)); 306 assertNotSame(EXPECTED_AGE, uqs.getValue(AGE)); 307 308 String[] register = {NAME, AGE}; 309 uqs.registerParameters(register, vs); 310 uqs.parseUrl(TEST_URL); 311 assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME)); 312 assertEquals(EXPECTED_AGE, uqs.getValue(AGE)); 313 assertNotSame(EXPECTED_HEIGHT, uqs.getValue(HEIGHT)); 314 315 uqs.setUnregisteredParameterValueSanitizer(vs); 316 assertEquals(vs, uqs.getUnregisteredParameterValueSanitizer()); 317 318 vs = UrlQuerySanitizer.getAllIllegal(); 319 assertEquals("Joe_User", vs.sanitize("Joe<User")); 320 vs = UrlQuerySanitizer.getAllButNulAndAngleBracketsLegal(); 321 assertEquals("Joe User", vs.sanitize("Joe<>\0User")); 322 vs = UrlQuerySanitizer.getAllButNulLegal(); 323 assertEquals("Joe User", vs.sanitize("Joe\0User")); 324 vs = UrlQuerySanitizer.getAllButWhitespaceLegal(); 325 assertEquals("Joe_User", vs.sanitize("Joe User")); 326 vs = UrlQuerySanitizer.getAmpAndSpaceLegal(); 327 assertEquals("Joe User&", vs.sanitize("Joe User&")); 328 vs = UrlQuerySanitizer.getAmpLegal(); 329 assertEquals("Joe_User&", vs.sanitize("Joe User&")); 330 vs = UrlQuerySanitizer.getSpaceLegal(); 331 assertEquals("Joe User ", vs.sanitize("Joe User&")); 332 vs = UrlQuerySanitizer.getUrlAndSpaceLegal(); 333 assertEquals("Joe User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'")); 334 vs = UrlQuerySanitizer.getUrlLegal(); 335 assertEquals("Joe_User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'")); 336 337 String escape = "Joe"; 338 assertEquals(escape, uqs.unescape(escape)); 339 String expectedPlus = "Joe User"; 340 String expectedPercentSignHex = "title=" + Character.toString((char)181); 341 String initialPlus = "Joe+User"; 342 String initialPercentSign = "title=%B5"; 343 assertEquals(expectedPlus, uqs.unescape(initialPlus)); 344 assertEquals(expectedPercentSignHex, uqs.unescape(initialPercentSign)); 345 346 assertTrue(uqs.decodeHexDigit('0') >= 0); 347 assertTrue(uqs.decodeHexDigit('b') >= 0); 348 assertTrue(uqs.decodeHexDigit('F') >= 0); 349 assertTrue(uqs.decodeHexDigit('$') < 0); 350 351 assertTrue(uqs.isHexDigit('0')); 352 assertTrue(uqs.isHexDigit('b')); 353 assertTrue(uqs.isHexDigit('F')); 354 assertFalse(uqs.isHexDigit('$')); 355 356 uqs.clear(); 357 assertEquals(0, urlSet.size()); 358 assertEquals(0, urlList.size()); 359 360 uqs.setPreferFirstRepeatedParameter(true); 361 assertTrue(uqs.getPreferFirstRepeatedParameter()); 362 uqs.setPreferFirstRepeatedParameter(false); 363 assertFalse(uqs.getPreferFirstRepeatedParameter()); 364 365 UrlQuerySanitizer uq = new UrlQuerySanitizer(); 366 uq.setPreferFirstRepeatedParameter(true); 367 final String PARA_ANSWER = "answer"; 368 uq.registerParameter(PARA_ANSWER, new MockValueSanitizer()); 369 uq.parseUrl("http://www.google.com/question?answer=13&answer=42"); 370 assertEquals("13", uq.getValue(PARA_ANSWER)); 371 372 uq.setPreferFirstRepeatedParameter(false); 373 uq.parseQuery("http://www.google.com/question?answer=13&answer=42"); 374 assertEquals("42", uq.getValue(PARA_ANSWER)); 375 376 } 377 378 private static class MockValueSanitizer implements ValueSanitizer{ 379 380 public String sanitize(String value) { 381 return value; 382 } 383 } 384 385 class MockUrlQuerySanitizer extends UrlQuerySanitizer { 386 public MockUrlQuerySanitizer() { 387 super(); 388 } 389 390 public MockUrlQuerySanitizer(String url) { 391 super(url); 392 } 393 394 @Override 395 protected void addSanitizedEntry(String parameter, String value) { 396 super.addSanitizedEntry(parameter, value); 397 } 398 399 @Override 400 protected void clear() { 401 super.clear(); 402 } 403 404 @Override 405 protected int decodeHexDigit(char c) { 406 return super.decodeHexDigit(c); 407 } 408 409 @Override 410 protected boolean isHexDigit(char c) { 411 return super.isHexDigit(c); 412 } 413 414 @Override 415 protected void parseEntry(String parameter, String value) { 416 super.parseEntry(parameter, value); 417 } 418 } 419 } 420