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++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 /* vim: set ts=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 "WorkerScope.h"
9 #include "jsapi.h"
10 #include "mozilla/EventListenerManager.h"
11 #include "mozilla/dom/FunctionBinding.h"
12 #include "mozilla/dom/DedicatedWorkerGlobalScopeBinding.h"
13 #include "mozilla/dom/SharedWorkerGlobalScopeBinding.h"
14 #include "mozilla/dom/Console.h"
16 #ifdef ANDROID
17 #include <android/log.h>
18 #endif
20 #include "Location.h"
21 #include "Navigator.h"
22 #include "Principal.h"
23 #include "RuntimeService.h"
24 #include "ScriptLoader.h"
25 #include "WorkerPrivate.h"
27 #define UNWRAP_WORKER_OBJECT(Interface, obj, value) \
28 UnwrapObject<prototypes::id::Interface##_workers, \
29 mozilla::dom::Interface##Binding_workers::NativeType>(obj, value)
31 using namespace mozilla;
32 using namespace mozilla::dom;
33 USING_WORKERS_NAMESPACE
35 BEGIN_WORKERS_NAMESPACE
37 WorkerGlobalScope::WorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
38 : mWorkerPrivate(aWorkerPrivate)
39 {
40 mWorkerPrivate->AssertIsOnWorkerThread();
42 SetIsDOMBinding();
43 }
45 WorkerGlobalScope::~WorkerGlobalScope()
46 {
47 mWorkerPrivate->AssertIsOnWorkerThread();
48 }
50 NS_IMPL_CYCLE_COLLECTION_CLASS(WorkerGlobalScope)
52 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WorkerGlobalScope,
53 DOMEventTargetHelper)
54 tmp->mWorkerPrivate->AssertIsOnWorkerThread();
55 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)
56 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigator)
57 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
59 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WorkerGlobalScope,
60 DOMEventTargetHelper)
61 tmp->mWorkerPrivate->AssertIsOnWorkerThread();
62 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
63 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)
64 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
66 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WorkerGlobalScope,
67 DOMEventTargetHelper)
68 tmp->mWorkerPrivate->AssertIsOnWorkerThread();
70 tmp->mWorkerPrivate->TraceTimeouts(aCallbacks, aClosure);
71 NS_IMPL_CYCLE_COLLECTION_TRACE_END
73 NS_IMPL_ADDREF_INHERITED(WorkerGlobalScope, DOMEventTargetHelper)
74 NS_IMPL_RELEASE_INHERITED(WorkerGlobalScope, DOMEventTargetHelper)
76 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WorkerGlobalScope)
77 NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
78 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
80 JSObject*
81 WorkerGlobalScope::WrapObject(JSContext* aCx)
82 {
83 MOZ_CRASH("We should never get here!");
84 }
86 already_AddRefed<Console>
87 WorkerGlobalScope::GetConsole()
88 {
89 mWorkerPrivate->AssertIsOnWorkerThread();
91 if (!mConsole) {
92 mConsole = new Console(nullptr);
93 MOZ_ASSERT(mConsole);
94 }
96 return mConsole.forget();
97 }
99 already_AddRefed<WorkerLocation>
100 WorkerGlobalScope::Location()
101 {
102 mWorkerPrivate->AssertIsOnWorkerThread();
104 if (!mLocation) {
105 WorkerPrivate::LocationInfo& info = mWorkerPrivate->GetLocationInfo();
107 mLocation = WorkerLocation::Create(info);
108 MOZ_ASSERT(mLocation);
109 }
111 nsRefPtr<WorkerLocation> location = mLocation;
112 return location.forget();
113 }
115 already_AddRefed<WorkerNavigator>
116 WorkerGlobalScope::Navigator()
117 {
118 mWorkerPrivate->AssertIsOnWorkerThread();
120 if (!mNavigator) {
121 mNavigator = WorkerNavigator::Create(mWorkerPrivate->OnLine());
122 MOZ_ASSERT(mNavigator);
123 }
125 nsRefPtr<WorkerNavigator> navigator = mNavigator;
126 return navigator.forget();
127 }
129 already_AddRefed<WorkerNavigator>
130 WorkerGlobalScope::GetExistingNavigator() const
131 {
132 mWorkerPrivate->AssertIsOnWorkerThread();
134 nsRefPtr<WorkerNavigator> navigator = mNavigator;
135 return navigator.forget();
136 }
138 void
139 WorkerGlobalScope::Close(JSContext* aCx)
140 {
141 mWorkerPrivate->AssertIsOnWorkerThread();
143 mWorkerPrivate->CloseInternal(aCx);
144 }
146 OnErrorEventHandlerNonNull*
147 WorkerGlobalScope::GetOnerror()
148 {
149 mWorkerPrivate->AssertIsOnWorkerThread();
151 EventListenerManager* elm = GetExistingListenerManager();
152 return elm ? elm->GetOnErrorEventHandler() : nullptr;
153 }
155 void
156 WorkerGlobalScope::SetOnerror(OnErrorEventHandlerNonNull* aHandler)
157 {
158 mWorkerPrivate->AssertIsOnWorkerThread();
160 EventListenerManager* elm = GetOrCreateListenerManager();
161 if (elm) {
162 elm->SetEventHandler(aHandler);
163 }
164 }
166 void
167 WorkerGlobalScope::ImportScripts(JSContext* aCx,
168 const Sequence<nsString>& aScriptURLs,
169 ErrorResult& aRv)
170 {
171 mWorkerPrivate->AssertIsOnWorkerThread();
172 scriptloader::Load(aCx, mWorkerPrivate, aScriptURLs, aRv);
173 }
175 int32_t
176 WorkerGlobalScope::SetTimeout(JSContext* aCx,
177 Function& aHandler,
178 const int32_t aTimeout,
179 const Sequence<JS::Value>& aArguments,
180 ErrorResult& aRv)
181 {
182 mWorkerPrivate->AssertIsOnWorkerThread();
183 return mWorkerPrivate->SetTimeout(aCx, &aHandler, EmptyString(), aTimeout,
184 aArguments, false, aRv);
185 }
187 int32_t
188 WorkerGlobalScope::SetTimeout(JSContext* /* unused */,
189 const nsAString& aHandler,
190 const int32_t aTimeout,
191 const Sequence<JS::Value>& /* unused */,
192 ErrorResult& aRv)
193 {
194 mWorkerPrivate->AssertIsOnWorkerThread();
195 Sequence<JS::Value> dummy;
196 return mWorkerPrivate->SetTimeout(GetCurrentThreadJSContext(), nullptr,
197 aHandler, aTimeout, dummy, false, aRv);
198 }
200 void
201 WorkerGlobalScope::ClearTimeout(int32_t aHandle, ErrorResult& aRv)
202 {
203 mWorkerPrivate->AssertIsOnWorkerThread();
204 mWorkerPrivate->ClearTimeout(aHandle);
205 }
207 int32_t
208 WorkerGlobalScope::SetInterval(JSContext* aCx,
209 Function& aHandler,
210 const Optional<int32_t>& aTimeout,
211 const Sequence<JS::Value>& aArguments,
212 ErrorResult& aRv)
213 {
214 mWorkerPrivate->AssertIsOnWorkerThread();
216 int32_t timeout = aTimeout.WasPassed() ? aTimeout.Value() : 0;
218 return mWorkerPrivate->SetTimeout(aCx, &aHandler, EmptyString(), timeout,
219 aArguments, !!timeout, aRv);
220 }
222 int32_t
223 WorkerGlobalScope::SetInterval(JSContext* /* unused */,
224 const nsAString& aHandler,
225 const Optional<int32_t>& aTimeout,
226 const Sequence<JS::Value>& /* unused */,
227 ErrorResult& aRv)
228 {
229 mWorkerPrivate->AssertIsOnWorkerThread();
231 Sequence<JS::Value> dummy;
233 int32_t timeout = aTimeout.WasPassed() ? aTimeout.Value() : 0;
235 return mWorkerPrivate->SetTimeout(GetCurrentThreadJSContext(), nullptr,
236 aHandler, timeout, dummy, !!timeout, aRv);
237 }
239 void
240 WorkerGlobalScope::ClearInterval(int32_t aHandle, ErrorResult& aRv)
241 {
242 mWorkerPrivate->AssertIsOnWorkerThread();
243 mWorkerPrivate->ClearTimeout(aHandle);
244 }
246 void
247 WorkerGlobalScope::Atob(const nsAString& aAtob, nsAString& aOutput, ErrorResult& aRv) const
248 {
249 mWorkerPrivate->AssertIsOnWorkerThread();
250 aRv = nsContentUtils::Atob(aAtob, aOutput);
251 }
253 void
254 WorkerGlobalScope::Btoa(const nsAString& aBtoa, nsAString& aOutput, ErrorResult& aRv) const
255 {
256 mWorkerPrivate->AssertIsOnWorkerThread();
257 aRv = nsContentUtils::Btoa(aBtoa, aOutput);
258 }
260 void
261 WorkerGlobalScope::Dump(const Optional<nsAString>& aString) const
262 {
263 mWorkerPrivate->AssertIsOnWorkerThread();
265 if (!aString.WasPassed()) {
266 return;
267 }
269 if (!mWorkerPrivate->DumpEnabled()) {
270 return;
271 }
273 NS_ConvertUTF16toUTF8 str(aString.Value());
275 #ifdef ANDROID
276 __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", str.get());
277 #endif
278 fputs(str.get(), stdout);
279 fflush(stdout);
280 }
282 DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
283 : WorkerGlobalScope(aWorkerPrivate)
284 {
285 }
287 /* static */ bool
288 DedicatedWorkerGlobalScope::Visible(JSContext* aCx, JSObject* aObj)
289 {
290 DedicatedWorkerGlobalScope* self = nullptr;
291 nsresult rv = UNWRAP_WORKER_OBJECT(DedicatedWorkerGlobalScope, aObj, self);
292 return NS_SUCCEEDED(rv) && self;
293 }
295 JSObject*
296 DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
297 {
298 mWorkerPrivate->AssertIsOnWorkerThread();
299 MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker());
301 JS::CompartmentOptions options;
302 mWorkerPrivate->CopyJSCompartmentOptions(options);
304 // We're wrapping the global, so the scope is undefined.
305 JS::Rooted<JSObject*> scope(aCx);
307 return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this,
308 options,
309 GetWorkerPrincipal());
310 }
312 void
313 DedicatedWorkerGlobalScope::PostMessage(JSContext* aCx,
314 JS::Handle<JS::Value> aMessage,
315 const Optional<Sequence<JS::Value>>& aTransferable,
316 ErrorResult& aRv)
317 {
318 mWorkerPrivate->AssertIsOnWorkerThread();
319 mWorkerPrivate->PostMessageToParent(aCx, aMessage, aTransferable, aRv);
320 }
322 SharedWorkerGlobalScope::SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
323 const nsCString& aName)
324 : WorkerGlobalScope(aWorkerPrivate), mName(aName)
325 {
326 }
328 /* static */ bool
329 SharedWorkerGlobalScope::Visible(JSContext* aCx, JSObject* aObj)
330 {
331 SharedWorkerGlobalScope* self = nullptr;
332 nsresult rv = UNWRAP_WORKER_OBJECT(SharedWorkerGlobalScope, aObj, self);
333 return NS_SUCCEEDED(rv) && self;
334 }
336 JSObject*
337 SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
338 {
339 mWorkerPrivate->AssertIsOnWorkerThread();
340 MOZ_ASSERT(mWorkerPrivate->IsSharedWorker());
342 JS::CompartmentOptions options;
343 mWorkerPrivate->CopyJSCompartmentOptions(options);
345 // We're wrapping the global, so the scope is undefined.
346 JS::Rooted<JSObject*> scope(aCx);
348 return SharedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this, options,
349 GetWorkerPrincipal());
350 }
352 bool
353 GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
354 {
355 JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr, JSMSG_GETTER_ONLY);
356 return false;
357 }
359 END_WORKERS_NAMESPACE