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: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "TestHarness.h"
9 #include <windows.h>
10 #include <winnetwk.h>
12 #include "mozilla/FileUtilsWin.h"
13 #include "mozilla/DebugOnly.h"
14 #include "nsCRTGlue.h"
16 class DriveMapping
17 {
18 public:
19 DriveMapping(const nsAString& aRemoteUNCPath);
20 ~DriveMapping();
22 bool
23 Init();
24 bool
25 ChangeDriveLetter();
26 wchar_t
27 GetDriveLetter() { return mDriveLetter; }
29 private:
30 bool
31 DoMapping();
32 void
33 Disconnect(wchar_t aDriveLetter);
35 wchar_t mDriveLetter;
36 nsString mRemoteUNCPath;
37 };
39 DriveMapping::DriveMapping(const nsAString& aRemoteUNCPath)
40 : mDriveLetter(0)
41 , mRemoteUNCPath(aRemoteUNCPath)
42 {
43 }
45 bool
46 DriveMapping::Init()
47 {
48 if (mDriveLetter) {
49 return false;
50 }
51 return DoMapping();
52 }
54 bool
55 DriveMapping::DoMapping()
56 {
57 wchar_t drvTemplate[] = L" :";
58 NETRESOURCEW netRes = {0};
59 netRes.dwType = RESOURCETYPE_DISK;
60 netRes.lpLocalName = drvTemplate;
61 netRes.lpRemoteName = reinterpret_cast<wchar_t*>(mRemoteUNCPath.BeginWriting());
62 wchar_t driveLetter = L'D';
63 DWORD result = NO_ERROR;
64 do {
65 drvTemplate[0] = driveLetter;
66 result = WNetAddConnection2W(&netRes, nullptr, nullptr, CONNECT_TEMPORARY);
67 } while (result == ERROR_ALREADY_ASSIGNED && ++driveLetter <= L'Z');
68 if (result != NO_ERROR) {
69 return false;
70 }
71 mDriveLetter = driveLetter;
72 return true;
73 }
75 bool
76 DriveMapping::ChangeDriveLetter()
77 {
78 wchar_t prevDriveLetter = mDriveLetter;
79 bool result = DoMapping();
80 MOZ_ASSERT(mDriveLetter != prevDriveLetter);
81 if (result && prevDriveLetter) {
82 Disconnect(prevDriveLetter);
83 }
84 return result;
85 }
87 void
88 DriveMapping::Disconnect(wchar_t aDriveLetter)
89 {
90 wchar_t drvTemplate[] = {aDriveLetter, L':', L'\0'};
91 mozilla::DebugOnly<DWORD> result = WNetCancelConnection2W(drvTemplate, 0, TRUE);
92 MOZ_ASSERT(result == NO_ERROR);
93 }
95 DriveMapping::~DriveMapping()
96 {
97 if (mDriveLetter) {
98 Disconnect(mDriveLetter);
99 }
100 }
102 bool
103 DriveToNtPath(const wchar_t aDriveLetter, nsAString& aNtPath)
104 {
105 const wchar_t drvTpl[] = {aDriveLetter, L':', L'\0'};
106 aNtPath.SetLength(MAX_PATH);
107 DWORD pathLen;
108 while (true) {
109 pathLen = QueryDosDeviceW(drvTpl, reinterpret_cast<wchar_t*>(aNtPath.BeginWriting()), aNtPath.Length());
110 if (pathLen || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
111 break;
112 }
113 aNtPath.SetLength(aNtPath.Length() * 2);
114 }
115 if (!pathLen) {
116 return false;
117 }
118 // aNtPath contains embedded NULLs, so we need to figure out the real length
119 // via wcslen.
120 aNtPath.SetLength(NS_strlen(aNtPath.BeginReading()));
121 return true;
122 }
124 bool
125 TestNtPathToDosPath(const wchar_t* aNtPath,
126 const wchar_t* aExpectedDosPath)
127 {
128 nsAutoString output;
129 bool result = mozilla::NtPathToDosPath(nsDependentString(aNtPath), output);
130 return result && output == aExpectedDosPath;
131 }
133 int main(int argc, char* argv[])
134 {
135 ScopedXPCOM xpcom("NtPathToDosPath");
136 if (xpcom.failed()) {
137 fail("XPCOM Startup");
138 return 1;
139 }
140 nsAutoString cDrive;
141 if (!DriveToNtPath(L'C', cDrive)) {
142 fail("Querying for this machine's C:");
143 return 1;
144 }
146 int result = 0;
148 // empty string
149 if (!TestNtPathToDosPath(L"", L"")) {
150 fail("Empty string");
151 result = 1;
152 }
153 // non-existent device, must fail
154 if (TestNtPathToDosPath(L"\\Device\\ThisDeviceDoesNotExist\\Foo", nullptr)) {
155 fail("Non-existent device");
156 result = 1;
157 }
158 // base case
159 nsAutoString testPath(cDrive);
160 testPath.Append(L"\\Foo");
161 if (!TestNtPathToDosPath(testPath.get(), L"C:\\Foo")) {
162 fail("Base case");
163 result = 1;
164 }
165 // drive letters as symbolic links (NtCreateFile uses these)
166 if (!TestNtPathToDosPath(L"\\??\\C:\\Foo", L"C:\\Foo")) {
167 fail("Path specified as symbolic link");
168 result = 1;
169 }
170 // other symbolic links (should fail)
171 if (TestNtPathToDosPath(L"\\??\\MountPointManager", nullptr)) {
172 fail("Other symbolic link");
173 result = 1;
174 }
175 // socket (should fail)
176 if (TestNtPathToDosPath(L"\\Device\\Afd\\Endpoint", nullptr)) {
177 fail("Socket");
178 result = 1;
179 }
180 // currently UNC paths that are not mapped to drive letters are unsupported,
181 // so this should fail
182 if (TestNtPathToDosPath(L"\\Device\\Mup\\127.0.0.1\\C$", nullptr)) {
183 fail("Unmapped UNC path");
184 result = 1;
185 }
186 DriveMapping drvMapping(NS_LITERAL_STRING("\\\\127.0.0.1\\C$"));
187 // Only run these tests if we were able to map; some machines don't have perms
188 if (drvMapping.Init()) {
189 wchar_t expected[] = L" :\\";
190 expected[0] = drvMapping.GetDriveLetter();
191 nsAutoString networkPath;
192 if (!DriveToNtPath(drvMapping.GetDriveLetter(), networkPath)) {
193 fail("Querying network drive");
194 return 1;
195 }
196 networkPath += MOZ_UTF16("\\");
197 if (!TestNtPathToDosPath(networkPath.get(), expected)) {
198 fail("Mapped UNC path");
199 result = 1;
200 }
201 // NtPathToDosPath must correctly handle paths whose drive letter mapping has
202 // changed. We need to test this because the APIs called by NtPathToDosPath
203 // return different info if this has happened.
204 if (!drvMapping.ChangeDriveLetter()) {
205 fail("Change drive letter");
206 return 1;
207 }
208 expected[0] = drvMapping.GetDriveLetter();
209 if (!DriveToNtPath(drvMapping.GetDriveLetter(), networkPath)) {
210 fail("Querying second network drive");
211 return 1;
212 }
213 networkPath += MOZ_UTF16("\\");
214 if (!TestNtPathToDosPath(networkPath.get(), expected)) {
215 fail("Re-mapped UNC path");
216 result = 1;
217 }
218 }
220 return result;
221 }