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 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "IOInterposer.h"
6 #include "NSPRInterposer.h"
8 #include "prio.h"
9 #include "private/pprio.h"
11 namespace {
13 using namespace mozilla;
15 /* Original IO methods */
16 PRCloseFN sCloseFn = nullptr;
17 PRReadFN sReadFn = nullptr;
18 PRWriteFN sWriteFn = nullptr;
19 PRFsyncFN sFSyncFn = nullptr;
20 PRFileInfoFN sFileInfoFn = nullptr;
21 PRFileInfo64FN sFileInfo64Fn = nullptr;
23 /**
24 * RAII class for timing the duration of an NSPR I/O call and reporting the
25 * result to the IOInterposeObserver API.
26 */
27 class NSPRIOAutoObservation : public IOInterposeObserver::Observation
28 {
29 public:
30 NSPRIOAutoObservation(IOInterposeObserver::Operation aOp)
31 : IOInterposeObserver::Observation(aOp, "NSPRIOInterposer")
32 {
33 }
35 ~NSPRIOAutoObservation()
36 {
37 Report();
38 }
39 };
41 PRStatus PR_CALLBACK interposedClose(PRFileDesc* aFd)
42 {
43 // If we don't have a valid original function pointer something is very wrong.
44 NS_ASSERTION(sCloseFn, "NSPR IO Interposing: sCloseFn is NULL");
46 NSPRIOAutoObservation timer(IOInterposeObserver::OpClose);
47 return sCloseFn(aFd);
48 }
50 int32_t PR_CALLBACK interposedRead(PRFileDesc* aFd, void* aBuf, int32_t aAmt)
51 {
52 // If we don't have a valid original function pointer something is very wrong.
53 NS_ASSERTION(sReadFn, "NSPR IO Interposing: sReadFn is NULL");
55 NSPRIOAutoObservation timer(IOInterposeObserver::OpRead);
56 return sReadFn(aFd, aBuf, aAmt);
57 }
59 int32_t PR_CALLBACK interposedWrite(PRFileDesc* aFd, const void* aBuf,
60 int32_t aAmt)
61 {
62 // If we don't have a valid original function pointer something is very wrong.
63 NS_ASSERTION(sWriteFn, "NSPR IO Interposing: sWriteFn is NULL");
65 NSPRIOAutoObservation timer(IOInterposeObserver::OpWrite);
66 return sWriteFn(aFd, aBuf, aAmt);
67 }
69 PRStatus PR_CALLBACK interposedFSync(PRFileDesc* aFd)
70 {
71 // If we don't have a valid original function pointer something is very wrong.
72 NS_ASSERTION(sFSyncFn, "NSPR IO Interposing: sFSyncFn is NULL");
74 NSPRIOAutoObservation timer(IOInterposeObserver::OpFSync);
75 return sFSyncFn(aFd);
76 }
78 PRStatus PR_CALLBACK interposedFileInfo(PRFileDesc *aFd, PRFileInfo *aInfo)
79 {
80 // If we don't have a valid original function pointer something is very wrong.
81 NS_ASSERTION(sFileInfoFn, "NSPR IO Interposing: sFileInfoFn is NULL");
83 NSPRIOAutoObservation timer(IOInterposeObserver::OpStat);
84 return sFileInfoFn(aFd, aInfo);
85 }
87 PRStatus PR_CALLBACK interposedFileInfo64(PRFileDesc *aFd, PRFileInfo64 *aInfo)
88 {
89 // If we don't have a valid original function pointer something is very wrong.
90 NS_ASSERTION(sFileInfo64Fn, "NSPR IO Interposing: sFileInfo64Fn is NULL");
92 NSPRIOAutoObservation timer(IOInterposeObserver::OpStat);
93 return sFileInfo64Fn(aFd, aInfo);
94 }
96 } // anonymous namespace
98 namespace mozilla {
100 void InitNSPRIOInterposing()
101 {
102 // Check that we have not interposed any of the IO methods before
103 MOZ_ASSERT(!sCloseFn && !sReadFn && !sWriteFn && !sFSyncFn && !sFileInfoFn &&
104 !sFileInfo64Fn);
106 // We can't actually use this assertion because we initialize this code
107 // before XPCOM is initialized, so NS_IsMainThread() always returns false.
108 // MOZ_ASSERT(NS_IsMainThread());
110 // Get IO methods from NSPR and const cast the structure so we can modify it.
111 PRIOMethods* methods = const_cast<PRIOMethods*>(PR_GetFileMethods());
113 // Something is badly wrong if we don't get IO methods... However, we don't
114 // want to crash over that in non-debug builds. This is unlikely to happen
115 // so an assert is enough, no need to report it to the caller.
116 MOZ_ASSERT(methods);
117 if (!methods) {
118 return;
119 }
121 // Store original functions
122 sCloseFn = methods->close;
123 sReadFn = methods->read;
124 sWriteFn = methods->write;
125 sFSyncFn = methods->fsync;
126 sFileInfoFn = methods->fileInfo;
127 sFileInfo64Fn = methods->fileInfo64;
129 // Overwrite with our interposed functions
130 methods->close = &interposedClose;
131 methods->read = &interposedRead;
132 methods->write = &interposedWrite;
133 methods->fsync = &interposedFSync;
134 methods->fileInfo = &interposedFileInfo;
135 methods->fileInfo64 = &interposedFileInfo64;
136 }
138 void ClearNSPRIOInterposing()
139 {
140 // If we have already cleared IO interposing, or not initialized it this is
141 // actually bad.
142 MOZ_ASSERT(sCloseFn && sReadFn && sWriteFn && sFSyncFn && sFileInfoFn &&
143 sFileInfo64Fn);
145 // Get IO methods from NSPR and const cast the structure so we can modify it.
146 PRIOMethods* methods = const_cast<PRIOMethods*>(PR_GetFileMethods());
148 // Something is badly wrong if we don't get IO methods... However, we don't
149 // want to crash over that in non-debug builds. This is unlikely to happen
150 // so an assert is enough, no need to report it to the caller.
151 MOZ_ASSERT(methods);
152 if (!methods) {
153 return;
154 }
156 // Restore original functions
157 methods->close = sCloseFn;
158 methods->read = sReadFn;
159 methods->write = sWriteFn;
160 methods->fsync = sFSyncFn;
161 methods->fileInfo = sFileInfoFn;
162 methods->fileInfo64 = sFileInfo64Fn;
164 // Forget about original functions
165 sCloseFn = nullptr;
166 sReadFn = nullptr;
167 sWriteFn = nullptr;
168 sFSyncFn = nullptr;
169 sFileInfoFn = nullptr;
170 sFileInfo64Fn = nullptr;
171 }
173 } // namespace mozilla