Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | #include <stdio.h> |
michael@0 | 6 | #include <ctype.h> |
michael@0 | 7 | #include "nsEscape.h" |
michael@0 | 8 | #include "nsString.h" |
michael@0 | 9 | #include "nsUrlClassifierUtils.h" |
michael@0 | 10 | #include "nsNetUtil.h" |
michael@0 | 11 | #include "stdlib.h" |
michael@0 | 12 | #include "TestHarness.h" |
michael@0 | 13 | |
michael@0 | 14 | static int gTotalTests = 0; |
michael@0 | 15 | static int gPassedTests = 0; |
michael@0 | 16 | |
michael@0 | 17 | static char int_to_hex_digit(int32_t i) { |
michael@0 | 18 | NS_ASSERTION((i >= 0) && (i <= 15), "int too big in int_to_hex_digit"); |
michael@0 | 19 | return static_cast<char>(((i < 10) ? (i + '0') : ((i - 10) + 'A'))); |
michael@0 | 20 | } |
michael@0 | 21 | |
michael@0 | 22 | static void CheckEquals(nsCString & expected, nsCString & actual) |
michael@0 | 23 | { |
michael@0 | 24 | if (!(expected).Equals((actual))) { |
michael@0 | 25 | fail("expected |%s| but got |%s|", (expected).get(), (actual).get()); |
michael@0 | 26 | } else { |
michael@0 | 27 | gPassedTests++; |
michael@0 | 28 | } |
michael@0 | 29 | gTotalTests++; |
michael@0 | 30 | } |
michael@0 | 31 | |
michael@0 | 32 | void TestUnescapeHelper(const char* in, const char* expected) |
michael@0 | 33 | { |
michael@0 | 34 | nsCString out, strIn(in), strExp(expected); |
michael@0 | 35 | nsUrlClassifierUtils utils; |
michael@0 | 36 | |
michael@0 | 37 | NS_UnescapeURL(strIn.get(), strIn.Length(), esc_AlwaysCopy, out); |
michael@0 | 38 | CheckEquals(strExp, out); |
michael@0 | 39 | } |
michael@0 | 40 | |
michael@0 | 41 | // Make sure Unescape from nsEncode.h's unescape does what the server does. |
michael@0 | 42 | void TestUnescape() |
michael@0 | 43 | { |
michael@0 | 44 | // test empty string |
michael@0 | 45 | TestUnescapeHelper("\0", "\0"); |
michael@0 | 46 | |
michael@0 | 47 | // Test docoding of all characters. |
michael@0 | 48 | nsCString allCharsEncoded, allCharsEncodedLowercase, allCharsAsString; |
michael@0 | 49 | for (int32_t i = 1; i < 256; ++i) { |
michael@0 | 50 | allCharsEncoded.Append('%'); |
michael@0 | 51 | allCharsEncoded.Append(int_to_hex_digit(i / 16)); |
michael@0 | 52 | allCharsEncoded.Append((int_to_hex_digit(i % 16))); |
michael@0 | 53 | |
michael@0 | 54 | allCharsEncodedLowercase.Append('%'); |
michael@0 | 55 | allCharsEncodedLowercase.Append(tolower(int_to_hex_digit(i / 16))); |
michael@0 | 56 | allCharsEncodedLowercase.Append(tolower(int_to_hex_digit(i % 16))); |
michael@0 | 57 | |
michael@0 | 58 | allCharsAsString.Append(static_cast<char>(i)); |
michael@0 | 59 | } |
michael@0 | 60 | |
michael@0 | 61 | nsUrlClassifierUtils utils; |
michael@0 | 62 | nsCString out; |
michael@0 | 63 | NS_UnescapeURL(allCharsEncoded.get(), allCharsEncoded.Length(), esc_AlwaysCopy, out); |
michael@0 | 64 | CheckEquals(allCharsAsString, out); |
michael@0 | 65 | |
michael@0 | 66 | out.Truncate(); |
michael@0 | 67 | NS_UnescapeURL(allCharsEncodedLowercase.get(), allCharsEncodedLowercase.Length(), esc_AlwaysCopy, out); |
michael@0 | 68 | CheckEquals(allCharsAsString, out); |
michael@0 | 69 | |
michael@0 | 70 | // Test %-related edge cases |
michael@0 | 71 | TestUnescapeHelper("%", "%"); |
michael@0 | 72 | TestUnescapeHelper("%xx", "%xx"); |
michael@0 | 73 | TestUnescapeHelper("%%", "%%"); |
michael@0 | 74 | TestUnescapeHelper("%%%", "%%%"); |
michael@0 | 75 | TestUnescapeHelper("%%%%", "%%%%"); |
michael@0 | 76 | TestUnescapeHelper("%1", "%1"); |
michael@0 | 77 | TestUnescapeHelper("%1z", "%1z"); |
michael@0 | 78 | TestUnescapeHelper("a%1z", "a%1z"); |
michael@0 | 79 | TestUnescapeHelper("abc%d%e%fg%hij%klmno%", "abc%d%e%fg%hij%klmno%"); |
michael@0 | 80 | |
michael@0 | 81 | // A few more tests |
michael@0 | 82 | TestUnescapeHelper("%25", "%"); |
michael@0 | 83 | TestUnescapeHelper("%25%32%35", "%25"); |
michael@0 | 84 | } |
michael@0 | 85 | |
michael@0 | 86 | void TestEncodeHelper(const char* in, const char* expected) |
michael@0 | 87 | { |
michael@0 | 88 | nsCString out, strIn(in), strExp(expected); |
michael@0 | 89 | nsUrlClassifierUtils utils; |
michael@0 | 90 | |
michael@0 | 91 | utils.SpecialEncode(strIn, true, out); |
michael@0 | 92 | CheckEquals(strExp, out); |
michael@0 | 93 | } |
michael@0 | 94 | |
michael@0 | 95 | void TestEnc() |
michael@0 | 96 | { |
michael@0 | 97 | // Test empty string |
michael@0 | 98 | TestEncodeHelper("", ""); |
michael@0 | 99 | |
michael@0 | 100 | // Test that all characters we shouldn't encode ([33-36],[38,126]) are not. |
michael@0 | 101 | nsCString noenc; |
michael@0 | 102 | for (int32_t i = 33; i < 127; i++) { |
michael@0 | 103 | if (i != 37) { // skip % |
michael@0 | 104 | noenc.Append(static_cast<char>(i)); |
michael@0 | 105 | } |
michael@0 | 106 | } |
michael@0 | 107 | nsUrlClassifierUtils utils; |
michael@0 | 108 | nsCString out; |
michael@0 | 109 | utils.SpecialEncode(noenc, false, out); |
michael@0 | 110 | CheckEquals(noenc, out); |
michael@0 | 111 | |
michael@0 | 112 | // Test that all the chars that we should encode [0,32],37,[127,255] are |
michael@0 | 113 | nsCString yesAsString, yesExpectedString; |
michael@0 | 114 | for (int32_t i = 1; i < 256; i++) { |
michael@0 | 115 | if (i < 33 || i == 37 || i > 126) { |
michael@0 | 116 | yesAsString.Append(static_cast<char>(i)); |
michael@0 | 117 | yesExpectedString.Append('%'); |
michael@0 | 118 | yesExpectedString.Append(int_to_hex_digit(i / 16)); |
michael@0 | 119 | yesExpectedString.Append(int_to_hex_digit(i % 16)); |
michael@0 | 120 | } |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | out.Truncate(); |
michael@0 | 124 | utils.SpecialEncode(yesAsString, false, out); |
michael@0 | 125 | CheckEquals(yesExpectedString, out); |
michael@0 | 126 | |
michael@0 | 127 | TestEncodeHelper("blah//blah", "blah/blah"); |
michael@0 | 128 | } |
michael@0 | 129 | |
michael@0 | 130 | void TestCanonicalizeHelper(const char* in, const char* expected) |
michael@0 | 131 | { |
michael@0 | 132 | nsCString out, strIn(in), strExp(expected); |
michael@0 | 133 | nsUrlClassifierUtils utils; |
michael@0 | 134 | |
michael@0 | 135 | utils.CanonicalizePath(strIn, out); |
michael@0 | 136 | CheckEquals(strExp, out); |
michael@0 | 137 | } |
michael@0 | 138 | |
michael@0 | 139 | void TestCanonicalize() |
michael@0 | 140 | { |
michael@0 | 141 | // Test repeated %-decoding. Note: %25 --> %, %32 --> 2, %35 --> 5 |
michael@0 | 142 | TestCanonicalizeHelper("%25", "%25"); |
michael@0 | 143 | TestCanonicalizeHelper("%25%32%35", "%25"); |
michael@0 | 144 | TestCanonicalizeHelper("asdf%25%32%35asd", "asdf%25asd"); |
michael@0 | 145 | TestCanonicalizeHelper("%%%25%32%35asd%%", "%25%25%25asd%25%25"); |
michael@0 | 146 | TestCanonicalizeHelper("%25%32%35%25%32%35%25%32%35", "%25%25%25"); |
michael@0 | 147 | TestCanonicalizeHelper("%25", "%25"); |
michael@0 | 148 | TestCanonicalizeHelper("%257Ea%2521b%2540c%2523d%2524e%25f%255E00%252611%252A22%252833%252944_55%252B", |
michael@0 | 149 | "~a!b@c#d$e%25f^00&11*22(33)44_55+"); |
michael@0 | 150 | |
michael@0 | 151 | TestCanonicalizeHelper("", ""); |
michael@0 | 152 | TestCanonicalizeHelper("%31%36%38%2e%31%38%38%2e%39%39%2e%32%36/%2E%73%65%63%75%72%65/%77%77%77%2E%65%62%61%79%2E%63%6F%6D/", |
michael@0 | 153 | "168.188.99.26/.secure/www.ebay.com/"); |
michael@0 | 154 | TestCanonicalizeHelper("195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/", |
michael@0 | 155 | "195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/"); |
michael@0 | 156 | // Added in bug 489455. %00 should no longer be changed to %01. |
michael@0 | 157 | TestCanonicalizeHelper("%00", "%00"); |
michael@0 | 158 | } |
michael@0 | 159 | |
michael@0 | 160 | void TestParseIPAddressHelper(const char *in, const char *expected) |
michael@0 | 161 | { |
michael@0 | 162 | nsCString out, strIn(in), strExp(expected); |
michael@0 | 163 | nsUrlClassifierUtils utils; |
michael@0 | 164 | utils.Init(); |
michael@0 | 165 | |
michael@0 | 166 | utils.ParseIPAddress(strIn, out); |
michael@0 | 167 | CheckEquals(strExp, out); |
michael@0 | 168 | } |
michael@0 | 169 | |
michael@0 | 170 | void TestParseIPAddress() |
michael@0 | 171 | { |
michael@0 | 172 | TestParseIPAddressHelper("123.123.0.0.1", ""); |
michael@0 | 173 | TestParseIPAddressHelper("255.0.0.1", "255.0.0.1"); |
michael@0 | 174 | TestParseIPAddressHelper("12.0x12.01234", "12.18.2.156"); |
michael@0 | 175 | TestParseIPAddressHelper("276.2.3", "20.2.0.3"); |
michael@0 | 176 | TestParseIPAddressHelper("012.034.01.055", "10.28.1.45"); |
michael@0 | 177 | TestParseIPAddressHelper("0x12.0x43.0x44.0x01", "18.67.68.1"); |
michael@0 | 178 | TestParseIPAddressHelper("167838211", "10.1.2.3"); |
michael@0 | 179 | TestParseIPAddressHelper("3279880203", "195.127.0.11"); |
michael@0 | 180 | TestParseIPAddressHelper("0x12434401", "18.67.68.1"); |
michael@0 | 181 | TestParseIPAddressHelper("413960661", "24.172.137.213"); |
michael@0 | 182 | TestParseIPAddressHelper("03053104725", "24.172.137.213"); |
michael@0 | 183 | TestParseIPAddressHelper("030.0254.0x89d5", "24.172.137.213"); |
michael@0 | 184 | TestParseIPAddressHelper("1.234.4.0377", "1.234.4.255"); |
michael@0 | 185 | TestParseIPAddressHelper("1.2.3.00x0", ""); |
michael@0 | 186 | TestParseIPAddressHelper("10.192.95.89 xy", "10.192.95.89"); |
michael@0 | 187 | TestParseIPAddressHelper("10.192.95.89 xyz", ""); |
michael@0 | 188 | TestParseIPAddressHelper("1.2.3.0x0", "1.2.3.0"); |
michael@0 | 189 | TestParseIPAddressHelper("1.2.3.4", "1.2.3.4"); |
michael@0 | 190 | } |
michael@0 | 191 | |
michael@0 | 192 | void TestCanonicalNumHelper(const char *in, uint32_t bytes, |
michael@0 | 193 | bool allowOctal, const char *expected) |
michael@0 | 194 | { |
michael@0 | 195 | nsCString out, strIn(in), strExp(expected); |
michael@0 | 196 | nsUrlClassifierUtils utils; |
michael@0 | 197 | utils.Init(); |
michael@0 | 198 | |
michael@0 | 199 | utils.CanonicalNum(strIn, bytes, allowOctal, out); |
michael@0 | 200 | CheckEquals(strExp, out); |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | void TestCanonicalNum() |
michael@0 | 204 | { |
michael@0 | 205 | TestCanonicalNumHelper("", 1, true, ""); |
michael@0 | 206 | TestCanonicalNumHelper("10", 0, true, ""); |
michael@0 | 207 | TestCanonicalNumHelper("45", 1, true, "45"); |
michael@0 | 208 | TestCanonicalNumHelper("0x10", 1, true, "16"); |
michael@0 | 209 | TestCanonicalNumHelper("367", 2, true, "1.111"); |
michael@0 | 210 | TestCanonicalNumHelper("012345", 3, true, "0.20.229"); |
michael@0 | 211 | TestCanonicalNumHelper("0173", 1, true, "123"); |
michael@0 | 212 | TestCanonicalNumHelper("09", 1, false, "9"); |
michael@0 | 213 | TestCanonicalNumHelper("0x120x34", 2, true, ""); |
michael@0 | 214 | TestCanonicalNumHelper("0x12fc", 2, true, "18.252"); |
michael@0 | 215 | TestCanonicalNumHelper("3279880203", 4, true, "195.127.0.11"); |
michael@0 | 216 | TestCanonicalNumHelper("0x0000059", 1, true, "89"); |
michael@0 | 217 | TestCanonicalNumHelper("0x00000059", 1, true, "89"); |
michael@0 | 218 | TestCanonicalNumHelper("0x0000067", 1, true, "103"); |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | void TestHostnameHelper(const char *in, const char *expected) |
michael@0 | 222 | { |
michael@0 | 223 | nsCString out, strIn(in), strExp(expected); |
michael@0 | 224 | nsUrlClassifierUtils utils; |
michael@0 | 225 | utils.Init(); |
michael@0 | 226 | |
michael@0 | 227 | utils.CanonicalizeHostname(strIn, out); |
michael@0 | 228 | CheckEquals(strExp, out); |
michael@0 | 229 | } |
michael@0 | 230 | |
michael@0 | 231 | void TestHostname() |
michael@0 | 232 | { |
michael@0 | 233 | TestHostnameHelper("abcd123;[]", "abcd123;[]"); |
michael@0 | 234 | TestHostnameHelper("abc.123", "abc.123"); |
michael@0 | 235 | TestHostnameHelper("abc..123", "abc.123"); |
michael@0 | 236 | TestHostnameHelper("trailing.", "trailing"); |
michael@0 | 237 | TestHostnameHelper("i love trailing dots....", "i%20love%20trailing%20dots"); |
michael@0 | 238 | TestHostnameHelper(".leading", "leading"); |
michael@0 | 239 | TestHostnameHelper("..leading", "leading"); |
michael@0 | 240 | TestHostnameHelper(".dots.", "dots"); |
michael@0 | 241 | TestHostnameHelper(".both.", "both"); |
michael@0 | 242 | TestHostnameHelper(".both..", "both"); |
michael@0 | 243 | TestHostnameHelper("..both.", "both"); |
michael@0 | 244 | TestHostnameHelper("..both..", "both"); |
michael@0 | 245 | TestHostnameHelper("..a.b.c.d..", "a.b.c.d"); |
michael@0 | 246 | TestHostnameHelper("..127.0.0.1..", "127.0.0.1"); |
michael@0 | 247 | TestHostnameHelper("asdf!@#$a", "asdf!@#$a"); |
michael@0 | 248 | TestHostnameHelper("AB CD 12354", "ab%20cd%2012354"); |
michael@0 | 249 | TestHostnameHelper("\1\2\3\4\112\177", "%01%02%03%04j%7F"); |
michael@0 | 250 | TestHostnameHelper("<>.AS/-+", "<>.as/-+"); |
michael@0 | 251 | // Added in bug 489455. %00 should no longer be changed to %01. |
michael@0 | 252 | TestHostnameHelper("%00", "%00"); |
michael@0 | 253 | } |
michael@0 | 254 | |
michael@0 | 255 | void TestLongHostname() |
michael@0 | 256 | { |
michael@0 | 257 | static const int kTestSize = 1024 * 150; |
michael@0 | 258 | char *str = static_cast<char*>(malloc(kTestSize + 1)); |
michael@0 | 259 | memset(str, 'x', kTestSize); |
michael@0 | 260 | str[kTestSize] = '\0'; |
michael@0 | 261 | |
michael@0 | 262 | nsUrlClassifierUtils utils; |
michael@0 | 263 | utils.Init(); |
michael@0 | 264 | |
michael@0 | 265 | nsAutoCString out; |
michael@0 | 266 | nsDependentCString in(str); |
michael@0 | 267 | PRIntervalTime clockStart = PR_IntervalNow(); |
michael@0 | 268 | utils.CanonicalizeHostname(in, out); |
michael@0 | 269 | PRIntervalTime clockEnd = PR_IntervalNow(); |
michael@0 | 270 | |
michael@0 | 271 | CheckEquals(in, out); |
michael@0 | 272 | |
michael@0 | 273 | printf("CanonicalizeHostname on long string (%dms)\n", |
michael@0 | 274 | PR_IntervalToMilliseconds(clockEnd - clockStart)); |
michael@0 | 275 | } |
michael@0 | 276 | |
michael@0 | 277 | void TestFragmentSet() |
michael@0 | 278 | { |
michael@0 | 279 | nsUrlClassifierFragmentSet set; |
michael@0 | 280 | set.Init(3); |
michael@0 | 281 | |
michael@0 | 282 | set.Put(NS_LITERAL_CSTRING("a")); |
michael@0 | 283 | set.Put(NS_LITERAL_CSTRING("b")); |
michael@0 | 284 | set.Put(NS_LITERAL_CSTRING("c")); |
michael@0 | 285 | |
michael@0 | 286 | // At this point, adding a fourth element would push "a" off. |
michael@0 | 287 | // Make sure that set.Has("a") moves it to the front of the list |
michael@0 | 288 | set.Has(NS_LITERAL_CSTRING("a")); |
michael@0 | 289 | |
michael@0 | 290 | // Now add a new item. This should now push "b" off the list, |
michael@0 | 291 | // but leave "a" |
michael@0 | 292 | set.Put(NS_LITERAL_CSTRING("d")); |
michael@0 | 293 | |
michael@0 | 294 | gTotalTests++; |
michael@0 | 295 | if (set.Has(NS_LITERAL_CSTRING("a"))) |
michael@0 | 296 | gPassedTests++; |
michael@0 | 297 | else |
michael@0 | 298 | fail("set.Has(\"a\") failed."); |
michael@0 | 299 | |
michael@0 | 300 | gTotalTests++; |
michael@0 | 301 | if (!set.Has(NS_LITERAL_CSTRING("b"))) |
michael@0 | 302 | gPassedTests++; |
michael@0 | 303 | else |
michael@0 | 304 | fail("!set.Has(\"b\") failed."); |
michael@0 | 305 | } |
michael@0 | 306 | |
michael@0 | 307 | int main(int argc, char **argv) |
michael@0 | 308 | { |
michael@0 | 309 | ScopedXPCOM xpcom("URLClassiferUtils"); |
michael@0 | 310 | |
michael@0 | 311 | TestUnescape(); |
michael@0 | 312 | TestEnc(); |
michael@0 | 313 | TestCanonicalize(); |
michael@0 | 314 | TestCanonicalNum(); |
michael@0 | 315 | TestParseIPAddress(); |
michael@0 | 316 | TestHostname(); |
michael@0 | 317 | TestLongHostname(); |
michael@0 | 318 | TestFragmentSet(); |
michael@0 | 319 | |
michael@0 | 320 | if (gPassedTests == gTotalTests) |
michael@0 | 321 | passed(__FILE__); |
michael@0 | 322 | printf("%d of %d tests passed\n", gPassedTests, gTotalTests); |
michael@0 | 323 | // Non-zero return status signals test failure to build system. |
michael@0 | 324 | |
michael@0 | 325 | return (gPassedTests != gTotalTests); |
michael@0 | 326 | } |