/work/obj-fuzz/dist/include/xpcpublic.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* vim: set ts=8 sts=4 et sw=4 tw=99: */ |
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/. */ |
6 | | |
7 | | #ifndef xpcpublic_h |
8 | | #define xpcpublic_h |
9 | | |
10 | | #include "jsapi.h" |
11 | | #include "js/HeapAPI.h" |
12 | | #include "js/GCAPI.h" |
13 | | #include "js/Proxy.h" |
14 | | #include "js/Wrapper.h" |
15 | | |
16 | | #include "nsAtom.h" |
17 | | #include "nsISupports.h" |
18 | | #include "nsIURI.h" |
19 | | #include "nsIPrincipal.h" |
20 | | #include "nsIGlobalObject.h" |
21 | | #include "nsPIDOMWindow.h" |
22 | | #include "nsWrapperCache.h" |
23 | | #include "nsString.h" |
24 | | #include "nsTArray.h" |
25 | | #include "mozilla/dom/JSSlots.h" |
26 | | #include "mozilla/fallible.h" |
27 | | #include "nsMathUtils.h" |
28 | | #include "nsStringBuffer.h" |
29 | | #include "mozilla/dom/BindingDeclarations.h" |
30 | | #include "mozilla/Preferences.h" |
31 | | |
32 | | class nsGlobalWindowInner; |
33 | | class nsIPrincipal; |
34 | | class nsIHandleReportCallback; |
35 | | |
36 | | namespace mozilla { |
37 | | namespace dom { |
38 | | class Exception; |
39 | | } |
40 | | } |
41 | | |
42 | | typedef void (* xpcGCCallback)(JSGCStatus status); |
43 | | |
44 | | namespace xpc { |
45 | | |
46 | | class Scriptability { |
47 | | public: |
48 | | explicit Scriptability(JS::Realm* realm); |
49 | | bool Allowed(); |
50 | | bool IsImmuneToScriptPolicy(); |
51 | | |
52 | | void Block(); |
53 | | void Unblock(); |
54 | | void SetDocShellAllowsScript(bool aAllowed); |
55 | | |
56 | | static Scriptability& Get(JSObject* aScope); |
57 | | static Scriptability& Get(JSScript* aScript); |
58 | | |
59 | | private: |
60 | | // Whenever a consumer wishes to prevent script from running on a global, |
61 | | // it increments this value with a call to Block(). When it wishes to |
62 | | // re-enable it (if ever), it decrements this value with a call to Unblock(). |
63 | | // Script may not run if this value is non-zero. |
64 | | uint32_t mScriptBlocks; |
65 | | |
66 | | // Whether the docshell allows javascript in this scope. If this scope |
67 | | // doesn't have a docshell, this value is always true. |
68 | | bool mDocShellAllowsScript; |
69 | | |
70 | | // Whether this scope is immune to user-defined or addon-defined script |
71 | | // policy. |
72 | | bool mImmuneToScriptPolicy; |
73 | | |
74 | | // Whether the new-style domain policy when this compartment was created |
75 | | // forbids script execution. |
76 | | bool mScriptBlockedByPolicy; |
77 | | }; |
78 | | |
79 | | JSObject* |
80 | | TransplantObject(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target); |
81 | | |
82 | | JSObject* |
83 | | TransplantObjectRetainingXrayExpandos(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target); |
84 | | |
85 | | bool IsContentXBLCompartment(JS::Compartment* compartment); |
86 | | bool IsContentXBLScope(JS::Realm* realm); |
87 | | bool IsInContentXBLScope(JSObject* obj); |
88 | | |
89 | | bool IsUAWidgetCompartment(JS::Compartment* compartment); |
90 | | bool IsUAWidgetScope(JS::Realm* realm); |
91 | | bool IsInUAWidgetScope(JSObject* obj); |
92 | | |
93 | | bool IsInSandboxCompartment(JSObject* obj); |
94 | | |
95 | | bool MightBeWebContentCompartment(JS::Compartment* compartment); |
96 | | |
97 | | void SetCompartmentChangedDocumentDomain(JS::Compartment* compartment); |
98 | | |
99 | | // Return a raw XBL scope object corresponding to contentScope, which must |
100 | | // be an object whose global is a DOM window. |
101 | | // |
102 | | // The return value is not wrapped into cx->compartment, so be sure to enter |
103 | | // its compartment before doing anything meaningful. |
104 | | // |
105 | | // Also note that XBL scopes are lazily created, so the return-value should be |
106 | | // null-checked unless the caller can ensure that the scope must already |
107 | | // exist. |
108 | | // |
109 | | // This function asserts if |contentScope| is itself in an XBL scope to catch |
110 | | // sloppy consumers. Conversely, GetXBLScopeOrGlobal will handle objects that |
111 | | // are in XBL scope (by just returning the global). |
112 | | JSObject* |
113 | | GetXBLScope(JSContext* cx, JSObject* contentScope); |
114 | | |
115 | | JSObject* |
116 | | GetUAWidgetScope(JSContext* cx, nsIPrincipal* principal); |
117 | | |
118 | | JSObject* |
119 | | GetUAWidgetScope(JSContext* cx, JSObject* contentScope); |
120 | | |
121 | | inline JSObject* |
122 | | GetXBLScopeOrGlobal(JSContext* cx, JSObject* obj) |
123 | 0 | { |
124 | 0 | MOZ_ASSERT(!js::IsCrossCompartmentWrapper(obj)); |
125 | 0 | if (IsInContentXBLScope(obj)) { |
126 | 0 | return JS::GetNonCCWObjectGlobal(obj); |
127 | 0 | } |
128 | 0 | return GetXBLScope(cx, obj); |
129 | 0 | } |
130 | | |
131 | | // Returns whether XBL scopes have been explicitly disabled for code running |
132 | | // in this compartment. See the comment around mAllowContentXBLScope. |
133 | | bool |
134 | | AllowContentXBLScope(JS::Realm* realm); |
135 | | |
136 | | // Returns whether we will use an XBL scope for this realm. This is |
137 | | // semantically equivalent to comparing global != GetXBLScope(global), but it |
138 | | // does not have the side-effect of eagerly creating the XBL scope if it does |
139 | | // not already exist. |
140 | | bool |
141 | | UseContentXBLScope(JS::Realm* realm); |
142 | | |
143 | | // Clear out the content XBL scope (if any) on the given global. This will |
144 | | // force creation of a new one if one is needed again. |
145 | | void |
146 | | ClearContentXBLScope(JSObject* global); |
147 | | |
148 | | bool |
149 | | IsSandboxPrototypeProxy(JSObject* obj); |
150 | | |
151 | | bool |
152 | | IsReflector(JSObject* obj); |
153 | | |
154 | | bool |
155 | | IsXrayWrapper(JSObject* obj); |
156 | | |
157 | | // If this function was created for a given XrayWrapper, returns the global of |
158 | | // the Xrayed object. Otherwise, returns the global of the function. |
159 | | // |
160 | | // To emphasize the obvious: the return value here is not necessarily same- |
161 | | // compartment with the argument. |
162 | | JSObject* |
163 | | XrayAwareCalleeGlobal(JSObject* fun); |
164 | | |
165 | | void |
166 | | TraceXPCGlobal(JSTracer* trc, JSObject* obj); |
167 | | |
168 | | /** |
169 | | * Creates a new global object using the given aCOMObj as the global |
170 | | * object. The object will be set up according to the flags (defined |
171 | | * below). If you do not pass INIT_JS_STANDARD_CLASSES, then aCOMObj |
172 | | * must implement nsIXPCScriptable so it can resolve the standard |
173 | | * classes when asked by the JS engine. |
174 | | * |
175 | | * @param aJSContext the context to use while creating the global object. |
176 | | * @param aCOMObj the native object that represents the global object. |
177 | | * @param aPrincipal the principal of the code that will run in this |
178 | | * compartment. Can be null if not on the main thread. |
179 | | * @param aFlags one of the flags below specifying what options this |
180 | | * global object wants. |
181 | | * @param aOptions JSAPI-specific options for the new compartment. |
182 | | */ |
183 | | nsresult |
184 | | InitClassesWithNewWrappedGlobal(JSContext* aJSContext, |
185 | | nsISupports* aCOMObj, |
186 | | nsIPrincipal* aPrincipal, |
187 | | uint32_t aFlags, |
188 | | JS::RealmOptions& aOptions, |
189 | | JS::MutableHandleObject aNewGlobal); |
190 | | |
191 | | enum InitClassesFlag { |
192 | | INIT_JS_STANDARD_CLASSES = 1 << 0, |
193 | | DONT_FIRE_ONNEWGLOBALHOOK = 1 << 1, |
194 | | OMIT_COMPONENTS_OBJECT = 1 << 2, |
195 | | }; |
196 | | |
197 | | } /* namespace xpc */ |
198 | | |
199 | | namespace JS { |
200 | | |
201 | | struct RuntimeStats; |
202 | | |
203 | | } // namespace JS |
204 | | |
205 | 29 | #define XPC_WRAPPER_FLAGS (JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE) |
206 | | |
207 | | #define XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(n) \ |
208 | 3 | JSCLASS_DOM_GLOBAL | JSCLASS_HAS_PRIVATE | \ |
209 | 3 | JSCLASS_PRIVATE_IS_NSISUPPORTS | \ |
210 | 3 | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS + n) |
211 | | |
212 | 3 | #define XPCONNECT_GLOBAL_EXTRA_SLOT_OFFSET (JSCLASS_GLOBAL_SLOT_COUNT + DOM_GLOBAL_SLOTS) |
213 | | |
214 | 29 | #define XPCONNECT_GLOBAL_FLAGS XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(0) |
215 | | |
216 | | inline JSObject* |
217 | | xpc_FastGetCachedWrapper(JSContext* cx, nsWrapperCache* cache, JS::MutableHandleValue vp) |
218 | 1.62M | { |
219 | 1.62M | if (cache) { |
220 | 0 | JSObject* wrapper = cache->GetWrapper(); |
221 | 0 | if (wrapper && |
222 | 0 | js::GetObjectCompartment(wrapper) == js::GetContextCompartment(cx)) |
223 | 0 | { |
224 | 0 | vp.setObject(*wrapper); |
225 | 0 | return wrapper; |
226 | 0 | } |
227 | 1.62M | } |
228 | 1.62M | |
229 | 1.62M | return nullptr; |
230 | 1.62M | } |
231 | | |
232 | | // If aWrappedJS is a JS wrapper, unmark its JSObject. |
233 | | extern void |
234 | | xpc_TryUnmarkWrappedGrayObject(nsISupports* aWrappedJS); |
235 | | |
236 | | extern void |
237 | | xpc_UnmarkSkippableJSHolders(); |
238 | | |
239 | | // Defined in XPCDebug.cpp. |
240 | | extern bool |
241 | | xpc_DumpJSStack(bool showArgs, bool showLocals, bool showThisProps); |
242 | | |
243 | | // Return a newly-allocated string containing a representation of the |
244 | | // current JS stack. Defined in XPCDebug.cpp. |
245 | | extern JS::UniqueChars |
246 | | xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals, |
247 | | bool showThisProps); |
248 | | |
249 | | |
250 | | // readable string conversions, static methods and members only |
251 | | class XPCStringConvert |
252 | | { |
253 | | public: |
254 | | |
255 | | // If the string shares the readable's buffer, that buffer will |
256 | | // get assigned to *sharedBuffer. Otherwise null will be |
257 | | // assigned. |
258 | | static bool ReadableToJSVal(JSContext* cx, const nsAString& readable, |
259 | | nsStringBuffer** sharedBuffer, |
260 | | JS::MutableHandleValue vp); |
261 | | |
262 | | // Convert the given stringbuffer/length pair to a jsval |
263 | | static MOZ_ALWAYS_INLINE bool |
264 | | StringBufferToJSVal(JSContext* cx, nsStringBuffer* buf, uint32_t length, |
265 | | JS::MutableHandleValue rval, bool* sharedBuffer) |
266 | 6 | { |
267 | 6 | JSString* str = JS_NewMaybeExternalString(cx, |
268 | 6 | static_cast<char16_t*>(buf->Data()), |
269 | 6 | length, &sDOMStringFinalizer, sharedBuffer); |
270 | 6 | if (!str) { |
271 | 0 | return false; |
272 | 0 | } |
273 | 6 | rval.setString(str); |
274 | 6 | return true; |
275 | 6 | } |
276 | | |
277 | | static inline bool |
278 | | StringLiteralToJSVal(JSContext* cx, const char16_t* literal, uint32_t length, |
279 | | JS::MutableHandleValue rval) |
280 | 0 | { |
281 | 0 | bool ignored; |
282 | 0 | JSString* str = JS_NewMaybeExternalString(cx, literal, length, |
283 | 0 | &sLiteralFinalizer, &ignored); |
284 | 0 | if (!str) { |
285 | 0 | return false; |
286 | 0 | } |
287 | 0 | rval.setString(str); |
288 | 0 | return true; |
289 | 0 | } |
290 | | |
291 | | static inline bool |
292 | | DynamicAtomToJSVal(JSContext* cx, nsDynamicAtom* atom, |
293 | | JS::MutableHandleValue rval) |
294 | 0 | { |
295 | 0 | bool sharedAtom; |
296 | 0 | JSString* str = JS_NewMaybeExternalString(cx, atom->GetUTF16String(), |
297 | 0 | atom->GetLength(), |
298 | 0 | &sDynamicAtomFinalizer, |
299 | 0 | &sharedAtom); |
300 | 0 | if (!str) { |
301 | 0 | return false; |
302 | 0 | } |
303 | 0 | if (sharedAtom) { |
304 | 0 | // We only have non-owning atoms in DOMString for now. |
305 | 0 | // nsDynamicAtom::AddRef is always-inline and defined in a |
306 | 0 | // translation unit we can't get to here. So we need to go through |
307 | 0 | // nsAtom::AddRef to call it. |
308 | 0 | static_cast<nsAtom*>(atom)->AddRef(); |
309 | 0 | } |
310 | 0 | rval.setString(str); |
311 | 0 | return true; |
312 | 0 | } |
313 | | |
314 | | static MOZ_ALWAYS_INLINE bool IsLiteral(JSString* str) |
315 | 0 | { |
316 | 0 | return JS_IsExternalString(str) && |
317 | 0 | JS_GetExternalStringFinalizer(str) == &sLiteralFinalizer; |
318 | 0 | } |
319 | | |
320 | | static MOZ_ALWAYS_INLINE bool IsDOMString(JSString* str) |
321 | 0 | { |
322 | 0 | return JS_IsExternalString(str) && |
323 | 0 | JS_GetExternalStringFinalizer(str) == &sDOMStringFinalizer; |
324 | 0 | } |
325 | | |
326 | | private: |
327 | | static const JSStringFinalizer |
328 | | sLiteralFinalizer, sDOMStringFinalizer, sDynamicAtomFinalizer; |
329 | | |
330 | | static void FinalizeLiteral(const JSStringFinalizer* fin, char16_t* chars); |
331 | | |
332 | | static void FinalizeDOMString(const JSStringFinalizer* fin, char16_t* chars); |
333 | | |
334 | | static void FinalizeDynamicAtom(const JSStringFinalizer* fin, |
335 | | char16_t* chars); |
336 | | |
337 | | XPCStringConvert() = delete; |
338 | | }; |
339 | | |
340 | | class nsIAddonInterposition; |
341 | | |
342 | | namespace xpc { |
343 | | |
344 | | // If these functions return false, then an exception will be set on cx. |
345 | | bool Base64Encode(JSContext* cx, JS::HandleValue val, JS::MutableHandleValue out); |
346 | | bool Base64Decode(JSContext* cx, JS::HandleValue val, JS::MutableHandleValue out); |
347 | | |
348 | | /** |
349 | | * Convert an nsString to jsval, returning true on success. |
350 | | * Note, the ownership of the string buffer may be moved from str to rval. |
351 | | * If that happens, str will point to an empty string after this call. |
352 | | */ |
353 | | bool NonVoidStringToJsval(JSContext* cx, nsAString& str, JS::MutableHandleValue rval); |
354 | | inline bool StringToJsval(JSContext* cx, nsAString& str, JS::MutableHandleValue rval) |
355 | 0 | { |
356 | 0 | // From the T_DOMSTRING case in XPCConvert::NativeData2JS. |
357 | 0 | if (str.IsVoid()) { |
358 | 0 | rval.setNull(); |
359 | 0 | return true; |
360 | 0 | } |
361 | 0 | return NonVoidStringToJsval(cx, str, rval); |
362 | 0 | } |
363 | | |
364 | | inline bool |
365 | | NonVoidStringToJsval(JSContext* cx, const nsAString& str, JS::MutableHandleValue rval) |
366 | 6 | { |
367 | 6 | nsString mutableCopy; |
368 | 6 | if (!mutableCopy.Assign(str, mozilla::fallible)) { |
369 | 0 | JS_ReportOutOfMemory(cx); |
370 | 0 | return false; |
371 | 0 | } |
372 | 6 | return NonVoidStringToJsval(cx, mutableCopy, rval); |
373 | 6 | } |
374 | | |
375 | | inline bool |
376 | | StringToJsval(JSContext* cx, const nsAString& str, JS::MutableHandleValue rval) |
377 | 0 | { |
378 | 0 | nsString mutableCopy; |
379 | 0 | if (!mutableCopy.Assign(str, mozilla::fallible)) { |
380 | 0 | JS_ReportOutOfMemory(cx); |
381 | 0 | return false; |
382 | 0 | } |
383 | 0 | return StringToJsval(cx, mutableCopy, rval); |
384 | 0 | } |
385 | | |
386 | | /** |
387 | | * As above, but for mozilla::dom::DOMString. |
388 | | */ |
389 | | inline |
390 | | bool NonVoidStringToJsval(JSContext* cx, mozilla::dom::DOMString& str, |
391 | | JS::MutableHandleValue rval) |
392 | 0 | { |
393 | 0 | if (str.IsEmpty()) { |
394 | 0 | rval.set(JS_GetEmptyStringValue(cx)); |
395 | 0 | return true; |
396 | 0 | } |
397 | 0 | |
398 | 0 | if (str.HasStringBuffer()) { |
399 | 0 | uint32_t length = str.StringBufferLength(); |
400 | 0 | nsStringBuffer* buf = str.StringBuffer(); |
401 | 0 | bool shared; |
402 | 0 | if (!XPCStringConvert::StringBufferToJSVal(cx, buf, length, rval, |
403 | 0 | &shared)) { |
404 | 0 | return false; |
405 | 0 | } |
406 | 0 | if (shared) { |
407 | 0 | // JS now needs to hold a reference to the buffer |
408 | 0 | str.RelinquishBufferOwnership(); |
409 | 0 | } |
410 | 0 | return true; |
411 | 0 | } |
412 | 0 |
|
413 | 0 | if (str.HasLiteral()) { |
414 | 0 | return XPCStringConvert::StringLiteralToJSVal(cx, str.Literal(), |
415 | 0 | str.LiteralLength(), rval); |
416 | 0 | } |
417 | 0 | |
418 | 0 | if (str.HasAtom()) { |
419 | 0 | return XPCStringConvert::DynamicAtomToJSVal(cx, str.Atom(), rval); |
420 | 0 | } |
421 | 0 | |
422 | 0 | // It's an actual XPCOM string |
423 | 0 | return NonVoidStringToJsval(cx, str.AsAString(), rval); |
424 | 0 | } |
425 | | |
426 | | MOZ_ALWAYS_INLINE |
427 | | bool StringToJsval(JSContext* cx, mozilla::dom::DOMString& str, |
428 | | JS::MutableHandleValue rval) |
429 | 0 | { |
430 | 0 | if (str.IsNull()) { |
431 | 0 | rval.setNull(); |
432 | 0 | return true; |
433 | 0 | } |
434 | 0 | return NonVoidStringToJsval(cx, str, rval); |
435 | 0 | } |
436 | | |
437 | | nsIPrincipal* GetCompartmentPrincipal(JS::Compartment* compartment); |
438 | | nsIPrincipal* GetRealmPrincipal(JS::Realm* realm); |
439 | | |
440 | | void NukeAllWrappersForCompartment(JSContext* cx, JS::Compartment* compartment, |
441 | | js::NukeReferencesToWindow nukeReferencesToWindow = js::NukeWindowReferences); |
442 | | |
443 | | void SetLocationForGlobal(JSObject* global, const nsACString& location); |
444 | | void SetLocationForGlobal(JSObject* global, nsIURI* locationURI); |
445 | | |
446 | | // ReportJSRuntimeExplicitTreeStats will expect this in the |extra| member |
447 | | // of JS::ZoneStats. |
448 | | class ZoneStatsExtras { |
449 | | public: |
450 | 0 | ZoneStatsExtras() {} |
451 | | |
452 | | nsCString pathPrefix; |
453 | | |
454 | | private: |
455 | | ZoneStatsExtras(const ZoneStatsExtras& other) = delete; |
456 | | ZoneStatsExtras& operator=(const ZoneStatsExtras& other) = delete; |
457 | | }; |
458 | | |
459 | | // ReportJSRuntimeExplicitTreeStats will expect this in the |extra| member |
460 | | // of JS::RealmStats. |
461 | | class RealmStatsExtras { |
462 | | public: |
463 | 0 | RealmStatsExtras() {} |
464 | | |
465 | | nsCString jsPathPrefix; |
466 | | nsCString domPathPrefix; |
467 | | nsCOMPtr<nsIURI> location; |
468 | | |
469 | | private: |
470 | | RealmStatsExtras(const RealmStatsExtras& other) = delete; |
471 | | RealmStatsExtras& operator=(const RealmStatsExtras& other) = delete; |
472 | | }; |
473 | | |
474 | | // This reports all the stats in |rtStats| that belong in the "explicit" tree, |
475 | | // (which isn't all of them). |
476 | | // @see ZoneStatsExtras |
477 | | // @see RealmStatsExtras |
478 | | void |
479 | | ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats& rtStats, |
480 | | const nsACString& rtPath, |
481 | | nsIHandleReportCallback* handleReport, |
482 | | nsISupports* data, |
483 | | bool anonymize, |
484 | | size_t* rtTotal = nullptr); |
485 | | |
486 | | /** |
487 | | * Throws an exception on cx and returns false. |
488 | | */ |
489 | | bool |
490 | | Throw(JSContext* cx, nsresult rv); |
491 | | |
492 | | /** |
493 | | * Returns the nsISupports native behind a given reflector (either DOM or |
494 | | * XPCWN). |
495 | | */ |
496 | | already_AddRefed<nsISupports> |
497 | | UnwrapReflectorToISupports(JSObject* reflector); |
498 | | |
499 | | /** |
500 | | * Singleton scopes for stuff that really doesn't fit anywhere else. |
501 | | * |
502 | | * If you find yourself wanting to use these compartments, you're probably doing |
503 | | * something wrong. Callers MUST consult with the XPConnect module owner before |
504 | | * using this compartment. If you don't, bholley will hunt you down. |
505 | | */ |
506 | | JSObject* |
507 | | UnprivilegedJunkScope(); |
508 | | |
509 | | /** |
510 | | * This will generally be the shared JSM global, but callers should not depend |
511 | | * on that fact. |
512 | | */ |
513 | | JSObject* |
514 | | PrivilegedJunkScope(); |
515 | | |
516 | | /** |
517 | | * Shared compilation scope for XUL prototype documents and XBL |
518 | | * precompilation. |
519 | | */ |
520 | | JSObject* |
521 | | CompilationScope(); |
522 | | |
523 | | /** |
524 | | * Returns the nsIGlobalObject corresponding to |obj|'s JS global. |obj| must |
525 | | * not be a cross-compartment wrapper: CCWs are not associated with a single |
526 | | * global. |
527 | | */ |
528 | | nsIGlobalObject* |
529 | | NativeGlobal(JSObject* obj); |
530 | | |
531 | | /** |
532 | | * Returns the nsIGlobalObject corresponding to |cx|'s JS global. Must not be |
533 | | * called when |cx| is not in a Realm. |
534 | | */ |
535 | | nsIGlobalObject* |
536 | | CurrentNativeGlobal(JSContext* cx); |
537 | | |
538 | | /** |
539 | | * If |aObj| is a window, returns the associated nsGlobalWindow. |
540 | | * Otherwise, returns null. |
541 | | */ |
542 | | nsGlobalWindowInner* |
543 | | WindowOrNull(JSObject* aObj); |
544 | | |
545 | | /** |
546 | | * If |aObj| has a window for a global, returns the associated nsGlobalWindow. |
547 | | * Otherwise, returns null. Note: aObj must not be a cross-compartment wrapper |
548 | | * because CCWs are not associated with a single global/realm. |
549 | | */ |
550 | | nsGlobalWindowInner* |
551 | | WindowGlobalOrNull(JSObject* aObj); |
552 | | |
553 | | /** |
554 | | * If |cx| is in a realm whose global is a window, returns the associated |
555 | | * nsGlobalWindow. Otherwise, returns null. |
556 | | */ |
557 | | nsGlobalWindowInner* |
558 | | CurrentWindowOrNull(JSContext* cx); |
559 | | |
560 | | class MOZ_RAII AutoScriptActivity |
561 | | { |
562 | | bool mActive; |
563 | | bool mOldValue; |
564 | | public: |
565 | | explicit AutoScriptActivity(bool aActive); |
566 | | ~AutoScriptActivity(); |
567 | | }; |
568 | | |
569 | | // This function may be used off-main-thread, in which case it is benignly |
570 | | // racey. |
571 | | bool |
572 | | ShouldDiscardSystemSource(); |
573 | | |
574 | | bool |
575 | | SharedMemoryEnabled(); |
576 | | |
577 | | bool |
578 | | ExtraWarningsForSystemJS(); |
579 | | |
580 | | class ErrorBase { |
581 | | public: |
582 | | nsString mErrorMsg; |
583 | | nsString mFileName; |
584 | | uint32_t mLineNumber; |
585 | | uint32_t mColumn; |
586 | | |
587 | | ErrorBase() : mLineNumber(0) |
588 | | , mColumn(0) |
589 | 0 | {} |
590 | | |
591 | | void Init(JSErrorBase* aReport); |
592 | | |
593 | | void AppendErrorDetailsTo(nsCString& error); |
594 | | }; |
595 | | |
596 | | class ErrorNote : public ErrorBase { |
597 | | public: |
598 | | void Init(JSErrorNotes::Note* aNote); |
599 | | |
600 | | // Produce an error event message string from the given JSErrorNotes::Note. |
601 | | // This may produce an empty string if aNote doesn't have a message |
602 | | // attached. |
603 | | static void ErrorNoteToMessageString(JSErrorNotes::Note* aNote, |
604 | | nsAString& aString); |
605 | | |
606 | | // Log the error note to the stderr. |
607 | | void LogToStderr(); |
608 | | }; |
609 | | |
610 | | class ErrorReport : public ErrorBase { |
611 | | public: |
612 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ErrorReport); |
613 | | |
614 | | nsTArray<ErrorNote> mNotes; |
615 | | |
616 | | nsCString mCategory; |
617 | | nsString mSourceLine; |
618 | | nsString mErrorMsgName; |
619 | | uint64_t mWindowID; |
620 | | uint32_t mFlags; |
621 | | bool mIsMuted; |
622 | | |
623 | | ErrorReport() : mWindowID(0) |
624 | | , mFlags(0) |
625 | | , mIsMuted(false) |
626 | 0 | {} |
627 | | |
628 | | void Init(JSErrorReport* aReport, const char* aToStringResult, |
629 | | bool aIsChrome, uint64_t aWindowID); |
630 | | void Init(JSContext* aCx, mozilla::dom::Exception* aException, |
631 | | bool aIsChrome, uint64_t aWindowID); |
632 | | |
633 | | // Log the error report to the console. Which console will depend on the |
634 | | // window id it was initialized with. |
635 | | void LogToConsole(); |
636 | | // Log to console, using the given stack object (which should be a stack of |
637 | | // the sort that JS::CaptureCurrentStack produces). aStack is allowed to be |
638 | | // null. If aStack is non-null, aStackGlobal must be a non-null global |
639 | | // object that's same-compartment with aStack. Note that aStack might be a |
640 | | // CCW. When recording/replaying, aTimeWarpTarget optionally indicates |
641 | | // where the error occurred in the process' execution. |
642 | | void LogToConsoleWithStack(JS::HandleObject aStack, JS::HandleObject aStackGlobal, |
643 | | uint64_t aTimeWarpTarget = 0); |
644 | | |
645 | | // Produce an error event message string from the given JSErrorReport. Note |
646 | | // that this may produce an empty string if aReport doesn't have a |
647 | | // message attached. |
648 | | static void ErrorReportToMessageString(JSErrorReport* aReport, |
649 | | nsAString& aString); |
650 | | |
651 | | // Log the error report to the stderr. |
652 | | void LogToStderr(); |
653 | | |
654 | | private: |
655 | 0 | ~ErrorReport() {} |
656 | | }; |
657 | | |
658 | | void |
659 | | DispatchScriptErrorEvent(nsPIDOMWindowInner* win, JS::RootingContext* rootingCx, |
660 | | xpc::ErrorReport* xpcReport, JS::Handle<JS::Value> exception); |
661 | | |
662 | | // Get a stack (as stackObj outparam) of the sort that can be passed to |
663 | | // xpc::ErrorReport::LogToConsoleWithStack from the given exception value. Can |
664 | | // be nullptr if the exception value doesn't have an associated stack. The |
665 | | // returned stack, if any, may also not be in the same compartment as |
666 | | // exceptionValue. |
667 | | // |
668 | | // The "win" argument passed in here should be the same as the window whose |
669 | | // WindowID() is used to initialize the xpc::ErrorReport. This may be null, of |
670 | | // course. If it's not null, this function may return a null stack object if |
671 | | // the window is far enough gone, because in those cases we don't want to have |
672 | | // the stack in the console message keeping the window alive. |
673 | | // |
674 | | // If this function sets stackObj to a non-null value, stackGlobal is set to |
675 | | // either the JS exception object's global or the global of the SavedFrame we |
676 | | // got from a DOM or XPConnect exception. In all cases, stackGlobal is an |
677 | | // unwrapped global object and is same-compartment with stackObj. |
678 | | void |
679 | | FindExceptionStackForConsoleReport(nsPIDOMWindowInner* win, |
680 | | JS::HandleValue exceptionValue, |
681 | | JS::MutableHandleObject stackObj, |
682 | | JS::MutableHandleObject stackGlobal); |
683 | | |
684 | | // Return a name for the realm. |
685 | | // This function makes reasonable efforts to make this name both mostly human-readable |
686 | | // and unique. However, there are no guarantees of either property. |
687 | | extern void |
688 | | GetCurrentRealmName(JSContext*, nsCString& name); |
689 | | |
690 | | void AddGCCallback(xpcGCCallback cb); |
691 | | void RemoveGCCallback(xpcGCCallback cb); |
692 | | |
693 | | inline bool |
694 | | AreNonLocalConnectionsDisabled() |
695 | 0 | { |
696 | 0 | static int disabledForTest = -1; |
697 | 0 | if (disabledForTest == -1) { |
698 | 0 | char *s = getenv("MOZ_DISABLE_NONLOCAL_CONNECTIONS"); |
699 | 0 | if (s) { |
700 | 0 | disabledForTest = *s != '0'; |
701 | 0 | } else { |
702 | 0 | disabledForTest = 0; |
703 | 0 | } |
704 | 0 | } |
705 | 0 | return disabledForTest; |
706 | 0 | } |
707 | | |
708 | | inline bool |
709 | | IsInAutomation() |
710 | 0 | { |
711 | 0 | static bool sAutomationPrefIsSet; |
712 | 0 | static bool sPrefCacheAdded = false; |
713 | 0 | if (!sPrefCacheAdded) { |
714 | 0 | mozilla::Preferences::AddBoolVarCache( |
715 | 0 | &sAutomationPrefIsSet, |
716 | 0 | "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer", |
717 | 0 | false); |
718 | 0 | sPrefCacheAdded = true; |
719 | 0 | } |
720 | 0 | return sAutomationPrefIsSet && AreNonLocalConnectionsDisabled(); |
721 | 0 | } |
722 | | |
723 | | void |
724 | | CreateCooperativeContext(); |
725 | | |
726 | | void |
727 | | DestroyCooperativeContext(); |
728 | | |
729 | | // Please see JS_YieldCooperativeContext in jsapi.h. |
730 | | void |
731 | | YieldCooperativeContext(); |
732 | | |
733 | | // Please see JS_ResumeCooperativeContext in jsapi.h. |
734 | | void |
735 | | ResumeCooperativeContext(); |
736 | | |
737 | | } // namespace xpc |
738 | | |
739 | | namespace mozilla { |
740 | | namespace dom { |
741 | | |
742 | | /** |
743 | | * A test for whether WebIDL methods that should only be visible to |
744 | | * chrome or XBL scopes should be exposed. |
745 | | */ |
746 | | bool IsChromeOrXBL(JSContext* cx, JSObject* /* unused */); |
747 | | |
748 | | /** |
749 | | * This is used to prevent UA widget code from directly creating and adopting |
750 | | * nodes via the content document, since they should use the special |
751 | | * create-and-insert apis instead. |
752 | | */ |
753 | | bool IsNotUAWidget(JSContext* cx, JSObject* /* unused */); |
754 | | |
755 | | /** |
756 | | * A test for whether WebIDL methods that should only be visible to |
757 | | * chrome, XBL scopes, or UA Widget scopes. |
758 | | */ |
759 | | bool IsChromeOrXBLOrUAWidget(JSContext* cx, JSObject* /* unused */); |
760 | | |
761 | | /** |
762 | | * Same as IsChromeOrXBLOrUAWidget but can be used in worker threads as well. |
763 | | */ |
764 | | bool ThreadSafeIsChromeOrXBLOrUAWidget(JSContext* cx, JSObject* obj); |
765 | | |
766 | | } // namespace dom |
767 | | |
768 | | /** |
769 | | * Fill the given vector with the buildid. |
770 | | */ |
771 | | bool |
772 | | GetBuildId(JS::BuildIdCharVector* aBuildID); |
773 | | |
774 | | } // namespace mozilla |
775 | | |
776 | | #endif |