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.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "prio.h"
7 #include "prsystem.h"
9 #include "TestHarness.h"
11 #include "nsIFile.h"
12 #include "nsDirectoryServiceDefs.h"
13 #include "nsDirectoryServiceUtils.h"
15 static const char* gFunction = "main";
17 static bool VerifyResult(nsresult aRV, const char* aMsg)
18 {
19 if (NS_FAILED(aRV)) {
20 fail("%s %s, rv=%x", gFunction, aMsg, aRV);
21 return false;
22 }
23 return true;
24 }
26 static already_AddRefed<nsIFile> NewFile(nsIFile* aBase)
27 {
28 nsresult rv;
29 nsCOMPtr<nsIFile> file =
30 do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
31 VerifyResult(rv, "Creating nsIFile");
32 rv = file->InitWithFile(aBase);
33 VerifyResult(rv, "InitWithFile");
34 return file.forget();
35 }
37 static nsCString FixName(const char* aName)
38 {
39 nsCString name;
40 for (uint32_t i = 0; aName[i]; ++i) {
41 char ch = aName[i];
42 // PR_GetPathSeparator returns the wrong value on Mac so don't use it
43 #if defined(XP_WIN)
44 if (ch == '/') {
45 ch = '\\';
46 }
47 #endif
48 name.Append(ch);
49 }
50 return name;
51 }
53 // Test nsIFile::AppendNative, verifying that aName is not a valid file name
54 static bool TestInvalidFileName(nsIFile* aBase, const char* aName)
55 {
56 gFunction = "TestInvalidFileName";
57 nsCOMPtr<nsIFile> file = NewFile(aBase);
58 if (!file)
59 return false;
61 nsCString name = FixName(aName);
62 nsresult rv = file->AppendNative(name);
63 if (NS_SUCCEEDED(rv)) {
64 fail("%s AppendNative with invalid filename %s", gFunction, name.get());
65 return false;
66 }
68 return true;
69 }
71 // Test nsIFile::Create, verifying that the file exists and did not exist before,
72 // and leaving it there for future tests
73 static bool TestCreate(nsIFile* aBase, const char* aName, int32_t aType, int32_t aPerm)
74 {
75 gFunction = "TestCreate";
76 nsCOMPtr<nsIFile> file = NewFile(aBase);
77 if (!file)
78 return false;
80 nsCString name = FixName(aName);
81 nsresult rv = file->AppendNative(name);
82 if (!VerifyResult(rv, "AppendNative"))
83 return false;
85 bool exists;
86 rv = file->Exists(&exists);
87 if (!VerifyResult(rv, "Exists (before)"))
88 return false;
89 if (exists) {
90 fail("%s File %s already exists", gFunction, name.get());
91 return false;
92 }
94 rv = file->Create(aType, aPerm);
95 if (!VerifyResult(rv, "Create"))
96 return false;
98 rv = file->Exists(&exists);
99 if (!VerifyResult(rv, "Exists (after)"))
100 return false;
101 if (!exists) {
102 fail("%s File %s was not created", gFunction, name.get());
103 return false;
104 }
106 return true;
107 }
109 // Test nsIFile::CreateUnique, verifying that the new file exists and if it existed before,
110 // the new file has a different name.
111 // The new file is left in place.
112 static bool TestCreateUnique(nsIFile* aBase, const char* aName, int32_t aType, int32_t aPerm)
113 {
114 gFunction = "TestCreateUnique";
115 nsCOMPtr<nsIFile> file = NewFile(aBase);
116 if (!file)
117 return false;
119 nsCString name = FixName(aName);
120 nsresult rv = file->AppendNative(name);
121 if (!VerifyResult(rv, "AppendNative"))
122 return false;
124 bool existsBefore;
125 rv = file->Exists(&existsBefore);
126 if (!VerifyResult(rv, "Exists (before)"))
127 return false;
129 rv = file->CreateUnique(aType, aPerm);
130 if (!VerifyResult(rv, "Create"))
131 return false;
133 bool existsAfter;
134 rv = file->Exists(&existsAfter);
135 if (!VerifyResult(rv, "Exists (after)"))
136 return false;
137 if (!existsAfter) {
138 fail("%s File %s was not created", gFunction, name.get());
139 return false;
140 }
142 if (existsBefore) {
143 nsAutoCString leafName;
144 rv = file->GetNativeLeafName(leafName);
145 if (!VerifyResult(rv, "GetNativeLeafName"))
146 return false;
147 if (leafName.Equals(name)) {
148 fail("%s File %s was not given a new name by CreateUnique", gFunction, name.get());
149 return false;
150 }
151 }
153 return true;
154 }
156 // Test nsIFile::OpenNSPRFileDesc with DELETE_ON_CLOSE, verifying that the file exists
157 // and did not exist before, and leaving it there for future tests
158 static bool TestDeleteOnClose(nsIFile* aBase, const char* aName, int32_t aFlags, int32_t aPerm)
159 {
160 gFunction = "TestDeleteOnClose";
161 nsCOMPtr<nsIFile> file = NewFile(aBase);
162 if (!file)
163 return false;
165 nsCString name = FixName(aName);
166 nsresult rv = file->AppendNative(name);
167 if (!VerifyResult(rv, "AppendNative"))
168 return false;
170 bool exists;
171 rv = file->Exists(&exists);
172 if (!VerifyResult(rv, "Exists (before)"))
173 return false;
174 if (exists) {
175 fail("%s File %s already exists", gFunction, name.get());
176 return false;
177 }
179 PRFileDesc* fileDesc;
180 rv = file->OpenNSPRFileDesc(aFlags | nsIFile::DELETE_ON_CLOSE, aPerm, &fileDesc);
181 if (!VerifyResult(rv, "OpenNSPRFileDesc"))
182 return false;
183 PRStatus status = PR_Close(fileDesc);
184 if (status != PR_SUCCESS) {
185 fail("%s File %s could not be closed", gFunction, name.get());
186 return false;
187 }
189 rv = file->Exists(&exists);
190 if (!VerifyResult(rv, "Exists (after)"))
191 return false;
192 if (exists) {
193 fail("%s File %s was not removed on close!", gFunction, name.get());
194 return false;
195 }
197 return true;
198 }
200 // Test nsIFile::Remove, verifying that the file does not exist and did before
201 static bool TestRemove(nsIFile* aBase, const char* aName, bool aRecursive)
202 {
203 gFunction = "TestDelete";
204 nsCOMPtr<nsIFile> file = NewFile(aBase);
205 if (!file)
206 return false;
208 nsCString name = FixName(aName);
209 nsresult rv = file->AppendNative(name);
210 if (!VerifyResult(rv, "AppendNative"))
211 return false;
213 bool exists;
214 rv = file->Exists(&exists);
215 if (!VerifyResult(rv, "Exists (before)"))
216 return false;
217 if (!exists) {
218 fail("%s File %s does not exist", gFunction, name.get());
219 return false;
220 }
222 rv = file->Remove(aRecursive);
223 if (!VerifyResult(rv, "Remove"))
224 return false;
226 rv = file->Exists(&exists);
227 if (!VerifyResult(rv, "Exists (after)"))
228 return false;
229 if (exists) {
230 fail("%s File %s was not removed", gFunction, name.get());
231 return false;
232 }
234 return true;
235 }
237 // Test nsIFile::MoveToNative, verifying that the file did not exist at the new location
238 // before and does afterward, and that it does not exist at the old location anymore
239 static bool TestMove(nsIFile* aBase, nsIFile* aDestDir, const char* aName, const char* aNewName)
240 {
241 gFunction = "TestMove";
242 nsCOMPtr<nsIFile> file = NewFile(aBase);
243 if (!file)
244 return false;
246 nsCString name = FixName(aName);
247 nsresult rv = file->AppendNative(name);
248 if (!VerifyResult(rv, "AppendNative"))
249 return false;
251 bool exists;
252 rv = file->Exists(&exists);
253 if (!VerifyResult(rv, "Exists (before)"))
254 return false;
255 if (!exists) {
256 fail("%s File %s does not exist", gFunction, name.get());
257 return false;
258 }
260 nsCOMPtr<nsIFile> newFile = NewFile(file);
261 nsCString newName = FixName(aNewName);
262 rv = newFile->MoveToNative(aDestDir, newName);
263 if (!VerifyResult(rv, "MoveToNative"))
264 return false;
266 rv = file->Exists(&exists);
267 if (!VerifyResult(rv, "Exists (after)"))
268 return false;
269 if (exists) {
270 fail("%s File %s was not moved", gFunction, name.get());
271 return false;
272 }
274 file = NewFile(aDestDir);
275 if (!file)
276 return false;
277 rv = file->AppendNative(newName);
278 if (!VerifyResult(rv, "AppendNative"))
279 return false;
280 bool equal;
281 rv = file->Equals(newFile, &equal);
282 if (!VerifyResult(rv, "Equals"))
283 return false;
284 if (!equal) {
285 fail("%s file object was not updated to destination", gFunction);
286 return false;
287 }
289 rv = file->Exists(&exists);
290 if (!VerifyResult(rv, "Exists (new after)"))
291 return false;
292 if (!exists) {
293 fail("%s Destination file %s was not created", gFunction, newName.get());
294 return false;
295 }
297 return true;
298 }
300 // Test nsIFile::CopyToNative, verifying that the file did not exist at the new location
301 // before and does afterward, and that it does exist at the old location too
302 static bool TestCopy(nsIFile* aBase, nsIFile* aDestDir, const char* aName, const char* aNewName)
303 {
304 gFunction = "TestCopy";
305 nsCOMPtr<nsIFile> file = NewFile(aBase);
306 if (!file)
307 return false;
309 nsCString name = FixName(aName);
310 nsresult rv = file->AppendNative(name);
311 if (!VerifyResult(rv, "AppendNative"))
312 return false;
314 bool exists;
315 rv = file->Exists(&exists);
316 if (!VerifyResult(rv, "Exists (before)"))
317 return false;
318 if (!exists) {
319 fail("%s File %s does not exist", gFunction, name.get());
320 return false;
321 }
323 nsCOMPtr<nsIFile> newFile = NewFile(file);
324 nsCString newName = FixName(aNewName);
325 rv = newFile->CopyToNative(aDestDir, newName);
326 if (!VerifyResult(rv, "MoveToNative"))
327 return false;
328 bool equal;
329 rv = file->Equals(newFile, &equal);
330 if (!VerifyResult(rv, "Equals"))
331 return false;
332 if (!equal) {
333 fail("%s file object updated unexpectedly", gFunction);
334 return false;
335 }
337 rv = file->Exists(&exists);
338 if (!VerifyResult(rv, "Exists (after)"))
339 return false;
340 if (!exists) {
341 fail("%s File %s was removed", gFunction, name.get());
342 return false;
343 }
345 file = NewFile(aDestDir);
346 if (!file)
347 return false;
348 rv = file->AppendNative(newName);
349 if (!VerifyResult(rv, "AppendNative"))
350 return false;
352 rv = file->Exists(&exists);
353 if (!VerifyResult(rv, "Exists (new after)"))
354 return false;
355 if (!exists) {
356 fail("%s Destination file %s was not created", gFunction, newName.get());
357 return false;
358 }
360 return true;
361 }
363 // Test nsIFile::GetParent
364 static bool TestParent(nsIFile* aBase, nsIFile* aStart)
365 {
366 gFunction = "TestParent";
367 nsCOMPtr<nsIFile> file = NewFile(aStart);
368 if (!file)
369 return false;
371 nsCOMPtr<nsIFile> parent;
372 nsresult rv = file->GetParent(getter_AddRefs(parent));
373 VerifyResult(rv, "GetParent");
375 bool equal;
376 rv = parent->Equals(aBase, &equal);
377 VerifyResult(rv, "Equals");
378 if (!equal) {
379 fail("%s Incorrect parent", gFunction);
380 return false;
381 }
383 return true;
384 }
386 // Test nsIFile::Normalize and native path setting/getting
387 static bool TestNormalizeNativePath(nsIFile* aBase, nsIFile* aStart)
388 {
389 gFunction = "TestNormalizeNativePath";
390 nsCOMPtr<nsIFile> file = NewFile(aStart);
391 if (!file)
392 return false;
394 nsAutoCString path;
395 nsresult rv = file->GetNativePath(path);
396 VerifyResult(rv, "GetNativePath");
397 path.Append(FixName("/./.."));
398 rv = file->InitWithNativePath(path);
399 VerifyResult(rv, "InitWithNativePath");
400 rv = file->Normalize();
401 VerifyResult(rv, "Normalize");
402 rv = file->GetNativePath(path);
403 VerifyResult(rv, "GetNativePath (after normalization)");
405 nsAutoCString basePath;
406 rv = aBase->GetNativePath(basePath);
407 VerifyResult(rv, "GetNativePath (base)");
409 if (!path.Equals(basePath)) {
410 fail("%s Incorrect normalization");
411 return false;
412 }
414 return true;
415 }
417 int main(int argc, char** argv)
418 {
419 ScopedXPCOM xpcom("nsLocalFile");
420 if (xpcom.failed())
421 return 1;
423 nsCOMPtr<nsIFile> base;
424 nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(base));
425 if (!VerifyResult(rv, "Getting temp directory"))
426 return 1;
427 rv = base->AppendNative(nsDependentCString("mozfiletests"));
428 if (!VerifyResult(rv, "Appending mozfiletests to temp directory name"))
429 return 1;
430 // Remove the directory in case tests failed and left it behind.
431 // don't check result since it might not be there
432 base->Remove(true);
434 // Now create the working directory we're going to use
435 rv = base->Create(nsIFile::DIRECTORY_TYPE, 0700);
436 if (!VerifyResult(rv, "Creating temp directory"))
437 return 1;
438 // Now we can safely normalize the path
439 rv = base->Normalize();
440 if (!VerifyResult(rv, "Normalizing temp directory name"))
441 return 1;
443 // Initialize subdir object for later use
444 nsCOMPtr<nsIFile> subdir = NewFile(base);
445 if (!subdir)
446 return 1;
447 rv = subdir->AppendNative(nsDependentCString("subdir"));
448 if (!VerifyResult(rv, "Appending 'subdir' to test dir name"))
449 return 1;
451 passed("Setup");
453 // Test path parsing
454 if (TestInvalidFileName(base, "a/b")) {
455 passed("AppendNative with invalid file name");
456 }
457 if (TestParent(base, subdir)) {
458 passed("GetParent");
459 }
461 // Test file creation
462 if (TestCreate(base, "file.txt", nsIFile::NORMAL_FILE_TYPE, 0600)) {
463 passed("Create file");
464 }
465 if (TestRemove(base, "file.txt", false)) {
466 passed("Remove file");
467 }
469 // Test directory creation
470 if (TestCreate(base, "subdir", nsIFile::DIRECTORY_TYPE, 0700)) {
471 passed("Create directory");
472 }
474 // Test move and copy in the base directory
475 if (TestCreate(base, "file.txt", nsIFile::NORMAL_FILE_TYPE, 0600) &&
476 TestMove(base, base, "file.txt", "file2.txt")) {
477 passed("MoveTo rename file");
478 }
479 if (TestCopy(base, base, "file2.txt", "file3.txt")) {
480 passed("CopyTo copy file");
481 }
482 // Test moving across directories
483 if (TestMove(base, subdir, "file2.txt", "file2.txt")) {
484 passed("MoveTo move file");
485 }
486 // Test moving across directories and renaming at the same time
487 if (TestMove(subdir, base, "file2.txt", "file4.txt")) {
488 passed("MoveTo move and rename file");
489 }
490 // Test copying across directoreis
491 if (TestCopy(base, subdir, "file4.txt", "file5.txt")) {
492 passed("CopyTo copy file across directories");
493 }
495 // Run normalization tests while the directory exists
496 if (TestNormalizeNativePath(base, subdir)) {
497 passed("Normalize with native paths");
498 }
500 // Test recursive directory removal
501 if (TestRemove(base, "subdir", true)) {
502 passed("Remove directory");
503 }
505 if (TestCreateUnique(base, "foo", nsIFile::NORMAL_FILE_TYPE, 0600) &&
506 TestCreateUnique(base, "foo", nsIFile::NORMAL_FILE_TYPE, 0600)) {
507 passed("CreateUnique file");
508 }
509 if (TestCreateUnique(base, "bar.xx", nsIFile::DIRECTORY_TYPE, 0700) &&
510 TestCreateUnique(base, "bar.xx", nsIFile::DIRECTORY_TYPE, 0700)) {
511 passed("CreateUnique directory");
512 }
514 if (TestDeleteOnClose(base, "file7.txt", PR_RDWR | PR_CREATE_FILE, 0600)) {
515 passed("OpenNSPRFileDesc DELETE_ON_CLOSE");
516 }
518 gFunction = "main";
519 // Clean up temporary stuff
520 rv = base->Remove(true);
521 VerifyResult(rv, "Cleaning up temp directory");
523 return gFailCount > 0;
524 }