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/. */
6
7 /* A namespace class for static content utilities. */
8
9 #ifndef nsContentUtils_h___
10 #define nsContentUtils_h___
11
12 #if defined(XP_WIN)
13 # include <float.h>
14 #endif
15
16 #if defined(SOLARIS)
17 # include <ieeefp.h>
18 #endif
19
20 #include <cstddef>
21 #include <cstdint>
22 #include <functional>
23 #include <tuple>
24 #include <utility>
25 #include "ErrorList.h"
26 #include "Units.h"
27 #include "js/Id.h"
28 #include "js/RootingAPI.h"
29 #include "mozilla/AlreadyAddRefed.h"
30 #include "mozilla/Assertions.h"
31 #include "mozilla/Attributes.h"
32 #include "mozilla/BasicEvents.h"
33 #include "mozilla/CORSMode.h"
34 #include "mozilla/CallState.h"
35 #include "mozilla/Maybe.h"
36 #include "mozilla/RefPtr.h"
37 #include "mozilla/TaskCategory.h"
38 #include "mozilla/TimeStamp.h"
39 #include "mozilla/UniquePtr.h"
40 #include "mozilla/dom/BindingDeclarations.h"
41 #include "mozilla/dom/FromParser.h"
42 #include "mozilla/fallible.h"
43 #include "mozilla/gfx/Point.h"
44 #include "nsCOMPtr.h"
45 #include "nsHashtablesFwd.h"
46 #include "nsIContentPolicy.h"
47 #include "nsID.h"
48 #include "nsINode.h"
49 #include "nsIScriptError.h"
50 #include "nsIThread.h"
51 #include "nsLiteralString.h"
52 #include "nsMargin.h"
53 #include "nsPIDOMWindow.h"
54 #include "nsStringFwd.h"
55 #include "nsTArray.h"
56 #include "nsTLiteralString.h"
57 #include "prtime.h"
58
59 #if defined(XP_WIN)
60 // Undefine LoadImage to prevent naming conflict with Windows.
61 # undef LoadImage
62 #endif
63
64 class JSObject;
65 class imgICache;
66 class imgIContainer;
67 class imgINotificationObserver;
68 class imgIRequest;
69 class imgLoader;
70 class imgRequestProxy;
71 class nsAtom;
72 class nsAttrValue;
73 class nsAutoScriptBlockerSuppressNodeRemoved;
74 class nsContentList;
75 class nsCycleCollectionTraversalCallback;
76 class nsDocShell;
77 class nsGlobalWindowInner;
78 class nsHtml5StringParser;
79 class nsIArray;
80 class nsIBidiKeyboard;
81 class nsIChannel;
82 class nsIConsoleService;
83 class nsIContent;
84 class nsIDocShell;
85 class nsIDocShellTreeItem;
86 class nsIDocumentLoaderFactory;
87 class nsIDragSession;
88 class nsIFile;
89 class nsIFragmentContentSink;
90 class nsIFrame;
91 class nsIHttpChannel;
92 class nsIIOService;
93 class nsIImageLoadingContent;
94 class nsIInterfaceRequestor;
95 class nsILoadGroup;
96 class nsILoadInfo;
97 class nsIObserver;
98 class nsIParser;
99 class nsIPluginTag;
100 class nsIPrincipal;
101 class nsIReferrerInfo;
102 class nsIRequest;
103 class nsIRunnable;
104 class nsIScreen;
105 class nsIScriptContext;
106 class nsIScriptSecurityManager;
107 class nsISerialEventTarget;
108 class nsIStringBundle;
109 class nsIStringBundleService;
110 class nsISupports;
111 class nsITransferable;
112 class nsIURI;
113 class nsIUUIDGenerator;
114 class nsIWidget;
115 class nsIXPConnect;
116 class nsNameSpaceManager;
117 class nsNodeInfoManager;
118 class nsPIWindowRoot;
119 class nsPresContext;
120 class nsStringBuffer;
121 class nsStringHashKey;
122 class nsTextFragment;
123 class nsView;
124 class nsWrapperCache;
125
126 struct JSContext;
127 struct nsPoint;
128
129 template <class T>
130 class nsRefPtrHashKey;
131
132 namespace IPC {
133 class Message;
134 }
135
136 namespace JS {
137 class Value;
138 class PropertyDescriptor;
139 } // namespace JS
140
141 namespace mozilla {
142 class Dispatcher;
143 class EditorBase;
144 class ErrorResult;
145 class EventListenerManager;
146 class HTMLEditor;
147 class LazyLogModule;
148 class LogModule;
149 class PresShell;
150 class TextEditor;
151 class WidgetDragEvent;
152 class WidgetKeyboardEvent;
153
154 struct InputEventOptions;
155
156 template <typename ParentType, typename RefType>
157 class RangeBoundaryBase;
158
159 template <typename T>
160 class NotNull;
161 template <class T>
162 class StaticRefPtr;
163
164 namespace dom {
165 struct AutocompleteInfo;
166 class BrowserChild;
167 class BrowserParent;
168 class BrowsingContext;
169 class BrowsingContextGroup;
170 class ContentChild;
171 class ContentFrameMessageManager;
172 class ContentParent;
173 struct CustomElementDefinition;
174 class CustomElementRegistry;
175 class DataTransfer;
176 class Document;
177 class DocumentFragment;
178 class DOMArena;
179 class Element;
180 class Event;
181 class EventTarget;
182 class HTMLInputElement;
183 class IPCDataTransfer;
184 class IPCDataTransferItem;
185 struct LifecycleCallbackArgs;
186 struct LifecycleAdoptedCallbackArgs;
187 class MessageBroadcaster;
188 class NodeInfo;
189 class Selection;
190 class WorkerPrivate;
191 enum class ElementCallbackType;
192 enum class ReferrerPolicy : uint8_t;
193 } // namespace dom
194
195 namespace intl {
196 class LineBreaker;
197 class WordBreaker;
198 } // namespace intl
199
200 namespace ipc {
201 class Shmem;
202 class IShmemAllocator;
203 } // namespace ipc
204
205 namespace gfx {
206 class DataSourceSurface;
207 enum class SurfaceFormat : int8_t;
208 } // namespace gfx
209
210 namespace layers {
211 class LayerManager;
212 } // namespace layers
213
214 } // namespace mozilla
215
216 extern const char kLoadAsData[];
217
218 // Stolen from nsReadableUtils, but that's OK, since we can declare the same
219 // name multiple times.
220 const nsString& EmptyString();
221 const nsCString& EmptyCString();
222
223 enum EventNameType {
224 EventNameType_None = 0x0000,
225 EventNameType_HTML = 0x0001,
226 EventNameType_XUL = 0x0002,
227 EventNameType_SVGGraphic = 0x0004, // svg graphic elements
228 EventNameType_SVGSVG = 0x0008, // the svg element
229 EventNameType_SMIL = 0x0010, // smil elements
230 EventNameType_HTMLBodyOrFramesetOnly = 0x0020,
231 EventNameType_HTMLMarqueeOnly = 0x0040,
232
233 EventNameType_HTMLXUL = 0x0003,
234 EventNameType_All = 0xFFFF
235 };
236
237 struct EventNameMapping {
238 // This holds pointers to nsGkAtoms members, and is therefore safe as a
239 // non-owning reference.
240 nsAtom* MOZ_NON_OWNING_REF mAtom;
241 int32_t mType;
242 mozilla::EventMessage mMessage;
243 mozilla::EventClassID mEventClassID;
244 // True if mAtom is possibly used by special SVG/SMIL events, but
245 // mMessage is eUnidentifiedEvent. See EventNameList.h
246 bool mMaybeSpecialSVGorSMILEvent;
247 };
248
249 namespace mozilla {
250 enum class PreventDefaultResult : uint8_t { No, ByContent, ByChrome };
251 }
252
253 class nsContentUtils {
254 friend class nsAutoScriptBlockerSuppressNodeRemoved;
255 typedef mozilla::dom::Element Element;
256 typedef mozilla::dom::Document Document;
257 typedef mozilla::Cancelable Cancelable;
258 typedef mozilla::CanBubble CanBubble;
259 typedef mozilla::Composed Composed;
260 typedef mozilla::ChromeOnlyDispatch ChromeOnlyDispatch;
261 typedef mozilla::EventMessage EventMessage;
262 typedef mozilla::TimeDuration TimeDuration;
263 typedef mozilla::Trusted Trusted;
264
265 public:
266 static nsresult Init();
267
268 static bool IsCallerChrome();
269 static bool ThreadsafeIsCallerChrome();
270 static bool IsCallerUAWidget();
IsFuzzingEnabled()271 static bool IsFuzzingEnabled()
272 #ifndef FUZZING
273 {
274 return false;
275 }
276 #else
277 ;
278 #endif
279 static bool IsErrorPage(nsIURI* aURI);
280
IsCallerChromeOrFuzzingEnabled(JSContext * aCx,JSObject *)281 static bool IsCallerChromeOrFuzzingEnabled(JSContext* aCx, JSObject*) {
282 return ThreadsafeIsSystemCaller(aCx) || IsFuzzingEnabled();
283 }
284
285 static bool IsCallerChromeOrElementTransformGettersEnabled(JSContext* aCx,
286 JSObject*);
287
288 static bool IsCallerChromeOrErrorPage(JSContext*, JSObject*);
289
290 // The APIs for checking whether the caller is system (in the sense of system
291 // principal) should only be used when the JSContext is known to accurately
292 // represent the caller. In practice, that means you should only use them in
293 // two situations at the moment:
294 //
295 // 1) Functions used in WebIDL Func annotations.
296 // 2) Bindings code or other code called directly from the JS engine.
297 //
298 // Use pretty much anywhere else is almost certainly wrong and should be
299 // replaced with [NeedsCallerType] annotations in bindings.
300
301 // Check whether the caller is system if you know you're on the main thread.
302 static bool IsSystemCaller(JSContext* aCx);
303
304 // Check whether the caller is system if you might be on a worker or worklet
305 // thread.
306 static bool ThreadsafeIsSystemCaller(JSContext* aCx);
307
308 // In the traditional Gecko architecture, both C++ code and untrusted JS code
309 // needed to rely on the same XPCOM method/getter/setter to get work done.
310 // This required lots of security checks in the various exposed methods, which
311 // in turn created difficulty in determining whether the caller was script
312 // (whose access needed to be checked) and internal C++ platform code (whose
313 // access did not need to be checked). To address this problem, Gecko had a
314 // convention whereby the absence of script on the stack was interpretted as
315 // "System Caller" and always granted unfettered access.
316 //
317 // Unfortunately, this created a bunch of footguns. For example, when the
318 // implementation of a DOM method wanted to perform a privileged
319 // sub-operation, it needed to "hide" the presence of script on the stack in
320 // order for that sub-operation to be allowed. Additionally, if script could
321 // trigger an API entry point to be invoked in some asynchronous way without
322 // script on the stack, it could potentially perform privilege escalation.
323 //
324 // In the modern world, untrusted script should interact with the platform
325 // exclusively over WebIDL APIs, and platform code has a lot more flexibility
326 // in deciding whether or not to use XPCOM. This gives us the flexibility to
327 // do something better.
328 //
329 // Going forward, APIs should be designed such that any security checks that
330 // ask the question "is my caller allowed to do this?" should live in WebIDL
331 // API entry points, with a separate method provided for internal callers
332 // that just want to get the job done.
333 //
334 // To enforce this and catch bugs, nsContentUtils::SubjectPrincipal will crash
335 // if it is invoked without script on the stack. To land that transition, it
336 // was necessary to go through and whitelist a bunch of callers that were
337 // depending on the old behavior. Those callers should be fixed up, and these
338 // methods should not be used by new code without review from bholley or bz.
LegacyIsCallerNativeCode()339 static bool LegacyIsCallerNativeCode() { return !GetCurrentJSContext(); }
LegacyIsCallerChromeOrNativeCode()340 static bool LegacyIsCallerChromeOrNativeCode() {
341 return LegacyIsCallerNativeCode() || IsCallerChrome();
342 }
SubjectPrincipalOrSystemIfNativeCaller()343 static nsIPrincipal* SubjectPrincipalOrSystemIfNativeCaller() {
344 if (!GetCurrentJSContext()) {
345 return GetSystemPrincipal();
346 }
347 return SubjectPrincipal();
348 }
349
350 static bool LookupBindingMember(
351 JSContext* aCx, nsIContent* aContent, JS::Handle<jsid> aId,
352 JS::MutableHandle<JS::PropertyDescriptor> aDesc);
353
354 // Check whether we should avoid leaking distinguishing information to JS/CSS.
355 // This function can be called both in the main thread and worker threads.
356 static bool ShouldResistFingerprinting();
357 static bool ShouldResistFingerprinting(nsIDocShell* aDocShell);
358 static bool ShouldResistFingerprinting(nsIPrincipal* aPrincipal);
359 static bool ShouldResistFingerprinting(
360 mozilla::dom::WorkerPrivate* aWorkerPrivate);
361 static bool ShouldResistFingerprinting(const Document* aDoc);
362 static bool ShouldResistFingerprinting(nsIChannel* aChannel);
363
364 // Prevent system colors from being exposed to CSS or canvas.
365 static bool UseStandinsForNativeColors();
366
367 // A helper function to calculate the rounded window size for fingerprinting
368 // resistance. The rounded size is based on the chrome UI size and available
369 // screen size. If the inputWidth/Height is greater than the available content
370 // size, this will report the available content size. Otherwise, it will
371 // round the size to the nearest upper 200x100.
372 static void CalcRoundedWindowSizeForResistingFingerprinting(
373 int32_t aChromeWidth, int32_t aChromeHeight, int32_t aScreenWidth,
374 int32_t aScreenHeight, int32_t aInputWidth, int32_t aInputHeight,
375 bool aSetOuterWidth, bool aSetOuterHeight, int32_t* aOutputWidth,
376 int32_t* aOutputHeight);
377
378 /**
379 * Returns the parent node of aChild crossing document boundaries, but skips
380 * any cross-process parent frames and continues with the nearest in-process
381 * frame in the hierarchy.
382 *
383 * Uses the parent node in the composed document.
384 */
385 static nsINode* GetNearestInProcessCrossDocParentNode(nsINode* aChild);
386
387 /**
388 * Similar to nsINode::IsInclusiveDescendantOf, except will treat an
389 * HTMLTemplateElement or ShadowRoot as an ancestor of things in the
390 * corresponding DocumentFragment. See the concept of "host-including
391 * inclusive ancestor" in the DOM specification.
392 */
393 static bool ContentIsHostIncludingDescendantOf(
394 const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
395
396 /**
397 * Similar to nsINode::IsInclusiveDescendantOf except it crosses document
398 * boundaries, this function uses ancestor/descendant relations in the
399 * composed document (see shadow DOM spec).
400 */
401 static bool ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
402 nsINode* aPossibleAncestor);
403
404 /**
405 * As with ContentIsCrossDocDescendantOf but crosses shadow boundaries but not
406 * cross document boundaries.
407 *
408 * @see nsINode::GetFlattenedTreeParentNode()
409 */
410 static bool ContentIsFlattenedTreeDescendantOf(
411 const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
412
413 /**
414 * Same as `ContentIsFlattenedTreeDescendantOf`, but from the flattened tree
415 * point of view of the style system
416 *
417 * @see nsINode::GetFlattenedTreeParentNodeForStyle()
418 */
419 static bool ContentIsFlattenedTreeDescendantOfForStyle(
420 const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
421
422 /**
423 * Retarget an object A against an object B
424 * @see https://dom.spec.whatwg.org/#retarget
425 */
426 static nsINode* Retarget(nsINode* aTargetA, nsINode* aTargetB);
427
428 /*
429 * https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor.
430 *
431 * This method fills the |aArray| with all ancestor nodes of |aNode|
432 * including |aNode| at the zero index.
433 *
434 */
435 static nsresult GetInclusiveAncestors(nsINode* aNode,
436 nsTArray<nsINode*>& aArray);
437
438 /*
439 * https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor.
440 *
441 * This method fills |aAncestorNodes| with all ancestor nodes of |aNode|
442 * including |aNode| (QI'd to nsIContent) at the zero index.
443 * For each ancestor, there is a corresponding element in |aAncestorOffsets|
444 * which is the IndexOf the child in relation to its parent.
445 *
446 * This method just sucks.
447 */
448 static nsresult GetInclusiveAncestorsAndOffsets(
449 nsINode* aNode, int32_t aOffset, nsTArray<nsIContent*>* aAncestorNodes,
450 nsTArray<int32_t>* aAncestorOffsets);
451
452 /**
453 * Returns the closest common inclusive ancestor
454 * (https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor) , if any,
455 * for two nodes.
456 *
457 * Returns null if the nodes are disconnected.
458 */
GetClosestCommonInclusiveAncestor(nsINode * aNode1,nsINode * aNode2)459 static nsINode* GetClosestCommonInclusiveAncestor(nsINode* aNode1,
460 nsINode* aNode2) {
461 if (aNode1 == aNode2) {
462 return aNode1;
463 }
464
465 return GetCommonAncestorHelper(aNode1, aNode2);
466 }
467
468 /**
469 * Returns the common flattened tree ancestor, if any, for two given content
470 * nodes.
471 */
GetCommonFlattenedTreeAncestor(nsIContent * aContent1,nsIContent * aContent2)472 static nsIContent* GetCommonFlattenedTreeAncestor(nsIContent* aContent1,
473 nsIContent* aContent2) {
474 if (aContent1 == aContent2) {
475 return aContent1;
476 }
477
478 return GetCommonFlattenedTreeAncestorHelper(aContent1, aContent2);
479 }
480
481 /**
482 * Returns the common flattened tree ancestor from the point of view of the
483 * style system, if any, for two given content nodes.
484 */
485 static Element* GetCommonFlattenedTreeAncestorForStyle(Element* aElement1,
486 Element* aElement2);
487
488 /**
489 * Returns the common ancestor under interactive content, if any.
490 * If neither one has interactive content as ancestor, common ancestor will be
491 * returned. If only one has interactive content as ancestor, null will be
492 * returned. If the nodes are the same, that node is returned.
493 */
494 static nsINode* GetCommonAncestorUnderInteractiveContent(nsINode* aNode1,
495 nsINode* aNode2);
496
497 /**
498 * Returns the common BrowserParent ancestor, if any, for two given
499 * BrowserParent.
500 */
501 static mozilla::dom::BrowserParent* GetCommonBrowserParentAncestor(
502 mozilla::dom::BrowserParent* aBrowserParent1,
503 mozilla::dom::BrowserParent* aBrowserParent2);
504
505 /**
506 * Returns true if aNode1 is before aNode2 in the same connected
507 * tree.
508 * aNode1Index and aNode2Index are in/out arguments. If non-null, and value is
509 * not -1, that value is used instead of calling slow ComputeIndexOf on the
510 * parent node. If value is -1, the value will be set to the return value of
511 * ComputeIndexOf.
512 */
513 static bool PositionIsBefore(nsINode* aNode1, nsINode* aNode2,
514 int32_t* aNode1Index = nullptr,
515 int32_t* aNode2Index = nullptr);
516
517 struct ComparePointsCache {
ComputeIndexOfComparePointsCache518 int32_t ComputeIndexOf(const nsINode* aParent, const nsINode* aChild) {
519 if (aParent == mParent && aChild == mChild) {
520 return mIndex;
521 }
522
523 mIndex = aParent->ComputeIndexOf(aChild);
524 mParent = aParent;
525 mChild = aChild;
526 return mIndex;
527 }
528
529 private:
530 const nsINode* mParent = nullptr;
531 const nsINode* mChild = nullptr;
532 int32_t mIndex = 0;
533 };
534
535 /**
536 * Utility routine to compare two "points", where a point is a node/offset
537 * pair.
538 * Pass a cache object as aParent1Cache if you expect to repeatedly
539 * call this function with the same value as aParent1.
540 *
541 * XXX aOffset1 and aOffset2 should be uint32_t since valid offset value is
542 * between 0 - UINT32_MAX. However, these methods work even with
543 * negative offset values! E.g., when aOffset1 is -1 and aOffset is 0,
544 * these methods return -1. Some root callers depend on this behavior.
545 *
546 * @return -1 if point1 < point2,
547 * 1 if point1 > point2,
548 * 0 if point1 == point2.
549 * `Nothing` if the two nodes aren't in the same connected subtree.
550 */
551 static mozilla::Maybe<int32_t> ComparePoints(
552 const nsINode* aParent1, int32_t aOffset1, const nsINode* aParent2,
553 int32_t aOffset2, ComparePointsCache* aParent1Cache = nullptr);
554 template <typename FPT, typename FRT, typename SPT, typename SRT>
555 static mozilla::Maybe<int32_t> ComparePoints(
556 const mozilla::RangeBoundaryBase<FPT, FRT>& aFirstBoundary,
557 const mozilla::RangeBoundaryBase<SPT, SRT>& aSecondBoundary);
558
559 /**
560 * Utility routine to compare two "points", where a point is a
561 * node/offset pair
562 * Returns -1 if point1 < point2, 1, if point1 > point2,
563 * 0 if error or if point1 == point2.
564 * NOTE! If the two nodes aren't in the same connected subtree,
565 * the result is 1, and the optional aDisconnected parameter
566 * is set to true.
567 *
568 * Pass a cache object as aParent1Cache if you expect to repeatedly
569 * call this function with the same value as aParent1.
570 *
571 * XXX aOffset1 and aOffset2 should be uint32_t since valid offset value is
572 * between 0 - UINT32_MAX. However, these methods work even with
573 * negative offset values! E.g., when aOffset1 is -1 and aOffset is 0,
574 * these methods return -1. Some root callers depend on this behavior.
575 * On the other hand, nsINode can have ATTRCHILD_ARRAY_MAX_CHILD_COUN
576 * (0x3FFFFF) at most. Therefore, they can be int32_t for now.
577 */
578 static int32_t ComparePoints_Deprecated(
579 const nsINode* aParent1, int32_t aOffset1, const nsINode* aParent2,
580 int32_t aOffset2, bool* aDisconnected = nullptr,
581 ComparePointsCache* aParent1Cache = nullptr);
582 template <typename FPT, typename FRT, typename SPT, typename SRT>
583 static int32_t ComparePoints_Deprecated(
584 const mozilla::RangeBoundaryBase<FPT, FRT>& aFirstBoundary,
585 const mozilla::RangeBoundaryBase<SPT, SRT>& aSecondBoundary,
586 bool* aDisconnected = nullptr);
587
588 /**
589 * Brute-force search of the element subtree rooted at aContent for
590 * an element with the given id. aId must be nonempty, otherwise
591 * this method may return nodes even if they have no id!
592 */
593 static Element* MatchElementId(nsIContent* aContent, const nsAString& aId);
594
595 /**
596 * Similar to above, but to be used if one already has an atom for the ID
597 */
598 static Element* MatchElementId(nsIContent* aContent, const nsAtom* aId);
599
600 /**
601 * Reverses the document position flags passed in.
602 *
603 * @param aDocumentPosition The document position flags to be reversed.
604 *
605 * @return The reversed document position flags.
606 *
607 * @see Node
608 */
609 static uint16_t ReverseDocumentPosition(uint16_t aDocumentPosition);
610
611 static const nsDependentSubstring TrimCharsInSet(const char* aSet,
612 const nsAString& aValue);
613
614 template <bool IsWhitespace(char16_t)>
615 static const nsDependentSubstring TrimWhitespace(const nsAString& aStr,
616 bool aTrimTrailing = true);
617
618 /**
619 * Returns true if aChar is of class Ps, Pi, Po, Pf, or Pe.
620 */
621 static bool IsFirstLetterPunctuation(uint32_t aChar);
622
623 /**
624 * Returns true if aChar is of class Lu, Ll, Lt, Lm, Lo, Nd, Nl or No
625 */
626 static bool IsAlphanumeric(uint32_t aChar);
627 /**
628 * Returns true if aChar is of class L*, N* or S* (for first-letter).
629 */
630 static bool IsAlphanumericOrSymbol(uint32_t aChar);
631 static bool IsAlphanumericOrSymbolAt(const nsTextFragment* aFrag,
632 uint32_t aOffset);
633
634 /*
635 * Is the character an HTML whitespace character?
636 *
637 * We define whitespace using the list in HTML5 and css3-selectors:
638 * U+0009, U+000A, U+000C, U+000D, U+0020
639 *
640 * HTML 4.01 also lists U+200B (zero-width space).
641 */
642 static bool IsHTMLWhitespace(char16_t aChar);
643
644 /*
645 * Returns whether the character is an HTML whitespace (see IsHTMLWhitespace)
646 * or a nbsp character (U+00A0).
647 */
648 static bool IsHTMLWhitespaceOrNBSP(char16_t aChar);
649
650 /**
651 * https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
652 */
653 static bool IsHTMLBlockLevelElement(nsIContent* aContent);
654
655 enum ParseHTMLIntegerResultFlags {
656 eParseHTMLInteger_NoFlags = 0,
657 // eParseHTMLInteger_NonStandard is set if the string representation of the
658 // integer was not the canonical one, but matches at least one of the
659 // following:
660 // * had leading whitespaces
661 // * had '+' sign
662 // * had leading '0'
663 // * was '-0'
664 eParseHTMLInteger_NonStandard = 1 << 0,
665 eParseHTMLInteger_DidNotConsumeAllInput = 1 << 1,
666 // Set if one or more error flags were set.
667 eParseHTMLInteger_Error = 1 << 2,
668 eParseHTMLInteger_ErrorNoValue = 1 << 3,
669 eParseHTMLInteger_ErrorOverflow = 1 << 4,
670 // Use this flag to detect the difference between overflow and underflow
671 eParseHTMLInteger_Negative = 1 << 5,
672 };
673 static int32_t ParseHTMLInteger(const nsAString& aValue,
674 ParseHTMLIntegerResultFlags* aResult);
675 static int32_t ParseHTMLInteger(const nsACString& aValue,
676 ParseHTMLIntegerResultFlags* aResult);
677
678 private:
679 template <class StringT>
680 static int32_t ParseHTMLIntegerImpl(const StringT& aValue,
681 ParseHTMLIntegerResultFlags* aResult);
682
683 public:
684 /**
685 * Parse a margin string of format 'top, right, bottom, left' into
686 * an nsIntMargin.
687 *
688 * @param aString the string to parse
689 * @param aResult the resulting integer
690 * @return whether the value could be parsed
691 */
692 static bool ParseIntMarginValue(const nsAString& aString,
693 nsIntMargin& aResult);
694
695 /**
696 * Parse the value of the <font size=""> attribute according to the HTML5
697 * spec as of April 16, 2012.
698 *
699 * @param aValue the value to parse
700 * @return 1 to 7, or 0 if the value couldn't be parsed
701 */
702 static int32_t ParseLegacyFontSize(const nsAString& aValue);
703
704 static void Shutdown();
705
706 /**
707 * Checks whether two nodes come from the same origin.
708 */
709 static nsresult CheckSameOrigin(const nsINode* aTrustedNode,
710 const nsINode* unTrustedNode);
711
712 // Check if the (JS) caller can access aNode.
713 static bool CanCallerAccess(const nsINode* aNode);
714
715 // Check if the (JS) caller can access aWindow.
716 // aWindow can be either outer or inner window.
717 static bool CanCallerAccess(nsPIDOMWindowInner* aWindow);
718
719 // Check if the principal is chrome or an addon with the permission.
720 static bool PrincipalHasPermission(nsIPrincipal& aPrincipal,
721 const nsAtom* aPerm);
722
723 // Check if the JS caller is chrome or an addon with the permission.
724 static bool CallerHasPermission(JSContext* aCx, const nsAtom* aPerm);
725
726 /**
727 * Returns the triggering principal which should be used for the given URL
728 * attribute value with the given subject principal.
729 *
730 * If the attribute value is not an absolute URL, the subject principal will
731 * be ignored, and the node principal of aContent will be used instead.
732 * If aContent is non-null, this function will always return a principal.
733 * Otherewise, it may return null if aSubjectPrincipal is null or is rejected
734 * based on the attribute value.
735 *
736 * @param aContent The content on which the attribute is being set.
737 * @param aAttrValue The URL value of the attribute. For parsed attribute
738 * values, such as `srcset`, this function should be called separately
739 * for each URL value it contains.
740 * @param aSubjectPrincipal The subject principal of the scripted caller
741 * responsible for setting the attribute, or null if no scripted caller
742 * can be determined.
743 */
744 static nsIPrincipal* GetAttrTriggeringPrincipal(
745 nsIContent* aContent, const nsAString& aAttrValue,
746 nsIPrincipal* aSubjectPrincipal);
747
748 /**
749 * Returns true if the given string is guaranteed to be treated as an absolute
750 * URL, rather than a relative URL. In practice, this means any complete URL
751 * as supported by nsStandardURL, or any string beginning with a valid scheme
752 * which is known to the IO service, and has the URI_NORELATIVE flag.
753 *
754 * If the URL may be treated as absolute in some cases, but relative in others
755 * (for instance, "http:foo", which can be either an absolute or relative URL,
756 * depending on the context), this function returns false.
757 */
758 static bool IsAbsoluteURL(const nsACString& aURL);
759
760 // Check if a node is in the document prolog, i.e. before the document
761 // element.
762 static bool InProlog(nsINode* aNode);
763
NameSpaceManager()764 static nsNameSpaceManager* NameSpaceManager() { return sNameSpaceManager; }
765
GetIOService()766 static nsIIOService* GetIOService() { return sIOService; }
767
768 static nsIBidiKeyboard* GetBidiKeyboard();
769
770 /**
771 * Get the cache security manager service. Can return null if the layout
772 * module has been shut down.
773 */
GetSecurityManager()774 static nsIScriptSecurityManager* GetSecurityManager() {
775 return sSecurityManager;
776 }
777
778 // Returns the subject principal from the JSContext. May only be called
779 // from the main thread and assumes an existing compartment.
780 static nsIPrincipal* SubjectPrincipal(JSContext* aCx);
781
782 // Returns the subject principal. Guaranteed to return non-null. May only
783 // be called when nsContentUtils is initialized.
784 static nsIPrincipal* SubjectPrincipal();
785
786 // Returns the prinipal of the given JS object. This may only be called on
787 // the main thread for objects from the main thread's JSRuntime. The object
788 // must not be a cross-compartment wrapper, because CCWs are not associated
789 // with a single realm.
790 static nsIPrincipal* ObjectPrincipal(JSObject* aObj);
791
792 static void GenerateStateKey(nsIContent* aContent, Document* aDocument,
793 nsACString& aKey);
794
795 /**
796 * Create a new nsIURI from aSpec, using aBaseURI as the base. The
797 * origin charset of the new nsIURI will be the document charset of
798 * aDocument.
799 */
800 static nsresult NewURIWithDocumentCharset(nsIURI** aResult,
801 const nsAString& aSpec,
802 Document* aDocument,
803 nsIURI* aBaseURI);
804
805 /**
806 * Returns true if |aName| is a name with dashes.
807 */
808 static bool IsNameWithDash(nsAtom* aName);
809
810 /**
811 * Returns true if |aName| is a valid name to be registered via
812 * customElements.define.
813 */
814 static bool IsCustomElementName(nsAtom* aName, uint32_t aNameSpaceID);
815
816 static nsresult CheckQName(const nsAString& aQualifiedName,
817 bool aNamespaceAware = true,
818 const char16_t** aColon = nullptr);
819
820 static nsresult SplitQName(const nsIContent* aNamespaceResolver,
821 const nsString& aQName, int32_t* aNamespace,
822 nsAtom** aLocalName);
823
824 static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI,
825 const nsAString& aQualifiedName,
826 nsNodeInfoManager* aNodeInfoManager,
827 uint16_t aNodeType,
828 mozilla::dom::NodeInfo** aNodeInfo);
829
830 static void SplitExpatName(const char16_t* aExpatName, nsAtom** aPrefix,
831 nsAtom** aTagName, int32_t* aNameSpaceID);
832
833 // Get a permission-manager setting for the given principal and type.
834 // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is
835 // returned, otherwise true is returned. Always returns true for the
836 // system principal, and false for a null principal.
837 static bool IsSitePermAllow(nsIPrincipal* aPrincipal,
838 const nsACString& aType);
839
840 // Get a permission-manager setting for the given principal and type.
841 // If the pref doesn't exist or if it isn't DENY_ACTION, false is
842 // returned, otherwise true is returned. Always returns false for the
843 // system principal, and true for a null principal.
844 static bool IsSitePermDeny(nsIPrincipal* aPrincipal, const nsACString& aType);
845
846 // Get a permission-manager setting for the given principal and type.
847 // If the pref doesn't exist or if it isn't ALLOW_ACTION, false is
848 // returned, otherwise true is returned. Always returns true for the
849 // system principal, and false for a null principal.
850 // This version checks the permission for an exact host match on
851 // the principal
852 static bool IsExactSitePermAllow(nsIPrincipal* aPrincipal,
853 const nsACString& aType);
854
855 // Get a permission-manager setting for the given principal and type.
856 // If the pref doesn't exist or if it isn't DENY_ACTION, false is
857 // returned, otherwise true is returned. Always returns false for the
858 // system principal, and true for a null principal.
859 // This version checks the permission for an exact host match on
860 // the principal
861 static bool IsExactSitePermDeny(nsIPrincipal* aPrincipal,
862 const nsACString& aType);
863
864 // Returns true if aDoc1 and aDoc2 have equal NodePrincipal()s.
865 static bool HaveEqualPrincipals(Document* aDoc1, Document* aDoc2);
866
LineBreaker()867 static mozilla::intl::LineBreaker* LineBreaker() {
868 return sLineBreaker.get();
869 }
870
WordBreaker()871 static mozilla::intl::WordBreaker* WordBreaker() {
872 return sWordBreaker.get();
873 }
874
875 /**
876 * Regster aObserver as a shutdown observer. A strong reference is held
877 * to aObserver until UnregisterShutdownObserver is called.
878 */
879 static void RegisterShutdownObserver(nsIObserver* aObserver);
880 static void UnregisterShutdownObserver(nsIObserver* aObserver);
881
882 /**
883 * @return true if aContent has an attribute aName in namespace aNameSpaceID,
884 * and the attribute value is non-empty.
885 */
886 static bool HasNonEmptyAttr(const nsIContent* aContent, int32_t aNameSpaceID,
887 nsAtom* aName);
888
889 /**
890 * Method that gets the primary presContext for the node.
891 *
892 * @param aContent The content node.
893 * @return the presContext, or nullptr if the content is not in a document
894 * (if GetComposedDoc returns nullptr)
895 */
896 static nsPresContext* GetContextForContent(const nsIContent* aContent);
897
898 /**
899 * Method that gets the pres shell for the node.
900 *
901 * @param aContent The content node.
902 * @return the pres shell, or nullptr if the content is not in a document
903 * (if GetComposedDoc returns nullptr)
904 */
905 static mozilla::PresShell* GetPresShellForContent(const nsIContent* aContent);
906
907 /**
908 * Method to do security and content policy checks on the image URI
909 *
910 * @param aURI uri of the image to be loaded
911 * @param aNode, the context the image is loaded in (eg an element)
912 * @param aLoadingDocument the document we belong to
913 * @param aLoadingPrincipal the principal doing the load
914 * @param [aContentPolicyType=nsIContentPolicy::TYPE_INTERNAL_IMAGE]
915 * (Optional) The CP content type to use
916 * @param aImageBlockingStatus the nsIContentPolicy blocking status for this
917 * image. This will be set even if a security check fails for the
918 * image, to some reasonable REJECT_* value. This out param will only
919 * be set if it's non-null.
920 * @return true if the load can proceed, or false if it is blocked.
921 * Note that aImageBlockingStatus, if set will always be an ACCEPT
922 * status if true is returned and always be a REJECT_* status if
923 * false is returned.
924 */
925 static bool CanLoadImage(nsIURI* aURI, nsINode* aNode,
926 Document* aLoadingDocument,
927 nsIPrincipal* aLoadingPrincipal);
928
929 /**
930 * Returns true if objects in aDocument shouldn't initiate image loads.
931 */
932 static bool DocumentInactiveForImageLoads(Document* aDocument);
933
934 /**
935 * Convert a CORSMode into the corresponding imgILoader flags for
936 * passing to LoadImage.
937 * @param aMode CORS mode to convert
938 * @return a bitfield suitable to bitwise OR with other nsIRequest flags
939 */
940 static int32_t CORSModeToLoadImageFlags(mozilla::CORSMode aMode);
941
942 /**
943 * Method to start an image load. This does not do any security checks.
944 * This method will attempt to make aURI immutable; a caller that wants to
945 * keep a mutable version around should pass in a clone.
946 *
947 * @param aURI uri of the image to be loaded
948 * @param aContext element of document where the result of this request
949 * will be used.
950 * @param aLoadingDocument the document we belong to
951 * @param aLoadingPrincipal the principal doing the load
952 * @param aReferrerInfo the referrerInfo use on channel creation
953 * @param aObserver the observer for the image load
954 * @param aLoadFlags the load flags to use. See nsIRequest
955 * @param [aContentPolicyType=nsIContentPolicy::TYPE_INTERNAL_IMAGE]
956 * (Optional) The CP content type to use
957 * @param aUseUrgentStartForChannel,(Optional) a flag to mark on channel if it
958 * is triggered by user input events.
959 * @return the imgIRequest for the image load
960 */
961 static nsresult LoadImage(
962 nsIURI* aURI, nsINode* aContext, Document* aLoadingDocument,
963 nsIPrincipal* aLoadingPrincipal, uint64_t aRequestContextID,
964 nsIReferrerInfo* aReferrerInfo, imgINotificationObserver* aObserver,
965 int32_t aLoadFlags, const nsAString& initiatorType,
966 imgRequestProxy** aRequest,
967 nsContentPolicyType aContentPolicyType =
968 nsIContentPolicy::TYPE_INTERNAL_IMAGE,
969 bool aUseUrgentStartForChannel = false, bool aLinkPreload = false);
970
971 /**
972 * Obtain an image loader that respects the given document/channel's privacy
973 * status. Null document/channel arguments return the public image loader.
974 */
975 static imgLoader* GetImgLoaderForDocument(Document* aDoc);
976 static imgLoader* GetImgLoaderForChannel(nsIChannel* aChannel,
977 Document* aContext);
978
979 /**
980 * Returns whether the given URI is in the image cache.
981 */
982 static bool IsImageInCache(nsIURI* aURI, Document* aDocument);
983
984 /**
985 * Method to get an imgIContainer from an image loading content
986 *
987 * @param aContent The image loading content. Must not be null.
988 * @param aRequest The image request [out]
989 * @return the imgIContainer corresponding to the first frame of the image
990 */
991 static already_AddRefed<imgIContainer> GetImageFromContent(
992 nsIImageLoadingContent* aContent, imgIRequest** aRequest = nullptr);
993
994 /**
995 * Method that decides whether a content node is draggable
996 *
997 * @param aContent The content node to test.
998 * @return whether it's draggable
999 */
1000 static bool ContentIsDraggable(nsIContent* aContent);
1001
1002 /**
1003 * Method that decides whether a content node is a draggable image
1004 *
1005 * @param aContent The content node to test.
1006 * @return whether it's a draggable image
1007 */
1008 static bool IsDraggableImage(nsIContent* aContent);
1009
1010 /**
1011 * Method that decides whether a content node is a draggable link
1012 *
1013 * @param aContent The content node to test.
1014 * @return whether it's a draggable link
1015 */
1016 static bool IsDraggableLink(const nsIContent* aContent);
1017
1018 /**
1019 * Convenience method to create a new nodeinfo that differs only by prefix and
1020 * name from aNodeInfo. The new nodeinfo's name is set to aName, and prefix is
1021 * set to null.
1022 */
1023 static nsresult QNameChanged(mozilla::dom::NodeInfo* aNodeInfo, nsAtom* aName,
1024 mozilla::dom::NodeInfo** aResult);
1025
1026 /**
1027 * Returns the appropriate event argument names for the specified
1028 * namespace and event name. Added because we need to switch between
1029 * SVG's "evt" and the rest of the world's "event", and because onerror
1030 * on window takes 5 args.
1031 */
1032 static void GetEventArgNames(int32_t aNameSpaceID, nsAtom* aEventName,
1033 bool aIsForWindow, uint32_t* aArgCount,
1034 const char*** aArgNames);
1035
1036 /**
1037 * Returns true if this document is in a Private Browsing window.
1038 */
1039 static bool IsInPrivateBrowsing(Document* aDoc);
1040
1041 /**
1042 * Returns true if this loadGroup uses Private Browsing.
1043 */
1044 static bool IsInPrivateBrowsing(nsILoadGroup* aLoadGroup);
1045
1046 /**
1047 * If aNode is not an element, return true exactly when aContent's binding
1048 * parent is null.
1049 *
1050 * If aNode is an element, return true exactly when aContent's binding parent
1051 * is the same as aNode's.
1052 *
1053 * This method is particularly useful for callers who are trying to ensure
1054 * that they are working with a non-anonymous descendant of a given node. If
1055 * aContent is a descendant of aNode, a return value of false from this
1056 * method means that it's an anonymous descendant from aNode's point of view.
1057 *
1058 * Both arguments to this method must be non-null.
1059 */
1060 static bool IsInSameAnonymousTree(const nsINode* aNode,
1061 const nsIContent* aContent);
1062
1063 /*
1064 * Traverse the parent chain from aElement up to aStop, and return true if
1065 * there's an interactive html content; false otherwise.
1066 *
1067 * Note: This crosses shadow boundaries but not document boundaries.
1068 */
1069 static bool IsInInteractiveHTMLContent(const Element* aElement,
1070 const Element* aStop);
1071
1072 /**
1073 * Return the nsIXPConnect service.
1074 */
XPConnect()1075 static nsIXPConnect* XPConnect() { return sXPConnect; }
1076
1077 /**
1078 * Report simple error message to the browser console
1079 * @param aErrorText the error message
1080 * @param aCategory Name of the module reporting error
1081 * @param aFromPrivateWindow Whether from private window or not
1082 * @param aFromChromeContext Whether from chrome context or not
1083 * @param [aErrorFlags] See nsIScriptError.
1084 */
1085 static void LogSimpleConsoleError(
1086 const nsAString& aErrorText, const char* aCategory,
1087 bool aFromPrivateWindow, bool aFromChromeContext,
1088 uint32_t aErrorFlags = nsIScriptError::errorFlag);
1089
1090 /**
1091 * Report a non-localized error message to the error console.
1092 * @param aErrorText the error message
1093 * @param aErrorFlags See nsIScriptError.
1094 * @param aCategory Name of module reporting error.
1095 * @param aDocument Reference to the document which triggered the message.
1096 * @param [aURI=nullptr] (Optional) URI of resource containing error.
1097 * @param [aSourceLine=u""_ns] (Optional) The text of the line that
1098 contains the error (may be empty).
1099 * @param [aLineNumber=0] (Optional) Line number within resource
1100 containing error.
1101 * @param [aColumnNumber=0] (Optional) Column number within resource
1102 containing error.
1103 If aURI is null, then aDocument->GetDocumentURI() is used.
1104 * @param [aLocationMode] (Optional) Specifies the behavior if
1105 error location information is omitted.
1106 */
1107 enum MissingErrorLocationMode {
1108 // Don't show location information in the error console.
1109 eOMIT_LOCATION,
1110 // Get location information from the currently executing script.
1111 eUSE_CALLING_LOCATION
1112 };
1113 static nsresult ReportToConsoleNonLocalized(
1114 const nsAString& aErrorText, uint32_t aErrorFlags,
1115 const nsACString& aCategory, const Document* aDocument,
1116 nsIURI* aURI = nullptr, const nsString& aSourceLine = u""_ns,
1117 uint32_t aLineNumber = 0, uint32_t aColumnNumber = 0,
1118 MissingErrorLocationMode aLocationMode = eUSE_CALLING_LOCATION);
1119
1120 /**
1121 * Report a non-localized error message to the error console base on the
1122 * innerWindowID.
1123 * @param aErrorText the error message
1124 * @param aErrorFlags See nsIScriptError.
1125 * @param aCategory Name of module reporting error.
1126 * @param [aInnerWindowID] Inner window ID for document which triggered the
1127 * message.
1128 * @param [aURI=nullptr] (Optional) URI of resource containing error.
1129 * @param [aSourceLine=u""_ns] (Optional) The text of the line that
1130 contains the error (may be empty).
1131 * @param [aLineNumber=0] (Optional) Line number within resource
1132 containing error.
1133 * @param [aColumnNumber=0] (Optional) Column number within resource
1134 containing error.
1135 If aURI is null, then aDocument->GetDocumentURI() is used.
1136 * @param [aLocationMode] (Optional) Specifies the behavior if
1137 error location information is omitted.
1138 */
1139 static nsresult ReportToConsoleByWindowID(
1140 const nsAString& aErrorText, uint32_t aErrorFlags,
1141 const nsACString& aCategory, uint64_t aInnerWindowID,
1142 nsIURI* aURI = nullptr, const nsString& aSourceLine = u""_ns,
1143 uint32_t aLineNumber = 0, uint32_t aColumnNumber = 0,
1144 MissingErrorLocationMode aLocationMode = eUSE_CALLING_LOCATION);
1145
1146 /**
1147 * Report a localized error message to the error console.
1148 * @param aErrorFlags See nsIScriptError.
1149 * @param aCategory Name of module reporting error.
1150 * @param aDocument Reference to the document which triggered the message.
1151 * @param aFile Properties file containing localized message.
1152 * @param aMessageName Name of localized message.
1153 * @param [aParams=empty-array] (Optional) Parameters to be substituted into
1154 localized message.
1155 * @param [aURI=nullptr] (Optional) URI of resource containing error.
1156 * @param [aSourceLine=u""_ns] (Optional) The text of the line that
1157 contains the error (may be empty).
1158 * @param [aLineNumber=0] (Optional) Line number within resource
1159 containing error.
1160 * @param [aColumnNumber=0] (Optional) Column number within resource
1161 containing error.
1162 If aURI is null, then aDocument->GetDocumentURI() is used.
1163 */
1164 enum PropertiesFile {
1165 eCSS_PROPERTIES,
1166 eXUL_PROPERTIES,
1167 eLAYOUT_PROPERTIES,
1168 eFORMS_PROPERTIES,
1169 ePRINTING_PROPERTIES,
1170 eDOM_PROPERTIES,
1171 eHTMLPARSER_PROPERTIES,
1172 eSVG_PROPERTIES,
1173 eBRAND_PROPERTIES,
1174 eCOMMON_DIALOG_PROPERTIES,
1175 eMATHML_PROPERTIES,
1176 eSECURITY_PROPERTIES,
1177 eNECKO_PROPERTIES,
1178 eFORMS_PROPERTIES_en_US,
1179 eDOM_PROPERTIES_en_US,
1180 PropertiesFile_COUNT
1181 };
1182 static nsresult ReportToConsole(
1183 uint32_t aErrorFlags, const nsACString& aCategory,
1184 const Document* aDocument, PropertiesFile aFile, const char* aMessageName,
1185 const nsTArray<nsString>& aParams = nsTArray<nsString>(),
1186 nsIURI* aURI = nullptr, const nsString& aSourceLine = u""_ns,
1187 uint32_t aLineNumber = 0, uint32_t aColumnNumber = 0);
1188
1189 static void ReportEmptyGetElementByIdArg(const Document* aDoc);
1190
1191 static void LogMessageToConsole(const char* aMsg);
1192
1193 static bool SpoofLocaleEnglish();
1194
1195 /**
1196 * Get the localized string named |aKey| in properties file |aFile|.
1197 */
1198 static nsresult GetLocalizedString(PropertiesFile aFile, const char* aKey,
1199 nsAString& aResult);
1200
1201 /**
1202 * Same as GetLocalizedString, except that it might use en-US locale depending
1203 * on SpoofLocaleEnglish() and whether the document is a built-in browser
1204 * page.
1205 */
1206 static nsresult GetMaybeLocalizedString(PropertiesFile aFile,
1207 const char* aKey, Document* aDocument,
1208 nsAString& aResult);
1209
1210 /**
1211 * A helper function that parses a sandbox attribute (of an <iframe> or a CSP
1212 * directive) and converts it to the set of flags used internally.
1213 *
1214 * @param aSandboxAttr the sandbox attribute
1215 * @return the set of flags (SANDBOXED_NONE if aSandboxAttr is
1216 * null)
1217 */
1218 static uint32_t ParseSandboxAttributeToFlags(const nsAttrValue* aSandboxAttr);
1219
1220 /**
1221 * A helper function that checks if a string matches a valid sandbox flag.
1222 *
1223 * @param aFlag the potential sandbox flag.
1224 * @return true if the flag is a sandbox flag.
1225 */
1226 static bool IsValidSandboxFlag(const nsAString& aFlag);
1227
1228 /**
1229 * A helper function that returns a string attribute corresponding to the
1230 * sandbox flags.
1231 *
1232 * @param aFlags the sandbox flags
1233 * @param aString the attribute corresponding to the flags (null if aFlags
1234 * is zero)
1235 */
1236 static void SandboxFlagsToString(uint32_t aFlags, nsAString& aString);
1237
1238 /**
1239 * Helper function that generates a UUID.
1240 */
1241 static nsresult GenerateUUIDInPlace(nsID& aUUID);
1242
1243 /**
1244 * Infallable (with an assertion) helper function that generates a UUID.
1245 */
1246 static nsID GenerateUUID();
1247
1248 static bool PrefetchPreloadEnabled(nsIDocShell* aDocShell);
1249
1250 static void ExtractErrorValues(JSContext* aCx, JS::Handle<JS::Value> aValue,
1251 nsAString& aSourceSpecOut, uint32_t* aLineOut,
1252 uint32_t* aColumnOut, nsString& aMessageOut);
1253
1254 // Variant on `ExtractErrorValues` with a `nsACString`. This
1255 // method is provided for backwards compatibility. Prefer the
1256 // faster method above for your code.
1257 static void ExtractErrorValues(JSContext* aCx, JS::Handle<JS::Value> aValue,
1258 nsACString& aSourceSpecOut, uint32_t* aLineOut,
1259 uint32_t* aColumnOut, nsString& aMessageOut);
1260
1261 static nsresult CalculateBufferSizeForImage(
1262 const uint32_t& aStride, const mozilla::gfx::IntSize& aImageSize,
1263 const mozilla::gfx::SurfaceFormat& aFormat, size_t* aMaxBufferSize,
1264 size_t* aUsedBufferSize);
1265
1266 // Returns true if the URI's host is contained in a list which is a comma
1267 // separated domain list. Each item may start with "*.". If starts with
1268 // "*.", it matches any sub-domains.
1269 // The aList argument must be a lower-case string.
1270 static bool IsURIInList(nsIURI* aURI, const nsCString& aList);
1271
1272 // Returns true if the URI's host is contained in a pref list which is a comma
1273 // separated domain list. Each item may start with "*.". If starts with
1274 // "*.", it matches any sub-domains.
1275 static bool IsURIInPrefList(nsIURI* aURI, const char* aPrefName);
1276
1277 /*&
1278 * A convenience version of FormatLocalizedString that can be used if all the
1279 * params are in same-typed strings. The variadic template args need to come
1280 * at the end, so we put aResult at the beginning to make sure it's clear
1281 * which is the output and which are the inputs.
1282 */
1283 template <typename... T>
FormatLocalizedString(nsAString & aResult,PropertiesFile aFile,const char * aKey,const T &...aParams)1284 static nsresult FormatLocalizedString(nsAString& aResult,
1285 PropertiesFile aFile, const char* aKey,
1286 const T&... aParams) {
1287 static_assert(sizeof...(aParams) != 0, "Use GetLocalizedString()");
1288 AutoTArray<nsString, sizeof...(aParams)> params = {
1289 aParams...,
1290 };
1291 return FormatLocalizedString(aFile, aKey, params, aResult);
1292 }
1293
1294 /**
1295 * Same as FormatLocalizedString template version, except that it might use
1296 * en-US locale depending on SpoofLocaleEnglish() and whether the document is
1297 * a built-in browser page.
1298 */
1299 template <typename... T>
FormatMaybeLocalizedString(nsAString & aResult,PropertiesFile aFile,const char * aKey,Document * aDocument,const T &...aParams)1300 static nsresult FormatMaybeLocalizedString(nsAString& aResult,
1301 PropertiesFile aFile,
1302 const char* aKey,
1303 Document* aDocument,
1304 const T&... aParams) {
1305 static_assert(sizeof...(aParams) != 0, "Use GetMaybeLocalizedString()");
1306 AutoTArray<nsString, sizeof...(aParams)> params = {
1307 aParams...,
1308 };
1309 return FormatMaybeLocalizedString(aFile, aKey, aDocument, params, aResult);
1310 }
1311
1312 /**
1313 * Fill (with the parameters given) the localized string named |aKey| in
1314 * properties file |aFile| consuming an nsTArray of nsString parameters rather
1315 * than a char16_t** for the sake of avoiding use-after-free errors involving
1316 * temporaries.
1317 */
1318 static nsresult FormatLocalizedString(PropertiesFile aFile, const char* aKey,
1319 const nsTArray<nsString>& aParamArray,
1320 nsAString& aResult);
1321
1322 /**
1323 * Same as FormatLocalizedString, except that it might use en-US locale
1324 * depending on SpoofLocaleEnglish() and whether the document is a built-in
1325 * browser page.
1326 */
1327 static nsresult FormatMaybeLocalizedString(
1328 PropertiesFile aFile, const char* aKey, Document* aDocument,
1329 const nsTArray<nsString>& aParamArray, nsAString& aResult);
1330
1331 /**
1332 * Returns true if aDocument is a chrome document
1333 */
1334 static bool IsChromeDoc(const Document* aDocument);
1335
1336 /**
1337 * Returns true if aDocument is in a docshell whose parent is the same type
1338 */
1339 static bool IsChildOfSameType(Document* aDoc);
1340
1341 /**
1342 * Returns true if the content-type will be rendered as plain-text.
1343 */
1344 static bool IsPlainTextType(const nsACString& aContentType);
1345
1346 /**
1347 * Returns true iff the type is rendered as plain text and doesn't support
1348 * non-UTF-8 encodings.
1349 */
1350 static bool IsUtf8OnlyPlainTextType(const nsACString& aContentType);
1351
1352 /**
1353 * Returns true if aDocument belongs to a chrome docshell for
1354 * display purposes. Returns false for null documents or documents
1355 * which do not belong to a docshell.
1356 */
1357 static bool IsInChromeDocshell(const Document* aDocument);
1358
1359 /**
1360 * Return the content policy service
1361 */
1362 static nsIContentPolicy* GetContentPolicy();
1363
1364 /**
1365 * Map internal content policy types to external ones.
1366 */
1367 static inline ExtContentPolicyType InternalContentPolicyTypeToExternal(
1368 nsContentPolicyType aType);
1369
1370 /**
1371 * Returns true if the content policy type is any of:
1372 * * TYPE_INTERNAL_SCRIPT_PRELOAD
1373 * * TYPE_INTERNAL_IMAGE_PRELOAD
1374 * * TYPE_INTERNAL_STYLESHEET_PRELOAD
1375 */
1376 static bool IsPreloadType(nsContentPolicyType aType);
1377
1378 /**
1379 * Returns true if the pref "security.mixed_content.upgrade_display_content"
1380 * is true and the content policy type is any of:
1381 * * TYPE_IMAGE
1382 * * TYPE_MEDIA
1383 */
1384 static bool IsUpgradableDisplayType(ExtContentPolicyType aType);
1385
1386 /**
1387 * Quick helper to determine whether there are any mutation listeners
1388 * of a given type that apply to this content or any of its ancestors.
1389 * The method has the side effect to call document's MayDispatchMutationEvent
1390 * using aTargetForSubtreeModified as the parameter.
1391 *
1392 * @param aNode The node to search for listeners
1393 * @param aType The type of listener (NS_EVENT_BITS_MUTATION_*)
1394 * @param aTargetForSubtreeModified The node which is the target of the
1395 * possible DOMSubtreeModified event.
1396 *
1397 * @return true if there are mutation listeners of the specified type
1398 */
1399 static bool HasMutationListeners(nsINode* aNode, uint32_t aType,
1400 nsINode* aTargetForSubtreeModified);
1401
1402 /**
1403 * Quick helper to determine whether there are any mutation listeners
1404 * of a given type that apply to any content in this document. It is valid
1405 * to pass null for aDocument here, in which case this function always
1406 * returns true.
1407 *
1408 * @param aDocument The document to search for listeners
1409 * @param aType The type of listener (NS_EVENT_BITS_MUTATION_*)
1410 *
1411 * @return true if there are mutation listeners of the specified type
1412 */
1413 static bool HasMutationListeners(Document* aDocument, uint32_t aType);
1414 /**
1415 * Synchronously fire DOMNodeRemoved on aChild. Only fires the event if
1416 * there really are listeners by checking using the HasMutationListeners
1417 * function above. The function makes sure to hold the relevant objects alive
1418 * for the duration of the event firing. However there are no guarantees
1419 * that any of the objects are alive by the time the function returns.
1420 * If you depend on that you need to hold references yourself.
1421 *
1422 * @param aChild The node to fire DOMNodeRemoved at.
1423 * @param aParent The parent of aChild.
1424 */
1425 static void MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent);
1426
1427 /**
1428 * These methods create and dispatch a trusted event.
1429 * Works only with events which can be created by calling
1430 * Document::CreateEvent() with parameter "Events".
1431 * Note that don't use these methods for "input" event. Use
1432 * DispatchInputEvent() instead.
1433 *
1434 * @param aDoc The document which will be used to create the event.
1435 * @param aTarget The target of the event, should be QIable to
1436 * EventTarget.
1437 * @param aEventName The name of the event.
1438 * @param aCanBubble Whether the event can bubble.
1439 * @param aCancelable Is the event cancelable.
1440 * @param aCopmosed Is the event composed.
1441 * @param aDefaultAction Set to true if default action should be taken,
1442 * see EventTarget::DispatchEvent.
1443 */
1444 // TODO: annotate with `MOZ_CAN_RUN_SCRIPT`
1445 // (https://bugzilla.mozilla.org/show_bug.cgi?id=1625902).
1446 static nsresult DispatchTrustedEvent(Document* aDoc, nsISupports* aTarget,
1447 const nsAString& aEventName, CanBubble,
1448 Cancelable,
1449 Composed aComposed = Composed::eDefault,
1450 bool* aDefaultAction = nullptr);
1451
1452 // TODO: annotate with `MOZ_CAN_RUN_SCRIPT`
1453 // (https://bugzilla.mozilla.org/show_bug.cgi?id=1625902).
DispatchTrustedEvent(Document * aDoc,nsISupports * aTarget,const nsAString & aEventName,CanBubble aCanBubble,Cancelable aCancelable,bool * aDefaultAction)1454 static nsresult DispatchTrustedEvent(Document* aDoc, nsISupports* aTarget,
1455 const nsAString& aEventName,
1456 CanBubble aCanBubble,
1457 Cancelable aCancelable,
1458 bool* aDefaultAction) {
1459 return DispatchTrustedEvent(aDoc, aTarget, aEventName, aCanBubble,
1460 aCancelable, Composed::eDefault,
1461 aDefaultAction);
1462 }
1463
1464 /**
1465 * This method creates and dispatches a trusted event using an event message.
1466 * @param aDoc The document which will be used to create the event.
1467 * @param aTarget The target of the event, should be QIable to
1468 * EventTarget.
1469 * @param aEventMessage The event message.
1470 * @param aCanBubble Whether the event can bubble.
1471 * @param aCancelable Is the event cancelable.
1472 * @param aDefaultAction Set to true if default action should be taken,
1473 * see EventTarget::DispatchEvent.
1474 */
1475 template <class WidgetEventType>
1476 static nsresult DispatchTrustedEvent(
1477 Document* aDoc, nsISupports* aTarget, EventMessage aEventMessage,
1478 CanBubble aCanBubble, Cancelable aCancelable,
1479 bool* aDefaultAction = nullptr,
1480 ChromeOnlyDispatch aOnlyChromeDispatch = ChromeOnlyDispatch::eNo) {
1481 WidgetEventType event(true, aEventMessage);
1482 MOZ_ASSERT(GetEventClassIDFromMessage(aEventMessage) == event.mClass);
1483 return DispatchEvent(aDoc, aTarget, event, aEventMessage, aCanBubble,
1484 aCancelable, Trusted::eYes, aDefaultAction,
1485 aOnlyChromeDispatch);
1486 }
1487
1488 /**
1489 * This method dispatches "beforeinput" event with EditorInputEvent or
1490 * "input" event with proper event class. If it's unsafe to dispatch,
1491 * this put the event into the script runner queue. In such case, the
1492 * event becomes not cancelable even if it's defined as cancelable by
1493 * the spec.
1494 * Input Events spec defines as:
1495 * Input events are dispatched on elements that act as editing hosts,
1496 * including elements with the contenteditable attribute set, textarea
1497 * elements, and input elements that permit text input.
1498 *
1499 * @param aEventTarget The event target element of the "beforeinput"
1500 * or "input" event. Must not be nullptr.
1501 * @param aEventMessage Muse be eEditorBeforeInput or eEditorInput.
1502 * @param aEditorInputType The inputType value of InputEvent.
1503 * If aEventTarget won't dispatch "input" event
1504 * with InputEvent, set EditorInputType::eUnknown.
1505 * @param aEditorBase Optional. If this is called by editor,
1506 * editor should set this. Otherwise, leave
1507 * nullptr.
1508 * @param aOptions Optional. If aEditorInputType value requires
1509 * some additional data, they should be properly
1510 * set with this argument.
1511 * @param aEventStatus Returns nsEventStatus_eConsumeNoDefault if
1512 * the dispatching event is cancelable and the
1513 * event was canceled by script (including
1514 * chrome script). Otherwise, returns given
1515 * value. Note that this can be nullptr only
1516 * when the dispatching event is not cancelable.
1517 */
1518 MOZ_CAN_RUN_SCRIPT static nsresult DispatchInputEvent(Element* aEventTarget);
1519 MOZ_CAN_RUN_SCRIPT static nsresult DispatchInputEvent(
1520 Element* aEventTarget, mozilla::EventMessage aEventMessage,
1521 mozilla::EditorInputType aEditorInputType,
1522 mozilla::EditorBase* aEditorBase, mozilla::InputEventOptions&& aOptions,
1523 nsEventStatus* aEventStatus = nullptr);
1524
1525 /**
1526 * This method creates and dispatches a untrusted event.
1527 * Works only with events which can be created by calling
1528 * Document::CreateEvent() with parameter "Events".
1529 * @param aDoc The document which will be used to create the event.
1530 * @param aTarget The target of the event, should be QIable to
1531 * EventTarget.
1532 * @param aEventName The name of the event.
1533 * @param aCanBubble Whether the event can bubble.
1534 * @param aCancelable Is the event cancelable.
1535 * @param aDefaultAction Set to true if default action should be taken,
1536 * see EventTarget::DispatchEvent.
1537 */
1538 static nsresult DispatchUntrustedEvent(Document* aDoc, nsISupports* aTarget,
1539 const nsAString& aEventName, CanBubble,
1540 Cancelable,
1541 bool* aDefaultAction = nullptr);
1542
1543 /**
1544 * This method creates and dispatches a untrusted event using an event
1545 * message.
1546 * @param aDoc The document which will be used to create the event.
1547 * @param aTarget The target of the event, should be QIable to
1548 * EventTarget.
1549 * @param aEventMessage The event message.
1550 * @param aCanBubble Whether the event can bubble.
1551 * @param aCancelable Is the event cancelable.
1552 * @param aDefaultAction Set to true if default action should be taken,
1553 * see EventTarget::DispatchEvent.
1554 */
1555 template <class WidgetEventType>
1556 static nsresult DispatchUntrustedEvent(
1557 Document* aDoc, nsISupports* aTarget, EventMessage aEventMessage,
1558 CanBubble aCanBubble, Cancelable aCancelable,
1559 bool* aDefaultAction = nullptr,
1560 ChromeOnlyDispatch aOnlyChromeDispatch = ChromeOnlyDispatch::eNo) {
1561 WidgetEventType event(false, aEventMessage);
1562 MOZ_ASSERT(GetEventClassIDFromMessage(aEventMessage) == event.mClass);
1563 return DispatchEvent(aDoc, aTarget, event, aEventMessage, aCanBubble,
1564 aCancelable, Trusted::eNo, aDefaultAction,
1565 aOnlyChromeDispatch);
1566 }
1567
1568 /**
1569 * This method creates and dispatches a trusted event to the chrome
1570 * event handler (the parent object of the DOM Window in the event target
1571 * chain). Note, chrome event handler is used even if aTarget is a chrome
1572 * object. Use DispatchEventOnlyToChrome if the normal event dispatching is
1573 * wanted in case aTarget is a chrome object.
1574 * Works only with events which can be created by calling
1575 * Document::CreateEvent() with parameter "Events".
1576 * @param aDocument The document which will be used to create the event,
1577 * and whose window's chrome handler will be used to
1578 * dispatch the event.
1579 * @param aTarget The target of the event, used for event->SetTarget()
1580 * @param aEventName The name of the event.
1581 * @param aCanBubble Whether the event can bubble.
1582 * @param aCancelable Is the event cancelable.
1583 * @param aDefaultAction Set to true if default action should be taken,
1584 * see EventTarget::DispatchEvent.
1585 */
1586 static nsresult DispatchChromeEvent(Document* aDoc, nsISupports* aTarget,
1587 const nsAString& aEventName, CanBubble,
1588 Cancelable,
1589 bool* aDefaultAction = nullptr);
1590
1591 /**
1592 * Helper to dispatch a "framefocusrequested" event to chrome, which will only
1593 * bring the window to the foreground and switch tabs if aCanRaise is true.
1594 */
1595 MOZ_CAN_RUN_SCRIPT_BOUNDARY static void RequestFrameFocus(
1596 Element& aFrameElement, bool aCanRaise,
1597 mozilla::dom::CallerType aCallerType);
1598
1599 /**
1600 * This method creates and dispatches a trusted event.
1601 * If aTarget is not a chrome object, the nearest chrome object in the
1602 * propagation path will be used as the start of the event target chain.
1603 * This method is different than DispatchChromeEvent, which always dispatches
1604 * events to chrome event handler. DispatchEventOnlyToChrome works like
1605 * DispatchTrustedEvent in the case aTarget is a chrome object.
1606 * Works only with events which can be created by calling
1607 * Document::CreateEvent() with parameter "Events".
1608 * @param aDoc The document which will be used to create the event.
1609 * @param aTarget The target of the event, should be QIable to
1610 * EventTarget.
1611 * @param aEventName The name of the event.
1612 * @param aCanBubble Whether the event can bubble.
1613 * @param aCancelable Is the event cancelable.
1614 * @param aComposed Is the event composed.
1615 * @param aDefaultAction Set to true if default action should be taken,
1616 * see EventTarget::DispatchEvent.
1617 */
1618 static nsresult DispatchEventOnlyToChrome(
1619 Document* aDoc, nsISupports* aTarget, const nsAString& aEventName,
1620 CanBubble, Cancelable, Composed aComposed = Composed::eDefault,
1621 bool* aDefaultAction = nullptr);
1622
DispatchEventOnlyToChrome(Document * aDoc,nsISupports * aTarget,const nsAString & aEventName,CanBubble aCanBubble,Cancelable aCancelable,bool * aDefaultAction)1623 static nsresult DispatchEventOnlyToChrome(
1624 Document* aDoc, nsISupports* aTarget, const nsAString& aEventName,
1625 CanBubble aCanBubble, Cancelable aCancelable, bool* aDefaultAction) {
1626 return DispatchEventOnlyToChrome(aDoc, aTarget, aEventName, aCanBubble,
1627 aCancelable, Composed::eDefault,
1628 aDefaultAction);
1629 }
1630
1631 /**
1632 * Determines if an event attribute name (such as onclick) is valid for
1633 * a given element type. Types are from the EventNameType enumeration
1634 * defined above.
1635 *
1636 * @param aName the event name to look up
1637 * @param aType the type of content
1638 */
1639 static bool IsEventAttributeName(nsAtom* aName, int32_t aType);
1640
1641 /**
1642 * Return the event message for the event with the given name. The name is
1643 * the event name with the 'on' prefix. Returns eUnidentifiedEvent if the
1644 * event doesn't match a known event name.
1645 *
1646 * @param aName the event name to look up
1647 */
1648 static EventMessage GetEventMessage(nsAtom* aName);
1649
1650 /**
1651 * Returns the EventMessage and nsAtom to be used for event listener
1652 * registration.
1653 */
1654 static EventMessage GetEventMessageAndAtomForListener(const nsAString& aName,
1655 nsAtom** aOnName);
1656
1657 /**
1658 * Return the EventClassID for the event with the given name. The name is the
1659 * event name *without* the 'on' prefix. Returns eBasicEventClass if the event
1660 * is not known to be of any particular event class.
1661 *
1662 * @param aName the event name to look up
1663 */
1664 static mozilla::EventClassID GetEventClassID(const nsAString& aName);
1665
1666 /**
1667 * Return the event message and atom for the event with the given name.
1668 * The name is the event name *without* the 'on' prefix.
1669 * Returns eUnidentifiedEvent on the aEventID if the
1670 * event doesn't match a known event name in the category.
1671 *
1672 * @param aName the event name to look up
1673 * @param aEventClassID only return event id for aEventClassID
1674 */
1675 static nsAtom* GetEventMessageAndAtom(const nsAString& aName,
1676 mozilla::EventClassID aEventClassID,
1677 EventMessage* aEventMessage);
1678
1679 /**
1680 * Used only during traversal of the XPCOM graph by the cycle
1681 * collector: push a pointer to the listener manager onto the
1682 * children deque, if it exists. Do nothing if there is no listener
1683 * manager.
1684 *
1685 * Crucially: does not perform any refcounting operations.
1686 *
1687 * @param aNode The node to traverse.
1688 * @param children The buffer to push a listener manager pointer into.
1689 */
1690 static void TraverseListenerManager(nsINode* aNode,
1691 nsCycleCollectionTraversalCallback& cb);
1692
1693 /**
1694 * Get the eventlistener manager for aNode, creating it if it does not
1695 * already exist.
1696 *
1697 * @param aNode The node for which to get the eventlistener manager.
1698 */
1699 static mozilla::EventListenerManager* GetListenerManagerForNode(
1700 nsINode* aNode);
1701 /**
1702 * Get the eventlistener manager for aNode, returning null if it does not
1703 * already exist.
1704 *
1705 * @param aNode The node for which to get the eventlistener manager.
1706 */
1707 static mozilla::EventListenerManager* GetExistingListenerManagerForNode(
1708 const nsINode* aNode);
1709
1710 static void AddEntryToDOMArenaTable(nsINode* aNode,
1711 mozilla::dom::DOMArena* aDOMArena);
1712
1713 static already_AddRefed<mozilla::dom::DOMArena> TakeEntryFromDOMArenaTable(
1714 const nsINode* aNode);
1715
1716 static void UnmarkGrayJSListenersInCCGenerationDocuments();
1717
1718 /**
1719 * Remove the eventlistener manager for aNode.
1720 *
1721 * @param aNode The node for which to remove the eventlistener manager.
1722 */
1723 static void RemoveListenerManager(nsINode* aNode);
1724
IsInitialized()1725 static bool IsInitialized() { return sInitialized; }
1726
1727 /**
1728 * Checks if the localname/prefix/namespace triple is valid wrt prefix
1729 * and namespace according to the Namespaces in XML and DOM Code
1730 * specfications.
1731 *
1732 * @param aLocalname localname of the node
1733 * @param aPrefix prefix of the node
1734 * @param aNamespaceID namespace of the node
1735 */
1736 static bool IsValidNodeName(nsAtom* aLocalName, nsAtom* aPrefix,
1737 int32_t aNamespaceID);
1738
1739 /**
1740 * Creates a DocumentFragment from text using a context node to resolve
1741 * namespaces.
1742 *
1743 * Please note that for safety reasons, if the node principal of
1744 * aContextNode is the system principal, this function will automatically
1745 * sanitize its input using nsTreeSanitizer.
1746 *
1747 * Note! In the HTML case with the HTML5 parser enabled, this is only called
1748 * from Range.createContextualFragment() and the implementation here is
1749 * quirky accordingly (html context node behaves like a body context node).
1750 * If you don't want that quirky behavior, don't use this method as-is!
1751 *
1752 * @param aContextNode the node which is used to resolve namespaces
1753 * @param aFragment the string which is parsed to a DocumentFragment
1754 * @param aReturn the resulting fragment
1755 * @param aPreventScriptExecution whether to mark scripts as already started
1756 */
1757 static already_AddRefed<mozilla::dom::DocumentFragment>
1758 CreateContextualFragment(nsINode* aContextNode, const nsAString& aFragment,
1759 bool aPreventScriptExecution,
1760 mozilla::ErrorResult& aRv);
1761
1762 /**
1763 * Invoke the fragment parsing algorithm (innerHTML) using the HTML parser.
1764 *
1765 * Please note that for safety reasons, if the node principal of aTargetNode
1766 * is the system principal, this function will automatically sanitize its
1767 * input using nsTreeSanitizer.
1768 *
1769 * @param aSourceBuffer the string being set as innerHTML
1770 * @param aTargetNode the target container
1771 * @param aContextLocalName local name of context node
1772 * @param aContextNamespace namespace of context node
1773 * @param aQuirks true to make <table> not close <p>
1774 * @param aPreventScriptExecution true to prevent scripts from executing;
1775 * don't set to false when parsing into a target node that has been
1776 * bound to tree.
1777 * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
1778 * fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
1779 * long and NS_OK otherwise.
1780 * @param aFlags defaults to -1 indicating that ParseFragmentHTML will do
1781 * default sanitization for system privileged calls to it. Only
1782 * ParserUtils::ParseFragment() should ever pass explicit aFlags
1783 * which will then used for sanitization of the fragment.
1784 * To pass explicit aFlags use any of the sanitization flags
1785 * listed in nsIParserUtils.idl.
1786 */
1787 static nsresult ParseFragmentHTML(const nsAString& aSourceBuffer,
1788 nsIContent* aTargetNode,
1789 nsAtom* aContextLocalName,
1790 int32_t aContextNamespace, bool aQuirks,
1791 bool aPreventScriptExecution,
1792 int32_t aFlags = -1);
1793
1794 /**
1795 * Invoke the fragment parsing algorithm (innerHTML) using the XML parser.
1796 *
1797 * Please note that for safety reasons, if the node principal of aDocument
1798 * is the system principal, this function will automatically sanitize its
1799 * input using nsTreeSanitizer.
1800 *
1801 * @param aSourceBuffer the string being set as innerHTML
1802 * @param aDocument the target document
1803 * @param aTagStack the namespace mapping context
1804 * @param aPreventExecution whether to mark scripts as already started
1805 * @param aFlags, pass -1 and ParseFragmentXML will do default
1806 * sanitization for system privileged calls to it. Only
1807 * ParserUtils::ParseFragment() should ever pass explicit aFlags
1808 * which will then used for sanitization of the fragment.
1809 * To pass explicit aFlags use any of the sanitization flags
1810 * listed in nsIParserUtils.idl.
1811 * @param aReturn the result fragment
1812 * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
1813 * fragments is made, a return code from the XML parser.
1814 */
1815 static nsresult ParseFragmentXML(const nsAString& aSourceBuffer,
1816 Document* aDocument,
1817 nsTArray<nsString>& aTagStack,
1818 bool aPreventScriptExecution, int32_t aFlags,
1819 mozilla::dom::DocumentFragment** aReturn);
1820
1821 /**
1822 * Parse a string into a document using the HTML parser.
1823 * Script elements are marked unexecutable.
1824 *
1825 * @param aSourceBuffer the string to parse as an HTML document
1826 * @param aTargetDocument the document object to parse into. Must not have
1827 * child nodes.
1828 * @param aScriptingEnabledForNoscriptParsing whether <noscript> is parsed
1829 * as if scripting was enabled
1830 * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
1831 * fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
1832 * long and NS_OK otherwise.
1833 */
1834 static nsresult ParseDocumentHTML(const nsAString& aSourceBuffer,
1835 Document* aTargetDocument,
1836 bool aScriptingEnabledForNoscriptParsing);
1837
1838 /**
1839 * Converts HTML source to plain text by parsing the source and using the
1840 * plain text serializer on the resulting tree.
1841 *
1842 * @param aSourceBuffer the string to parse as an HTML document
1843 * @param aResultBuffer the string where the plain text result appears;
1844 * may be the same string as aSourceBuffer
1845 * @param aFlags Flags from nsIDocumentEncoder.
1846 * @param aWrapCol Number of columns after which to line wrap; 0 for no
1847 * auto-wrapping
1848 * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
1849 * fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
1850 * long and NS_OK otherwise.
1851 */
1852 static nsresult ConvertToPlainText(const nsAString& aSourceBuffer,
1853 nsAString& aResultBuffer, uint32_t aFlags,
1854 uint32_t aWrapCol);
1855
1856 /**
1857 * Creates a 'loaded-as-data' HTML document that takes that principal,
1858 * script global, and URL from the argument, which may be null.
1859 */
1860 static already_AddRefed<Document> CreateInertHTMLDocument(
1861 const Document* aTemplate);
1862
1863 /**
1864 * Creates a 'loaded-as-data' XML document that takes that principal,
1865 * script global, and URL from the argument, which may be null.
1866 */
1867 static already_AddRefed<Document> CreateInertXMLDocument(
1868 const Document* aTemplate);
1869
1870 public:
1871 /**
1872 * Sets the text contents of a node by replacing all existing children
1873 * with a single text child.
1874 *
1875 * The function always notifies.
1876 *
1877 * Will reuse the first text child if one is available. Will not reuse
1878 * existing cdata children.
1879 *
1880 * @param aContent Node to set contents of.
1881 * @param aValue Value to set contents to.
1882 * @param aTryReuse When true, the function will try to reuse an existing
1883 * textnodes rather than always creating a new one.
1884 */
1885 static nsresult SetNodeTextContent(nsIContent* aContent,
1886 const nsAString& aValue, bool aTryReuse);
1887
1888 /**
1889 * Get the textual contents of a node. This is a concatenation of all
1890 * textnodes that are direct or (depending on aDeep) indirect children
1891 * of the node.
1892 *
1893 * NOTE! No serialization takes place and <br> elements
1894 * are not converted into newlines. Only textnodes and cdata nodes are
1895 * added to the result.
1896 *
1897 * @see nsLayoutUtils::GetFrameTextContent
1898 *
1899 * @param aNode Node to get textual contents of.
1900 * @param aDeep If true child elements of aNode are recursivly descended
1901 * into to find text children.
1902 * @param aResult the result. Out param.
1903 * @return false on out of memory errors, true otherwise.
1904 */
1905 [[nodiscard]] static bool GetNodeTextContent(nsINode* aNode, bool aDeep,
1906 nsAString& aResult,
1907 const mozilla::fallible_t&);
1908
1909 static void GetNodeTextContent(nsINode* aNode, bool aDeep,
1910 nsAString& aResult);
1911
1912 /**
1913 * Same as GetNodeTextContents but appends the result rather than sets it.
1914 */
1915 static bool AppendNodeTextContent(nsINode* aNode, bool aDeep,
1916 nsAString& aResult,
1917 const mozilla::fallible_t&);
1918
1919 /**
1920 * Utility method that checks if a given node has any non-empty children. This
1921 * method does not descend recursively into children by default.
1922 *
1923 * @param aDiscoverMode Set to eRecurseIntoChildren to descend recursively
1924 * into children.
1925 */
1926 enum TextContentDiscoverMode : uint8_t {
1927 eRecurseIntoChildren,
1928 eDontRecurseIntoChildren
1929 };
1930
1931 static bool HasNonEmptyTextContent(
1932 nsINode* aNode,
1933 TextContentDiscoverMode aDiscoverMode = eDontRecurseIntoChildren);
1934
1935 /**
1936 * Delete strings allocated for nsContentList matches
1937 */
1938 static void DestroyMatchString(void* aData);
1939
1940 /*
1941 * Notify when the first XUL menu is opened and when the all XUL menus are
1942 * closed. At opening, aInstalling should be TRUE, otherwise, it should be
1943 * FALSE.
1944 */
1945 static void NotifyInstalledMenuKeyboardListener(bool aInstalling);
1946
1947 /**
1948 * Check whether the nsIURI uses the given scheme.
1949 *
1950 * Note that this will check the innermost URI rather than that of
1951 * the nsIURI itself.
1952 */
1953 static bool SchemeIs(nsIURI* aURI, const char* aScheme);
1954
1955 /**
1956 * Returns true if aPrincipal is an ExpandedPrincipal.
1957 */
1958 static bool IsExpandedPrincipal(nsIPrincipal* aPrincipal);
1959
1960 /**
1961 * Returns true if aPrincipal is the system or an ExpandedPrincipal.
1962 */
1963 static bool IsSystemOrExpandedPrincipal(nsIPrincipal* aPrincipal);
1964
1965 /**
1966 * Gets the system principal from the security manager.
1967 */
1968 static nsIPrincipal* GetSystemPrincipal();
1969
1970 /**
1971 * Gets the null subject principal singleton. This is only useful for
1972 * assertions.
1973 */
GetNullSubjectPrincipal()1974 static nsIPrincipal* GetNullSubjectPrincipal() {
1975 return sNullSubjectPrincipal;
1976 }
1977
1978 /**
1979 * *aResourcePrincipal is a principal describing who may access the contents
1980 * of a resource. The resource can only be consumed by a principal that
1981 * subsumes *aResourcePrincipal. MAKE SURE THAT NOTHING EVER ACTS WITH THE
1982 * AUTHORITY OF *aResourcePrincipal.
1983 * It may be null to indicate that the resource has no data from any origin
1984 * in it yet and anything may access the resource.
1985 * Additional data is being mixed into the resource from aExtraPrincipal
1986 * (which may be null; if null, no data is being mixed in and this function
1987 * will do nothing). Update *aResourcePrincipal to reflect the new data.
1988 * If *aResourcePrincipal subsumes aExtraPrincipal, nothing needs to change,
1989 * otherwise *aResourcePrincipal is replaced with the system principal.
1990 * Returns true if *aResourcePrincipal changed.
1991 */
1992 static bool CombineResourcePrincipals(
1993 nsCOMPtr<nsIPrincipal>* aResourcePrincipal,
1994 nsIPrincipal* aExtraPrincipal);
1995
1996 /**
1997 * Trigger a link with uri aLinkURI. If aClick is false, this triggers a
1998 * mouseover on the link, otherwise it triggers a load after doing a
1999 * security check using aContent's principal.
2000 *
2001 * @param aContent the node on which a link was triggered.
2002 * @param aLinkURI the URI of the link, must be non-null.
2003 * @param aTargetSpec the target (like target=, may be empty).
2004 * @param aClick whether this was a click or not (if false, this method
2005 * assumes you just hovered over the link).
2006 * @param aIsTrusted If false, JS Context will be pushed to stack
2007 * when the link is triggered.
2008 */
2009 static void TriggerLink(nsIContent* aContent, nsIURI* aLinkURI,
2010 const nsString& aTargetSpec, bool aClick,
2011 bool aIsTrusted);
2012
2013 /**
2014 * Get the link location.
2015 */
2016 static void GetLinkLocation(mozilla::dom::Element* aElement,
2017 nsString& aLocationString);
2018
2019 /**
2020 * Return top-level widget in the parent chain.
2021 */
2022 static nsIWidget* GetTopLevelWidget(nsIWidget* aWidget);
2023
2024 /**
2025 * Return the localized ellipsis for UI.
2026 */
2027 static const nsDependentString GetLocalizedEllipsis();
2028
2029 /**
2030 * Hide any XUL popups associated with aDocument, including any documents
2031 * displayed in child frames. Does nothing if aDocument is null.
2032 */
2033 static void HidePopupsInDocument(Document* aDocument);
2034
2035 /**
2036 * Retrieve the current drag session, or null if no drag is currently occuring
2037 */
2038 static already_AddRefed<nsIDragSession> GetDragSession();
2039
2040 /*
2041 * Initialize and set the dataTransfer field of an WidgetDragEvent.
2042 */
2043 static nsresult SetDataTransferInEvent(mozilla::WidgetDragEvent* aDragEvent);
2044
2045 // filters the drag and drop action to fit within the effects allowed and
2046 // returns it.
2047 static uint32_t FilterDropEffect(uint32_t aAction, uint32_t aEffectAllowed);
2048
2049 /*
2050 * Return true if the target of a drop event is a content document that is
2051 * an ancestor of the document for the source of the drag.
2052 */
2053 static bool CheckForSubFrameDrop(nsIDragSession* aDragSession,
2054 mozilla::WidgetDragEvent* aDropEvent);
2055
2056 /**
2057 * Return true if aURI is a local file URI (i.e. file://).
2058 */
2059 static bool URIIsLocalFile(nsIURI* aURI);
2060
2061 /**
2062 * Get the application manifest URI for this document. The manifest URI
2063 * is specified in the manifest= attribute of the root element of the
2064 * document.
2065 *
2066 * @param aDocument The document that lists the manifest.
2067 * @param aURI The manifest URI.
2068 */
2069 static void GetOfflineAppManifest(Document* aDocument, nsIURI** aURI);
2070
2071 /**
2072 * Check whether an application should be allowed to use offline APIs.
2073 */
2074 static bool OfflineAppAllowed(nsIURI* aURI);
2075
2076 /**
2077 * Check whether an application should be allowed to use offline APIs.
2078 */
2079 static bool OfflineAppAllowed(nsIPrincipal* aPrincipal);
2080
2081 /**
2082 * Determine whether the principal or document is allowed access to the
2083 * localization system. We don't want the web to ever see this but all our UI
2084 * including in content pages should pass this test. aDocumentURI may be
2085 * null.
2086 */
2087 static bool PrincipalAllowsL10n(nsIPrincipal& aPrincipal,
2088 nsIURI* aDocumentURI);
2089
2090 /**
2091 * Increases the count of blockers preventing scripts from running.
2092 * NOTE: You might want to use nsAutoScriptBlocker rather than calling
2093 * this directly
2094 */
2095 static void AddScriptBlocker();
2096
2097 /**
2098 * Decreases the count of blockers preventing scripts from running.
2099 * NOTE: You might want to use nsAutoScriptBlocker rather than calling
2100 * this directly
2101 *
2102 * WARNING! Calling this function could synchronously execute scripts.
2103 */
2104 static void RemoveScriptBlocker();
2105
2106 /**
2107 * Add a runnable that is to be executed as soon as it's safe to execute
2108 * scripts.
2109 * NOTE: If it's currently safe to execute scripts, aRunnable will be run
2110 * synchronously before the function returns.
2111 *
2112 * @param aRunnable The nsIRunnable to run as soon as it's safe to execute
2113 * scripts. Passing null is allowed and results in nothing
2114 * happening. It is also allowed to pass an object that
2115 * has not yet been AddRefed.
2116 */
2117 static void AddScriptRunner(already_AddRefed<nsIRunnable> aRunnable);
2118 static void AddScriptRunner(nsIRunnable* aRunnable);
2119
2120 /**
2121 * Returns true if it's safe to execute content script and false otherwise.
2122 *
2123 * The only known case where this lies is mutation events. They run, and can
2124 * run anything else, when this function returns false, but this is ok.
2125 */
2126 static bool IsSafeToRunScript();
2127
2128 // Returns the browser window with the most recent time stamp that is
2129 // not in private browsing mode.
2130 static already_AddRefed<nsPIDOMWindowOuter> GetMostRecentNonPBWindow();
2131
2132 /**
2133 * Call this function if !IsSafeToRunScript() and we fail to run the script
2134 * (rather than using AddScriptRunner as we usually do). |aDocument| is
2135 * optional as it is only used for showing the URL in the console.
2136 */
2137 static void WarnScriptWasIgnored(Document* aDocument);
2138
2139 /**
2140 * Add a "synchronous section", in the form of an nsIRunnable run once the
2141 * event loop has reached a "stable state". |aRunnable| must not cause any
2142 * queued events to be processed (i.e. must not spin the event loop).
2143 * We've reached a stable state when the currently executing task/event has
2144 * finished, see
2145 * http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#synchronous-section
2146 * In practice this runs aRunnable once the currently executing event
2147 * finishes. If called multiple times per task/event, all the runnables will
2148 * be executed, in the order in which RunInStableState() was called.
2149 */
2150 static void RunInStableState(already_AddRefed<nsIRunnable> aRunnable);
2151
2152 /* Add a pending IDBTransaction to be cleaned up at the end of performing a
2153 * microtask checkpoint.
2154 * See the step of "Cleanup Indexed Database Transactions" in
2155 * https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint
2156 */
2157 static void AddPendingIDBTransaction(
2158 already_AddRefed<nsIRunnable> aTransaction);
2159
2160 /**
2161 * Returns true if we are doing StableState/MetastableState.
2162 */
2163 static bool IsInStableOrMetaStableState();
2164
2165 static JSContext* GetCurrentJSContext();
2166
2167 /**
2168 * Case insensitive comparison between two atoms.
2169 */
2170 static bool EqualsIgnoreASCIICase(nsAtom* aAtom1, nsAtom* aAtom2);
2171
2172 /**
2173 * Case insensitive comparison between two strings. However it only ignores
2174 * case for ASCII characters a-z.
2175 */
2176 static bool EqualsIgnoreASCIICase(const nsAString& aStr1,
2177 const nsAString& aStr2);
2178
2179 /**
2180 * Convert ASCII A-Z to a-z.
2181 */
2182 static void ASCIIToLower(nsAString& aStr);
2183 static void ASCIIToLower(nsACString& aStr);
2184 static void ASCIIToLower(const nsAString& aSource, nsAString& aDest);
2185 static void ASCIIToLower(const nsACString& aSource, nsACString& aDest);
2186
2187 /**
2188 * Convert ASCII a-z to A-Z.
2189 */
2190 static void ASCIIToUpper(nsAString& aStr);
2191 static void ASCIIToUpper(nsACString& aStr);
2192 static void ASCIIToUpper(const nsAString& aSource, nsAString& aDest);
2193 static void ASCIIToUpper(const nsACString& aSource, nsACString& aDest);
2194
2195 /**
2196 * Return whether aStr contains an ASCII uppercase character.
2197 */
2198 static bool StringContainsASCIIUpper(const nsAString& aStr);
2199
2200 // Returns NS_OK for same origin, error (NS_ERROR_DOM_BAD_URI) if not.
2201 static nsresult CheckSameOrigin(nsIChannel* aOldChannel,
2202 nsIChannel* aNewChannel);
2203 static nsIInterfaceRequestor* SameOriginChecker();
2204
2205 /**
2206 * Get the Origin of the passed in nsIPrincipal or nsIURI. If the passed in
2207 * nsIURI or the URI of the passed in nsIPrincipal does not have a host, the
2208 * origin is set to 'null'.
2209 *
2210 * The ASCII versions return a ASCII strings that are puny-code encoded,
2211 * suitable for, for example, header values. The UTF versions return strings
2212 * containing international characters.
2213 *
2214 * The thread-safe versions return NS_ERROR_UNKNOWN_PROTOCOL if the
2215 * operation cannot be completed on the current thread.
2216 *
2217 * @pre aPrincipal/aOrigin must not be null.
2218 *
2219 * @note this should be used for HTML5 origin determination.
2220 */
2221 static nsresult GetASCIIOrigin(nsIURI* aURI, nsACString& aOrigin);
2222 static nsresult GetUTFOrigin(nsIPrincipal* aPrincipal, nsAString& aOrigin);
2223 static nsresult GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin);
2224
2225 /**
2226 * This method creates and dispatches "command" event, which implements
2227 * XULCommandEvent.
2228 * If aPresShell is not null, dispatching goes via
2229 * PresShell::HandleDOMEventWithTarget().
2230 */
2231 MOZ_CAN_RUN_SCRIPT
2232 static nsresult DispatchXULCommand(
2233 nsIContent* aTarget, bool aTrusted,
2234 mozilla::dom::Event* aSourceEvent = nullptr,
2235 mozilla::PresShell* aPresShell = nullptr, bool aCtrl = false,
2236 bool aAlt = false, bool aShift = false, bool aMeta = false,
2237 // Including MouseEventBinding here leads
2238 // to incude loops, unfortunately.
2239 uint16_t inputSource = 0 /* MouseEvent_Binding::MOZ_SOURCE_UNKNOWN */,
2240 int16_t aButton = 0);
2241
2242 static bool CheckMayLoad(nsIPrincipal* aPrincipal, nsIChannel* aChannel,
2243 bool aAllowIfInheritsPrincipal);
2244
2245 /**
2246 * The method checks whether the caller can access native anonymous content.
2247 * If there is no JS in the stack or privileged JS is running, this
2248 * method returns true, otherwise false.
2249 */
2250 static bool CanAccessNativeAnon();
2251
2252 [[nodiscard]] static nsresult WrapNative(JSContext* cx, nsISupports* native,
2253 const nsIID* aIID,
2254 JS::MutableHandle<JS::Value> vp,
2255 bool aAllowWrapping = true) {
2256 return WrapNative(cx, native, nullptr, aIID, vp, aAllowWrapping);
2257 }
2258
2259 // Same as the WrapNative above, but use this one if aIID is nsISupports' IID.
2260 [[nodiscard]] static nsresult WrapNative(JSContext* cx, nsISupports* native,
2261 JS::MutableHandle<JS::Value> vp,
2262 bool aAllowWrapping = true) {
2263 return WrapNative(cx, native, nullptr, nullptr, vp, aAllowWrapping);
2264 }
2265
2266 [[nodiscard]] static nsresult WrapNative(JSContext* cx, nsISupports* native,
2267 nsWrapperCache* cache,
2268 JS::MutableHandle<JS::Value> vp,
2269 bool aAllowWrapping = true) {
2270 return WrapNative(cx, native, cache, nullptr, vp, aAllowWrapping);
2271 }
2272
2273 /**
2274 * Creates an arraybuffer from a binary string.
2275 */
2276 static nsresult CreateArrayBuffer(JSContext* aCx, const nsACString& aData,
2277 JSObject** aResult);
2278
2279 static void StripNullChars(const nsAString& aInStr, nsAString& aOutStr);
2280
2281 /**
2282 * Strip all \n, \r and nulls from the given string
2283 * @param aString the string to remove newlines from [in/out]
2284 */
2285 static void RemoveNewlines(nsString& aString);
2286
2287 /**
2288 * Convert Windows and Mac platform linebreaks to \n.
2289 * @param aString the string to convert the newlines inside [in/out]
2290 */
2291 static void PlatformToDOMLineBreaks(nsString& aString);
2292 [[nodiscard]] static bool PlatformToDOMLineBreaks(nsString& aString,
2293 const mozilla::fallible_t&);
2294
2295 /**
2296 * Populates aResultString with the contents of the string-buffer aBuf, up
2297 * to aBuf's null-terminator. aBuf must not be null. Ownership of the string
2298 * is not transferred.
2299 */
2300 static void PopulateStringFromStringBuffer(nsStringBuffer* aBuf,
2301 nsAString& aResultString);
2302
IsHandlingKeyBoardEvent()2303 static bool IsHandlingKeyBoardEvent() { return sIsHandlingKeyBoardEvent; }
2304
SetIsHandlingKeyBoardEvent(bool aHandling)2305 static void SetIsHandlingKeyBoardEvent(bool aHandling) {
2306 sIsHandlingKeyBoardEvent = aHandling;
2307 }
2308
2309 /**
2310 * Utility method for getElementsByClassName. aRootNode is the node (either
2311 * document or element), which getElementsByClassName was called on.
2312 */
2313 static already_AddRefed<nsContentList> GetElementsByClassName(
2314 nsINode* aRootNode, const nsAString& aClasses);
2315
2316 /**
2317 * Returns a presshell for this document, if there is one. This will be
2318 * aDoc's direct presshell if there is one, otherwise we'll look at all
2319 * ancestor documents to try to find a presshell, so for example this can
2320 * still find a presshell for documents in display:none frames that have
2321 * no presentation. So you have to be careful how you use this presshell ---
2322 * getting generic data like a device context or widget from it is OK, but it
2323 * might not be this document's actual presentation.
2324 */
2325 static mozilla::PresShell* FindPresShellForDocument(
2326 const Document* aDocument);
2327
2328 /**
2329 * Like FindPresShellForDocument, but returns the shell's PresContext instead.
2330 */
2331 static nsPresContext* FindPresContextForDocument(const Document* aDocument);
2332
2333 /**
2334 * Returns the widget for this document if there is one. Looks at all ancestor
2335 * documents to try to find a widget, so for example this can still find a
2336 * widget for documents in display:none frames that have no presentation.
2337 *
2338 * You should probably use WidgetForContent() instead of this, unless you have
2339 * a good reason to do otherwise.
2340 */
2341 static nsIWidget* WidgetForDocument(const Document* aDocument);
2342
2343 /**
2344 * Returns the appropriate widget for this element, if there is one. Unlike
2345 * WidgetForDocument(), this returns the correct widget for content in popups.
2346 *
2347 * You should probably use this instead of WidgetForDocument().
2348 */
2349 static nsIWidget* WidgetForContent(const nsIContent* aContent);
2350
2351 /**
2352 * Returns a layer manager to use for the given document. Basically we
2353 * look up the document hierarchy for the first document which has
2354 * a presentation with an associated widget, and use that widget's
2355 * layer manager.
2356 *
2357 * You should probably use LayerManagerForContent() instead of this, unless
2358 * you have a good reason to do otherwise.
2359 *
2360 * @param aDoc the document for which to return a layer manager.
2361 * @param aAllowRetaining an outparam that states whether the returned
2362 * layer manager should be used for retained layers
2363 */
2364 static already_AddRefed<mozilla::layers::LayerManager>
2365 LayerManagerForDocument(const Document* aDoc);
2366
2367 /**
2368 * Returns a layer manager to use for the given content. Unlike
2369 * LayerManagerForDocument(), this returns the correct layer manager for
2370 * content in popups.
2371 *
2372 * You should probably use this instead of LayerManagerForDocument().
2373 */
2374 static already_AddRefed<mozilla::layers::LayerManager> LayerManagerForContent(
2375 const nsIContent* aContent);
2376
2377 /**
2378 * Returns a layer manager to use for the given document. Basically we
2379 * look up the document hierarchy for the first document which has
2380 * a presentation with an associated widget, and use that widget's
2381 * layer manager. In addition to the normal layer manager lookup this will
2382 * specifically request a persistent layer manager. This means that the layer
2383 * manager is expected to remain the layer manager for the document in the
2384 * forseeable future. This function should be used carefully as it may change
2385 * the document's layer manager.
2386 *
2387 * @param aDoc the document for which to return a layer manager.
2388 * @param aAllowRetaining an outparam that states whether the returned
2389 * layer manager should be used for retained layers
2390 */
2391 static already_AddRefed<mozilla::layers::LayerManager>
2392 PersistentLayerManagerForDocument(Document* aDoc);
2393
2394 /**
2395 * Determine whether a content node is focused or not,
2396 *
2397 * @param aContent the content node to check
2398 * @return true if the content node is focused, false otherwise.
2399 */
2400 static bool IsFocusedContent(const nsIContent* aContent);
2401
2402 /**
2403 * Returns true if calling execCommand with 'cut' or 'copy' arguments is
2404 * allowed for the given subject principal. These are only allowed if the user
2405 * initiated them (like with a mouse-click or key press).
2406 */
2407 static bool IsCutCopyAllowed(Document* aDocument,
2408 nsIPrincipal& aSubjectPrincipal);
2409
2410 /*
2411 * Returns true if the browser should attempt to prevent the given caller type
2412 * from collecting distinctive information about the browser that could
2413 * be used to "fingerprint" and track the user across websites.
2414 */
ResistFingerprinting(mozilla::dom::CallerType aCallerType)2415 static bool ResistFingerprinting(mozilla::dom::CallerType aCallerType) {
2416 return aCallerType != mozilla::dom::CallerType::System &&
2417 ShouldResistFingerprinting();
2418 }
2419
2420 /**
2421 * Returns true if CSSOM origin check should be skipped for WebDriver
2422 * based crawl to be able to collect data from cross-origin CSS style
2423 * sheets. This can be enabled by setting environment variable
2424 * MOZ_BYPASS_CSSOM_ORIGIN_CHECK.
2425 */
BypassCSSOMOriginCheck()2426 static bool BypassCSSOMOriginCheck() {
2427 #ifdef RELEASE_OR_BETA
2428 return false;
2429 #else
2430 return sBypassCSSOMOriginCheck;
2431 #endif
2432 }
2433
2434 /**
2435 * Fire mutation events for changes caused by parsing directly into a
2436 * context node.
2437 *
2438 * @param aDoc the document of the node
2439 * @param aDest the destination node that got stuff appended to it
2440 * @param aOldChildCount the number of children the node had before parsing
2441 */
2442 static void FireMutationEventsForDirectParsing(Document* aDoc,
2443 nsIContent* aDest,
2444 int32_t aOldChildCount);
2445
2446 /**
2447 * Returns true if the content is in a document and contains a plugin
2448 * which we don't control event dispatch for, i.e. do any plugins in this
2449 * doc tree receive key events outside of our control? This always returns
2450 * false on MacOSX.
2451 */
2452 static bool HasPluginWithUncontrolledEventDispatch(nsIContent* aContent);
2453
2454 /**
2455 * Returns the in-process subtree root document in a document hierarchy.
2456 * This could be a chrome document.
2457 */
2458 static Document* GetInProcessSubtreeRootDocument(Document* aDoc);
2459
2460 static void GetShiftText(nsAString& text);
2461 static void GetControlText(nsAString& text);
2462 static void GetMetaText(nsAString& text);
2463 static void GetOSText(nsAString& text);
2464 static void GetAltText(nsAString& text);
2465 static void GetModifierSeparatorText(nsAString& text);
2466
2467 /**
2468 * Returns if aContent has a tabbable subdocument.
2469 * A sub document isn't tabbable when it's a zombie document.
2470 *
2471 * @param aElement element to test.
2472 *
2473 * @return Whether the subdocument is tabbable.
2474 */
2475 static bool IsSubDocumentTabbable(nsIContent* aContent);
2476
2477 /**
2478 * Returns if aContent has the 'scrollgrab' property.
2479 * aContent may be null (in this case false is returned).
2480 */
2481 static bool HasScrollgrab(nsIContent* aContent);
2482
2483 /**
2484 * Flushes the layout tree (recursively)
2485 *
2486 * @param aWindow the window the flush should start at
2487 *
2488 */
2489 static void FlushLayoutForTree(nsPIDOMWindowOuter* aWindow);
2490
2491 /**
2492 * Returns true if content with the given principal is allowed to use XUL
2493 * and XBL and false otherwise.
2494 */
2495 static bool AllowXULXBLForPrincipal(nsIPrincipal* aPrincipal);
2496
2497 /**
2498 * Perform cleanup that's appropriate for XPCOM shutdown.
2499 */
2500 static void XPCOMShutdown();
2501
2502 /**
2503 * Checks if internal PDF viewer is enabled.
2504 */
2505 static bool IsPDFJSEnabled();
2506
2507 /**
2508 * Checks to see whether the given principal is the internal PDF
2509 * viewer principal.
2510 */
2511 static bool IsPDFJS(nsIPrincipal* aPrincipal);
2512 /**
2513 * Same, but from WebIDL bindings. Checks whether the subject principal is for
2514 * the internal PDF viewer.
2515 */
2516 static bool IsPDFJS(JSContext*, JSObject*);
2517
2518 /**
2519 * Checks if internal SWF player is enabled.
2520 */
2521 static bool IsSWFPlayerEnabled();
2522
2523 enum ContentViewerType {
2524 TYPE_UNSUPPORTED,
2525 TYPE_CONTENT,
2526 TYPE_FALLBACK,
2527 TYPE_UNKNOWN
2528 };
2529
2530 static already_AddRefed<nsIDocumentLoaderFactory> FindInternalContentViewer(
2531 const nsACString& aType, ContentViewerType* aLoaderType = nullptr);
2532
2533 /**
2534 * This helper method returns true if the aPattern pattern matches aValue.
2535 * aPattern should not contain leading and trailing slashes (/).
2536 * The pattern has to match the entire value not just a subset.
2537 * aDocument must be a valid pointer (not null).
2538 *
2539 * This is following the HTML5 specification:
2540 * http://dev.w3.org/html5/spec/forms.html#attr-input-pattern
2541 *
2542 * WARNING: This method mutates aPattern and aValue!
2543 *
2544 * @param aValue the string to check.
2545 * @param aPattern the string defining the pattern.
2546 * @param aDocument the owner document of the element.
2547 * @result whether the given string is matches the pattern, or
2548 * Nothing() if the pattern couldn't be evaluated.
2549 */
2550 static mozilla::Maybe<bool> IsPatternMatching(nsAString& aValue,
2551 nsAString& aPattern,
2552 const Document* aDocument);
2553
2554 /**
2555 * Calling this adds support for
2556 * ontouch* event handler DOM attributes.
2557 */
2558 static void InitializeTouchEventTable();
2559
2560 /**
2561 * Test whether the given URI always inherits a security context
2562 * from the document it comes from.
2563 */
2564 static nsresult URIInheritsSecurityContext(nsIURI* aURI, bool* aResult);
2565
2566 /**
2567 * Called before a channel is created to query whether the new
2568 * channel should inherit the principal.
2569 *
2570 * The argument aLoadingPrincipal must not be null. The argument
2571 * aURI must be the URI of the new channel. If aInheritForAboutBlank
2572 * is true, then about:blank will be told to inherit the principal.
2573 * If aForceInherit is true, the new channel will be told to inherit
2574 * the principal no matter what.
2575 *
2576 * The return value is whether the new channel should inherit
2577 * the principal.
2578 */
2579 static bool ChannelShouldInheritPrincipal(nsIPrincipal* aLoadingPrincipal,
2580 nsIURI* aURI,
2581 bool aInheritForAboutBlank,
2582 bool aForceInherit);
2583
2584 static nsresult Btoa(const nsAString& aBinaryData,
2585 nsAString& aAsciiBase64String);
2586
2587 static nsresult Atob(const nsAString& aAsciiString, nsAString& aBinaryData);
2588
2589 /**
2590 * Returns whether the input element passed in parameter has the autocomplete
2591 * functionality enabled. It is taking into account the form owner.
2592 * NOTE: the caller has to make sure autocomplete makes sense for the
2593 * element's type.
2594 *
2595 * @param aInput the input element to check. NOTE: aInput can't be null.
2596 * @return whether the input element has autocomplete enabled.
2597 */
2598 static bool IsAutocompleteEnabled(mozilla::dom::HTMLInputElement* aInput);
2599
2600 enum AutocompleteAttrState : uint8_t {
2601 eAutocompleteAttrState_Unknown = 1,
2602 eAutocompleteAttrState_Invalid,
2603 eAutocompleteAttrState_Valid,
2604 };
2605 /**
2606 * Parses the value of the autocomplete attribute into aResult, ensuring it's
2607 * composed of valid tokens, otherwise the value "" is used.
2608 * Note that this method is used for form fields, not on a <form> itself.
2609 *
2610 * @return whether aAttr was valid and can be cached.
2611 */
2612 static AutocompleteAttrState SerializeAutocompleteAttribute(
2613 const nsAttrValue* aAttr, nsAString& aResult,
2614 AutocompleteAttrState aCachedState = eAutocompleteAttrState_Unknown);
2615
2616 /* Variation that is used to retrieve a dictionary of the parts of the
2617 * autocomplete attribute.
2618 *
2619 * @return whether aAttr was valid and can be cached.
2620 */
2621 static AutocompleteAttrState SerializeAutocompleteAttribute(
2622 const nsAttrValue* aAttr, mozilla::dom::AutocompleteInfo& aInfo,
2623 AutocompleteAttrState aCachedState = eAutocompleteAttrState_Unknown,
2624 bool aGrantAllValidValue = false);
2625
2626 /**
2627 * This will parse aSource, to extract the value of the pseudo attribute
2628 * with the name specified in aName. See
2629 * http://www.w3.org/TR/xml-stylesheet/#NT-StyleSheetPI for the specification
2630 * which is used to parse aSource.
2631 *
2632 * @param aSource the string to parse
2633 * @param aName the name of the attribute to get the value for
2634 * @param aValue [out] the value for the attribute with name specified in
2635 * aAttribute. Empty if the attribute isn't present.
2636 * @return true if the attribute exists and was successfully parsed.
2637 * false if the attribute doesn't exist, or has a malformed
2638 * value, such as an unknown or unterminated entity.
2639 */
2640 static bool GetPseudoAttributeValue(const nsString& aSource, nsAtom* aName,
2641 nsAString& aValue);
2642
2643 /**
2644 * Returns true if the language name is a version of JavaScript and
2645 * false otherwise
2646 */
2647 static bool IsJavaScriptLanguage(const nsString& aName);
2648
2649 static bool IsJavascriptMIMEType(const nsAString& aMIMEType);
2650
2651 static void SplitMimeType(const nsAString& aValue, nsString& aType,
2652 nsString& aParams);
2653
2654 /**
2655 * Function checks if the user is idle.
2656 *
2657 * @param aRequestedIdleTimeInMS The idle observer's requested idle time.
2658 * @param aUserIsIdle boolean indicating if the user
2659 * is currently idle or not.
2660 * @return NS_OK NS_OK returned if the requested idle
2661 * service and the current idle time were
2662 * successfully obtained.
2663 * NS_ERROR_FAILURE returned if the the
2664 * requested idle service or the current
2665 * idle were not obtained.
2666 */
2667 static nsresult IsUserIdle(uint32_t aRequestedIdleTimeInMS,
2668 bool* aUserIsIdle);
2669
2670 /**
2671 * Takes a selection, and a text control element (<input> or <textarea>), and
2672 * returns the offsets in the text content corresponding to the selection.
2673 * The selection's anchor and focus must both be in the root node passed or a
2674 * descendant.
2675 *
2676 * @param aSelection Selection to check
2677 * @param aRoot Root <input> or <textarea> element
2678 * @param aOutStartOffset Output start offset
2679 * @param aOutEndOffset Output end offset
2680 */
2681 static void GetSelectionInTextControl(mozilla::dom::Selection* aSelection,
2682 Element* aRoot,
2683 uint32_t& aOutStartOffset,
2684 uint32_t& aOutEndOffset);
2685
2686 /**
2687 * Takes a frame for anonymous content within a text control (<input> or
2688 * <textarea>), and returns an offset in the text content, adjusted for a
2689 * trailing <br> frame.
2690 *
2691 * @param aOffsetFrame Frame for the text content in which the offset
2692 * lies
2693 * @param aOffset Offset as calculated by GetContentOffsetsFromPoint
2694 * @param aOutOffset Output adjusted offset
2695 *
2696 * @see GetSelectionInTextControl for the original basis of this function.
2697 */
2698 static int32_t GetAdjustedOffsetInTextControl(nsIFrame* aOffsetFrame,
2699 int32_t aOffset);
2700
2701 /**
2702 * Returns pointer to HTML editor instance for the aPresContext when there is.
2703 * The HTML editor is shared by contenteditable elements or used in
2704 * designMode. When there are no contenteditable elements and the document
2705 * is not in designMode, this returns nullptr.
2706 */
2707 static mozilla::HTMLEditor* GetHTMLEditor(nsPresContext* aPresContext);
2708 static mozilla::HTMLEditor* GetHTMLEditor(nsDocShell* aDocShell);
2709
2710 /**
2711 * Returns pointer to a text editor if <input> or <textarea> element is
2712 * active element in the document for aPresContext, or pointer to HTML
2713 * editor if there is (i.e., even if non-editable element has focus or
2714 * nobody has focus). The reason is, HTML editor may handle some input
2715 * even if there is no active editing host.
2716 * Note that this does not return editor in descendant documents.
2717 */
2718 static mozilla::EditorBase* GetActiveEditor(nsPresContext* aPresContext);
2719 static mozilla::EditorBase* GetActiveEditor(nsPIDOMWindowOuter* aWindow);
2720
2721 /**
2722 * Returns `TextEditor` which manages `aAnonymousContent` if there is.
2723 * Note that this method returns `nullptr` if `TextEditor` for the
2724 * `aAnonymousContent` hasn't been created yet.
2725 */
2726 static mozilla::TextEditor* GetTextEditorFromAnonymousNodeWithoutCreation(
2727 nsIContent* aAnonymousContent);
2728
2729 /**
2730 * Returns whether a node has an editable ancestor.
2731 *
2732 * @param aNode The node to test.
2733 */
2734 static bool IsNodeInEditableRegion(nsINode* aNode);
2735
2736 /**
2737 * Returns a LogModule that logs debugging info from RFP functions.
2738 */
2739 static mozilla::LogModule* ResistFingerprintingLog();
2740
2741 /**
2742 * Returns a LogModule that dump calls from content script are logged to.
2743 * This can be enabled with the 'Dump' module, and is useful for synchronizing
2744 * content JS to other logging modules.
2745 */
2746 static mozilla::LogModule* DOMDumpLog();
2747
2748 /**
2749 * Returns whether a given header is forbidden for an XHR or fetch
2750 * request.
2751 */
2752 static bool IsForbiddenRequestHeader(const nsACString& aHeader);
2753
2754 /**
2755 * Returns whether a given header is forbidden for a system XHR
2756 * request.
2757 */
2758 static bool IsForbiddenSystemRequestHeader(const nsACString& aHeader);
2759
2760 /**
2761 * Returns whether a given header has characters that aren't permitted
2762 */
2763 static bool IsCorsUnsafeRequestHeaderValue(const nsACString& aHeaderValue);
2764
2765 /**
2766 * Returns whether a given Accept header value is allowed
2767 * for a non-CORS XHR or fetch request.
2768 */
2769 static bool IsAllowedNonCorsAccept(const nsACString& aHeaderValue);
2770
2771 /**
2772 * Returns whether a given Content-Type header value is allowed
2773 * for a non-CORS XHR or fetch request.
2774 */
2775 static bool IsAllowedNonCorsContentType(const nsACString& aHeaderValue);
2776
2777 /**
2778 * Returns whether a given Content-Language or accept-language header value is
2779 * allowed for a non-CORS XHR or fetch request.
2780 */
2781 static bool IsAllowedNonCorsLanguage(const nsACString& aHeaderValue);
2782
2783 /**
2784 * Returns whether a given header and value is a CORS-safelisted request
2785 * header per https://fetch.spec.whatwg.org/#cors-safelisted-request-header
2786 */
2787 static bool IsCORSSafelistedRequestHeader(const nsACString& aName,
2788 const nsACString& aValue);
2789
2790 /**
2791 * Returns whether a given header is forbidden for an XHR or fetch
2792 * response.
2793 */
2794 static bool IsForbiddenResponseHeader(const nsACString& aHeader);
2795
2796 /**
2797 * Returns the inner window ID for the window associated with a request.
2798 */
2799 static uint64_t GetInnerWindowID(nsIRequest* aRequest);
2800
2801 /**
2802 * Returns the inner window ID for the window associated with a load group.
2803 */
2804 static uint64_t GetInnerWindowID(nsILoadGroup* aLoadGroup);
2805
2806 /**
2807 * Encloses aHost in brackets if it is an IPv6 address.
2808 */
2809 static void MaybeFixIPv6Host(nsACString& aHost);
2810
2811 /**
2812 * If the hostname for aURI is an IPv6 it encloses it in brackets,
2813 * otherwise it just outputs the hostname in aHost.
2814 */
2815 static nsresult GetHostOrIPv6WithBrackets(nsIURI* aURI, nsAString& aHost);
2816 static nsresult GetHostOrIPv6WithBrackets(nsIURI* aURI, nsACString& aHost);
2817 static nsresult GetHostOrIPv6WithBrackets(nsIPrincipal* aPrincipal,
2818 nsACString& aHost);
2819
2820 /*
2821 * Call the given callback on all remote children of the given top-level
2822 * window. Return Callstate::Stop from the callback to stop calling further
2823 * children.
2824 */
2825 static void CallOnAllRemoteChildren(
2826 nsPIDOMWindowOuter* aWindow,
2827 const std::function<mozilla::CallState(mozilla::dom::BrowserParent*)>&
2828 aCallback);
2829
2830 /*
2831 * Call nsPIDOMWindow::SetKeyboardIndicators all all remote children. This is
2832 * in here rather than nsGlobalWindow because BrowserParent indirectly
2833 * includes Windows headers which aren't allowed there.
2834 */
2835 static void SetKeyboardIndicatorsOnRemoteChildren(
2836 nsPIDOMWindowOuter* aWindow, UIStateChangeType aShowFocusRings);
2837
2838 /**
2839 * Given an nsIFile, attempts to read it into aString.
2840 *
2841 * Note: Use sparingly! This causes main-thread I/O, which causes jank and all
2842 * other bad things.
2843 */
2844 static nsresult SlurpFileToString(nsIFile* aFile, nsACString& aString);
2845
2846 /**
2847 * Returns true if the mime service thinks this file contains an image.
2848 *
2849 * The content type is returned in aType.
2850 */
2851 static bool IsFileImage(nsIFile* aFile, nsACString& aType);
2852
2853 /**
2854 * Given an IPCDataTransferItem that has a flavor for which IsFlavorImage
2855 * returns true and whose IPCDataTransferData is of type nsCString (raw image
2856 * data), construct an imgIContainer for the image encoded by the transfer
2857 * item.
2858 */
2859 static nsresult DataTransferItemToImage(
2860 const mozilla::dom::IPCDataTransferItem& aItem,
2861 imgIContainer** aContainer);
2862
2863 /**
2864 * Given a flavor obtained from an IPCDataTransferItem or nsITransferable,
2865 * returns true if we should treat the data as an image.
2866 */
2867 static bool IsFlavorImage(const nsACString& aFlavor);
2868
2869 static nsresult IPCTransferableToTransferable(
2870 const mozilla::dom::IPCDataTransfer& aDataTransfer,
2871 const bool& aIsPrivateData, nsIPrincipal* aRequestingPrincipal,
2872 const nsContentPolicyType& aContentPolicyType,
2873 nsITransferable* aTransferable,
2874 mozilla::dom::ContentParent* aContentParent,
2875 mozilla::dom::BrowserChild* aBrowserChild);
2876
2877 static void TransferablesToIPCTransferables(
2878 nsIArray* aTransferables, nsTArray<mozilla::dom::IPCDataTransfer>& aIPC,
2879 bool aInSyncMessage, mozilla::dom::ContentChild* aChild,
2880 mozilla::dom::ContentParent* aParent);
2881
2882 static void TransferableToIPCTransferable(
2883 nsITransferable* aTransferable,
2884 mozilla::dom::IPCDataTransfer* aIPCDataTransfer, bool aInSyncMessage,
2885 mozilla::dom::ContentChild* aChild, mozilla::dom::ContentParent* aParent);
2886
2887 /*
2888 * Get the pixel data from the given source surface and return it as a buffer.
2889 * The length and stride will be assigned from the surface.
2890 */
2891 static mozilla::UniquePtr<char[]> GetSurfaceData(
2892 mozilla::NotNull<mozilla::gfx::DataSourceSurface*> aSurface,
2893 size_t* aLength, int32_t* aStride);
2894
2895 /*
2896 * Get the pixel data from the given source surface and fill it in Shmem.
2897 * The length and stride will be assigned from the surface.
2898 */
2899 static mozilla::Maybe<mozilla::ipc::Shmem> GetSurfaceData(
2900 mozilla::gfx::DataSourceSurface* aSurface, size_t* aLength,
2901 int32_t* aStride, mozilla::ipc::IShmemAllocator* aAlloc);
2902
2903 // Helpers shared by the implementations of nsContentUtils methods and
2904 // nsIDOMWindowUtils methods.
2905 static mozilla::Modifiers GetWidgetModifiers(int32_t aModifiers);
2906 static nsIWidget* GetWidget(mozilla::PresShell* aPresShell, nsPoint* aOffset);
2907 static int16_t GetButtonsFlagForButton(int32_t aButton);
2908 static mozilla::LayoutDeviceIntPoint ToWidgetPoint(
2909 const mozilla::CSSPoint& aPoint, const nsPoint& aOffset,
2910 nsPresContext* aPresContext);
2911 static nsView* GetViewToDispatchEvent(nsPresContext* aPresContext,
2912 mozilla::PresShell** aPresShell);
2913
2914 /**
2915 * Synthesize a mouse event to the given widget
2916 * (see nsIDOMWindowUtils.sendMouseEvent).
2917 */
2918 MOZ_CAN_RUN_SCRIPT
2919 static nsresult SendMouseEvent(
2920 mozilla::PresShell* aPresShell, const nsAString& aType, float aX,
2921 float aY, int32_t aButton, int32_t aButtons, int32_t aClickCount,
2922 int32_t aModifiers, bool aIgnoreRootScrollFrame, float aPressure,
2923 unsigned short aInputSourceArg, uint32_t aIdentifier, bool aToWindow,
2924 mozilla::PreventDefaultResult* aPreventDefault,
2925 bool aIsDOMEventSynthesized, bool aIsWidgetEventSynthesized);
2926
2927 static void FirePageShowEventForFrameLoaderSwap(
2928 nsIDocShellTreeItem* aItem,
2929 mozilla::dom::EventTarget* aChromeEventHandler, bool aFireIfShowing,
2930 bool aOnlySystemGroup = false);
2931
2932 static void FirePageHideEventForFrameLoaderSwap(
2933 nsIDocShellTreeItem* aItem,
2934 mozilla::dom::EventTarget* aChromeEventHandler,
2935 bool aOnlySystemGroup = false);
2936
2937 static already_AddRefed<nsPIWindowRoot> GetWindowRoot(Document* aDoc);
2938
2939 /*
2940 * If there is a Referrer-Policy response header in |aChannel|, parse a
2941 * referrer policy from the header.
2942 *
2943 * @param the channel from which to get the Referrer-Policy header
2944 * @return referrer policy from the response header in aChannel
2945 */
2946 static mozilla::dom::ReferrerPolicy GetReferrerPolicyFromChannel(
2947 nsIChannel* aChannel);
2948
2949 static bool IsNonSubresourceRequest(nsIChannel* aChannel);
2950
2951 static bool IsNonSubresourceInternalPolicyType(nsContentPolicyType aType);
2952
2953 public:
2954 /*
2955 * Returns true if this window/channel is a 3rd party context.
2956 */
2957 static bool IsThirdPartyWindowOrChannel(nsPIDOMWindowInner* aWindow,
2958 nsIChannel* aChannel, nsIURI* aURI);
2959
2960 /*
2961 * Returns true if this window's channel has been marked as a third-party
2962 * tracking resource.
2963 */
2964 static bool IsThirdPartyTrackingResourceWindow(nsPIDOMWindowInner* aWindow);
2965
2966 /*
2967 * Returns true if this window's channel has been marked as a first-party
2968 * tracking resource.
2969 */
2970 static bool IsFirstPartyTrackingResourceWindow(nsPIDOMWindowInner* aWindow);
2971
2972 /*
2973 * Serializes a HTML nsINode into its markup representation.
2974 */
2975 static bool SerializeNodeToMarkup(nsINode* aRoot, bool aDescendentsOnly,
2976 nsAString& aOut);
2977
2978 /*
2979 * Returns true iff the provided JSObject is a global, and its URI matches
2980 * the provided about: URI.
2981 * @param aGlobal the JSObject whose URI to check, if it is a global.
2982 * @param aUri the URI to match, e.g. "about:feeds"
2983 */
2984 static bool IsSpecificAboutPage(JSObject* aGlobal, const char* aUri);
2985
2986 static void SetScrollbarsVisibility(nsIDocShell* aDocShell, bool aVisible);
2987
2988 /*
2989 * Try to find the docshell corresponding to the given event target.
2990 */
2991 static nsIDocShell* GetDocShellForEventTarget(
2992 mozilla::dom::EventTarget* aTarget);
2993
2994 /**
2995 * Returns true if the "HTTPS state" of the document should be "modern". See:
2996 *
2997 * https://html.spec.whatwg.org/#concept-document-https-state
2998 * https://fetch.spec.whatwg.org/#concept-response-https-state
2999 */
3000 static bool HttpsStateIsModern(Document* aDocument);
3001
3002 /**
3003 * Returns true if the channel is for top-level window and is over secure
3004 * context.
3005 * https://github.com/whatwg/html/issues/4930 tracks the spec side of this.
3006 */
3007 static bool ComputeIsSecureContext(nsIChannel* aChannel);
3008
3009 /**
3010 * Try to upgrade an element.
3011 * https://html.spec.whatwg.org/multipage/custom-elements.html#concept-try-upgrade
3012 */
3013 static void TryToUpgradeElement(Element* aElement);
3014
3015 /**
3016 * Creates a new XUL or XHTML element applying any appropriate custom element
3017 * definition.
3018 *
3019 * If aFromParser != FROM_PARSER_FRAGMENT, a nested event loop permits
3020 * arbitrary changes to the world before this function returns. This should
3021 * probably just be MOZ_CAN_RUN_SCRIPT - bug 1543259.
3022 */
3023 MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult NewXULOrHTMLElement(
3024 Element** aResult, mozilla::dom::NodeInfo* aNodeInfo,
3025 mozilla::dom::FromParser aFromParser, nsAtom* aIsAtom,
3026 mozilla::dom::CustomElementDefinition* aDefinition);
3027
3028 static mozilla::dom::CustomElementRegistry* GetCustomElementRegistry(
3029 Document*);
3030
3031 /**
3032 * Looking up a custom element definition.
3033 * https://html.spec.whatwg.org/#look-up-a-custom-element-definition
3034 */
3035 static mozilla::dom::CustomElementDefinition* LookupCustomElementDefinition(
3036 Document* aDoc, nsAtom* aNameAtom, uint32_t aNameSpaceID,
3037 nsAtom* aTypeAtom);
3038
3039 static void RegisterCallbackUpgradeElement(Element* aElement,
3040 nsAtom* aTypeName);
3041
3042 static void RegisterUnresolvedElement(Element* aElement, nsAtom* aTypeName);
3043 static void UnregisterUnresolvedElement(Element* aElement);
3044
3045 static void EnqueueUpgradeReaction(
3046 Element* aElement, mozilla::dom::CustomElementDefinition* aDefinition);
3047
3048 static void EnqueueLifecycleCallback(
3049 mozilla::dom::ElementCallbackType aType, Element* aCustomElement,
3050 mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
3051 mozilla::dom::LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs =
3052 nullptr,
3053 mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
3054
3055 /**
3056 * Appends all "document level" native anonymous content subtree roots for
3057 * aDocument to aElements. Document level NAC subtrees are those created
3058 * by ancestor frames of the document element's primary frame, such as
3059 * the scrollbar elements created by the root scroll frame.
3060 */
3061 static void AppendDocumentLevelNativeAnonymousContentTo(
3062 Document* aDocument, nsTArray<nsIContent*>& aElements);
3063
3064 /**
3065 * Appends all native anonymous content subtree roots generated by `aContent`
3066 * to `aKids`.
3067 *
3068 * See `AllChildrenIterator` for the description of the `aFlags` parameter.
3069 */
3070 static void AppendNativeAnonymousChildren(const nsIContent* aContent,
3071 nsTArray<nsIContent*>& aKids,
3072 uint32_t aFlags);
3073
3074 /**
3075 * Query triggeringPrincipal if there's a 'triggeringprincipal' attribute on
3076 * aLoadingNode, if no such attribute is specified, aDefaultPrincipal is
3077 * returned if it is provided, otherwise the NodePrincipal of aLoadingNode is
3078 * returned.
3079 *
3080 * Return true if aLoadingNode has a 'triggeringprincipal' attribute, and
3081 * the value 'triggeringprincipal' is also successfully deserialized,
3082 * otherwise return false.
3083 */
3084 static bool QueryTriggeringPrincipal(nsIContent* aLoadingNode,
3085 nsIPrincipal* aDefaultPrincipal,
3086 nsIPrincipal** aTriggeringPrincipal);
3087
QueryTriggeringPrincipal(nsIContent * aLoadingNode,nsIPrincipal ** aTriggeringPrincipal)3088 static bool QueryTriggeringPrincipal(nsIContent* aLoadingNode,
3089 nsIPrincipal** aTriggeringPrincipal) {
3090 return QueryTriggeringPrincipal(aLoadingNode, nullptr,
3091 aTriggeringPrincipal);
3092 }
3093
3094 // Returns whether the image for the given URI and triggering principal is
3095 // already available. Ideally this should exactly match the "list of available
3096 // images" in the HTML spec, but our implementation of that at best only
3097 // resembles it.
3098 static bool IsImageAvailable(nsIContent*, nsIURI*,
3099 nsIPrincipal* aDefaultTriggeringPrincipal,
3100 mozilla::CORSMode);
3101
3102 /**
3103 * Returns the content policy type that should be used for loading images
3104 * for displaying in the UI. The sources of such images can be <xul:image>,
3105 * <xul:menuitem> on OSX where we load the image through nsMenuItemIconX, etc.
3106 */
3107 static void GetContentPolicyTypeForUIImageLoading(
3108 nsIContent* aLoadingNode, nsIPrincipal** aTriggeringPrincipal,
3109 nsContentPolicyType& aContentPolicyType, uint64_t* aRequestContextID);
3110
3111 static nsresult CreateJSValueFromSequenceOfObject(
3112 JSContext* aCx, const mozilla::dom::Sequence<JSObject*>& aTransfer,
3113 JS::MutableHandle<JS::Value> aValue);
3114
3115 /**
3116 * Returns true if reserved key events should be prevented from being sent
3117 * to their target. Instead, the key event should be handled by chrome only.
3118 */
3119 static bool ShouldBlockReservedKeys(mozilla::WidgetKeyboardEvent* aKeyEvent);
3120
3121 /**
3122 * Returns the nsIPluginTag for the plugin we should try to use for a given
3123 * MIME type.
3124 *
3125 * @param aMIMEType The MIME type of the document being loaded.
3126 * @param aNoFakePlugin If false then this method should consider JS plugins.
3127 */
3128 static already_AddRefed<nsIPluginTag> PluginTagForType(
3129 const nsCString& aMIMEType, bool aNoFakePlugin);
3130
3131 /**
3132 * Returns one of the nsIObjectLoadingContent::TYPE_ values describing the
3133 * content type which will be used for the given MIME type when loaded within
3134 * an nsObjectLoadingContent.
3135 *
3136 * NOTE: This method doesn't take capabilities into account. The caller must
3137 * take that into account.
3138 *
3139 * @param aMIMEType The MIME type of the document being loaded.
3140 * @param aNoFakePlugin If false then this method should consider JS plugins.
3141 * @param aContent The nsIContent object which is performing the load. May be
3142 * nullptr in which case the docshell's plugin permissions
3143 * will not be checked.
3144 */
3145 static uint32_t HtmlObjectContentTypeForMIMEType(const nsCString& aMIMEType,
3146 bool aNoFakePlugin,
3147 nsIContent* aContent);
3148
3149 static already_AddRefed<nsISerialEventTarget> GetEventTargetByLoadInfo(
3150 nsILoadInfo* aLoadInfo, mozilla::TaskCategory aCategory);
3151
3152 /**
3153 * Detect whether a string is a local-url.
3154 * https://drafts.csswg.org/css-values/#local-urls
3155 */
3156 static bool IsLocalRefURL(const nsAString& aString);
3157
3158 /**
3159 * Compose a tab id with process id and a serial number.
3160 */
3161 static uint64_t GenerateTabId();
3162
3163 /**
3164 * Compose a browser id with process id and a serial number.
3165 */
3166 static uint64_t GenerateBrowserId();
3167
3168 /**
3169 * Generate an id for a BrowsingContext using a range of serial
3170 * numbers reserved for the current process.
3171 */
3172 static uint64_t GenerateBrowsingContextId();
3173
3174 /**
3175 * Generate an id using a range of serial numbers reserved for the current
3176 * process. aId should be a counter that's incremented every time
3177 * GenerateProcessSpecificId is called.
3178 */
3179 static uint64_t GenerateProcessSpecificId(uint64_t aId);
3180
3181 static std::tuple<uint64_t, uint64_t> SplitProcessSpecificId(uint64_t aId);
3182
3183 /**
3184 * Generate a window ID which is unique across processes and will never be
3185 * recycled.
3186 */
3187 static uint64_t GenerateWindowId();
3188
3189 /**
3190 * Generate an ID for a load which is unique across processes and will never
3191 * be recycled.
3192 */
3193 static uint64_t GenerateLoadIdentifier();
3194
3195 /**
3196 * Determine whether or not the user is currently interacting with the web
3197 * browser. This method is safe to call from off of the main thread.
3198 */
3199 static bool GetUserIsInteracting();
3200
3201 // Alternate data MIME type used by the ScriptLoader to register and read
3202 // bytecode out of the nsCacheInfoChannel.
3203 [[nodiscard]] static bool InitJSBytecodeMimeType();
JSBytecodeMimeType()3204 static nsCString& JSBytecodeMimeType() {
3205 MOZ_ASSERT(sJSBytecodeMimeType);
3206 return *sJSBytecodeMimeType;
3207 }
3208
3209 /**
3210 * Checks if the passed-in name is one of the special names: "_blank", "_top",
3211 * "_parent" or "_self".
3212 */
3213 static bool IsSpecialName(const nsAString& aName);
3214
3215 /**
3216 * Checks if the passed-in name should override an existing name on the
3217 * window. Values which should not override include: "", "_blank", "_top",
3218 * "_parent" and "_self".
3219 */
3220 static bool IsOverridingWindowName(const nsAString& aName);
3221
3222 /**
3223 * If there is a SourceMap (higher precedence) or X-SourceMap (lower
3224 * precedence) response header in |aChannel|, set |aResult| to the
3225 * header's value and return true. Otherwise, return false.
3226 *
3227 * @param aChannel The HTTP channel
3228 * @param aResult The string result.
3229 */
3230 static bool GetSourceMapURL(nsIHttpChannel* aChannel, nsACString& aResult);
3231
3232 /**
3233 * Returns true if the passed-in mesasge is a pending InputEvent.
3234 *
3235 * @param aMsg The message to check
3236 */
3237 static bool IsMessageInputEvent(const IPC::Message& aMsg);
3238
3239 /**
3240 * Returns true if the passed-in message is a critical InputEvent.
3241 *
3242 * @param aMsg The message to check
3243 */
3244 static bool IsMessageCriticalInputEvent(const IPC::Message& aMsg);
3245
3246 static void AsyncPrecreateStringBundles();
3247
3248 static bool ContentIsLink(nsIContent* aContent);
3249
3250 static already_AddRefed<mozilla::dom::ContentFrameMessageManager>
3251 TryGetBrowserChildGlobal(nsISupports* aFrom);
3252
3253 // Get a serial number for a newly created inner or outer window.
3254 static uint32_t InnerOrOuterWindowCreated();
3255 // Record that an inner or outer window has been destroyed.
3256 static void InnerOrOuterWindowDestroyed();
3257 // Get the current number of inner or outer windows.
GetCurrentInnerOrOuterWindowCount()3258 static int32_t GetCurrentInnerOrOuterWindowCount() {
3259 return sInnerOrOuterWindowCount;
3260 }
3261
3262 /**
3263 * Serializes a JSON-like JS::Value into a string.
3264 *
3265 * Usage:
3266 * nsAutoString serializedValue;
3267 * nsContentUtils::StringifyJSON(cx, &value, serializedValue);
3268 */
3269 static bool StringifyJSON(JSContext* aCx, JS::MutableHandle<JS::Value> vp,
3270 nsAString& aOutStr);
3271
3272 /**
3273 * Returns true if the top level ancestor content document of aDocument hasn't
3274 * yet had the first contentful paint and there is a high priority event
3275 * pending in the main thread.
3276 */
3277 static bool HighPriorityEventPendingForTopLevelDocumentBeforeContentfulPaint(
3278 Document* aDocument);
3279
3280 static nsGlobalWindowInner* CallerInnerWindow();
3281
3282 /*
3283 * Return safe area insets of window that defines as
3284 * https://drafts.csswg.org/css-env-1/#safe-area-insets.
3285 */
3286 static mozilla::ScreenIntMargin GetWindowSafeAreaInsets(
3287 nsIScreen* aScreen, const mozilla::ScreenIntMargin& aSafeareaInsets,
3288 const mozilla::LayoutDeviceIntRect& aWindowRect);
3289
3290 struct SubresourceCacheValidationInfo {
3291 // The expiration time, in seconds, if known.
3292 mozilla::Maybe<uint32_t> mExpirationTime;
3293 bool mMustRevalidate = false;
3294 };
3295
3296 /**
3297 * Gets cache validation info for subresources such as images or CSS
3298 * stylesheets.
3299 */
3300 static SubresourceCacheValidationInfo GetSubresourceCacheValidationInfo(
3301 nsIRequest*);
3302
SecondsFromPRTime(PRTime aTime)3303 static uint32_t SecondsFromPRTime(PRTime aTime) {
3304 return uint32_t(int64_t(aTime) / int64_t(PR_USEC_PER_SEC));
3305 }
3306
3307 /**
3308 * Converts the given URL to a string and truncates it to the given length.
3309 *
3310 * Returns an empty string if aURL is null.
3311 */
3312 static nsCString TruncatedURLForDisplay(nsIURI* aURL, size_t aMaxLen = 128);
3313
3314 private:
3315 static bool InitializeEventTable();
3316
3317 static nsresult EnsureStringBundle(PropertiesFile aFile);
3318
3319 static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
3320 nsIPrincipal* aPrincipal);
3321
3322 static nsresult WrapNative(JSContext* cx, nsISupports* native,
3323 nsWrapperCache* cache, const nsIID* aIID,
3324 JS::MutableHandle<JS::Value> vp,
3325 bool aAllowWrapping);
3326
3327 static nsresult DispatchEvent(Document* aDoc, nsISupports* aTarget,
3328 const nsAString& aEventName, CanBubble,
3329 Cancelable, Composed, Trusted,
3330 bool* aDefaultAction = nullptr,
3331 ChromeOnlyDispatch = ChromeOnlyDispatch::eNo);
3332
3333 static nsresult DispatchEvent(Document* aDoc, nsISupports* aTarget,
3334 mozilla::WidgetEvent& aWidgetEvent,
3335 EventMessage aEventMessage, CanBubble,
3336 Cancelable, Trusted,
3337 bool* aDefaultAction = nullptr,
3338 ChromeOnlyDispatch = ChromeOnlyDispatch::eNo);
3339
3340 static void InitializeModifierStrings();
3341
3342 static void DropFragmentParsers();
3343
3344 static bool MatchClassNames(mozilla::dom::Element* aElement,
3345 int32_t aNamespaceID, nsAtom* aAtom, void* aData);
3346 static void DestroyClassNameArray(void* aData);
3347 static void* AllocClassMatchingInfo(nsINode* aRootNode,
3348 const nsString* aClasses);
3349
3350 static mozilla::EventClassID GetEventClassIDFromMessage(
3351 EventMessage aEventMessage);
3352
3353 // Fills in aInfo with the tokens from the supplied autocomplete attribute.
3354 static AutocompleteAttrState InternalSerializeAutocompleteAttribute(
3355 const nsAttrValue* aAttrVal, mozilla::dom::AutocompleteInfo& aInfo,
3356 bool aGrantAllValidValue = false);
3357
3358 static mozilla::CallState CallOnAllRemoteChildren(
3359 mozilla::dom::MessageBroadcaster* aManager,
3360 const std::function<mozilla::CallState(mozilla::dom::BrowserParent*)>&
3361 aCallback);
3362
3363 static nsINode* GetCommonAncestorHelper(nsINode* aNode1, nsINode* aNode2);
3364 static nsIContent* GetCommonFlattenedTreeAncestorHelper(
3365 nsIContent* aContent1, nsIContent* aContent2);
3366
3367 static nsIXPConnect* sXPConnect;
3368
3369 static nsIScriptSecurityManager* sSecurityManager;
3370 static nsIPrincipal* sSystemPrincipal;
3371 static nsIPrincipal* sNullSubjectPrincipal;
3372
3373 static nsNameSpaceManager* sNameSpaceManager;
3374
3375 static nsIIOService* sIOService;
3376 static nsIUUIDGenerator* sUUIDGenerator;
3377
3378 static nsIConsoleService* sConsoleService;
3379
3380 static nsTHashMap<nsRefPtrHashKey<nsAtom>, EventNameMapping>* sAtomEventTable;
3381 static nsTHashMap<nsStringHashKey, EventNameMapping>* sStringEventTable;
3382 static nsTArray<RefPtr<nsAtom>>* sUserDefinedEvents;
3383
3384 static nsIStringBundleService* sStringBundleService;
3385 static nsIStringBundle* sStringBundles[PropertiesFile_COUNT];
3386 class nsContentUtilsReporter;
3387
3388 static nsIContentPolicy* sContentPolicyService;
3389 static bool sTriedToGetContentPolicy;
3390
3391 static RefPtr<mozilla::intl::LineBreaker> sLineBreaker;
3392 static RefPtr<mozilla::intl::WordBreaker> sWordBreaker;
3393
3394 static mozilla::StaticRefPtr<nsIBidiKeyboard> sBidiKeyboard;
3395
3396 static bool sInitialized;
3397 static uint32_t sScriptBlockerCount;
3398 static uint32_t sDOMNodeRemovedSuppressCount;
3399
3400 // Not an nsCOMArray because removing elements from those is slower
3401 static AutoTArray<nsCOMPtr<nsIRunnable>, 8>* sBlockedScriptRunners;
3402 static uint32_t sRunnersCountAtFirstBlocker;
3403 static uint32_t sScriptBlockerCountWhereRunnersPrevented;
3404
3405 static nsIInterfaceRequestor* sSameOriginChecker;
3406
3407 static bool sIsHandlingKeyBoardEvent;
3408 #ifndef RELEASE_OR_BETA
3409 static bool sBypassCSSOMOriginCheck;
3410 #endif
3411
3412 class UserInteractionObserver;
3413 static UserInteractionObserver* sUserInteractionObserver;
3414
3415 static nsHtml5StringParser* sHTMLFragmentParser;
3416 static nsIParser* sXMLFragmentParser;
3417 static nsIFragmentContentSink* sXMLFragmentSink;
3418
3419 /**
3420 * True if there's a fragment parser activation on the stack.
3421 */
3422 static bool sFragmentParsingActive;
3423
3424 static nsString* sShiftText;
3425 static nsString* sControlText;
3426 static nsString* sMetaText;
3427 static nsString* sOSText;
3428 static nsString* sAltText;
3429 static nsString* sModifierSeparator;
3430
3431 // Alternate data mime type, used by the ScriptLoader to register and read the
3432 // bytecode out of the nsCacheInfoChannel.
3433 static nsCString* sJSBytecodeMimeType;
3434
3435 static mozilla::LazyLogModule gResistFingerprintingLog;
3436 static mozilla::LazyLogModule sDOMDumpLog;
3437
3438 static int32_t sInnerOrOuterWindowCount;
3439 static uint32_t sInnerOrOuterWindowSerialCounter;
3440 };
3441
3442 /* static */ inline ExtContentPolicyType
InternalContentPolicyTypeToExternal(nsContentPolicyType aType)3443 nsContentUtils::InternalContentPolicyTypeToExternal(nsContentPolicyType aType) {
3444 switch (aType) {
3445 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
3446 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
3447 case nsIContentPolicy::TYPE_INTERNAL_MODULE:
3448 case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
3449 case nsIContentPolicy::TYPE_INTERNAL_WORKER:
3450 case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
3451 case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
3452 case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
3453 case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
3454 case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
3455 case nsIContentPolicy::TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT:
3456 case nsIContentPolicy::TYPE_INTERNAL_FRAME_MESSAGEMANAGER_SCRIPT:
3457 return ExtContentPolicy::TYPE_SCRIPT;
3458
3459 case nsIContentPolicy::TYPE_INTERNAL_EMBED:
3460 case nsIContentPolicy::TYPE_INTERNAL_OBJECT:
3461 return ExtContentPolicy::TYPE_OBJECT;
3462
3463 case nsIContentPolicy::TYPE_INTERNAL_FRAME:
3464 case nsIContentPolicy::TYPE_INTERNAL_IFRAME:
3465 return ExtContentPolicy::TYPE_SUBDOCUMENT;
3466
3467 case nsIContentPolicy::TYPE_INTERNAL_AUDIO:
3468 case nsIContentPolicy::TYPE_INTERNAL_VIDEO:
3469 case nsIContentPolicy::TYPE_INTERNAL_TRACK:
3470 return ExtContentPolicy::TYPE_MEDIA;
3471
3472 case nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST:
3473 case nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE:
3474 return ExtContentPolicy::TYPE_XMLHTTPREQUEST;
3475
3476 case nsIContentPolicy::TYPE_INTERNAL_IMAGE:
3477 case nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD:
3478 case nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON:
3479 return ExtContentPolicy::TYPE_IMAGE;
3480
3481 case nsIContentPolicy::TYPE_INTERNAL_STYLESHEET:
3482 case nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD:
3483 return ExtContentPolicy::TYPE_STYLESHEET;
3484
3485 case nsIContentPolicy::TYPE_INTERNAL_DTD:
3486 case nsIContentPolicy::TYPE_INTERNAL_FORCE_ALLOWED_DTD:
3487 return ExtContentPolicy::TYPE_DTD;
3488
3489 case nsIContentPolicy::TYPE_INTERNAL_FONT_PRELOAD:
3490 return ExtContentPolicy::TYPE_FONT;
3491
3492 case nsIContentPolicy::TYPE_INTERNAL_FETCH_PRELOAD:
3493 return ExtContentPolicy::TYPE_FETCH;
3494
3495 default:
3496 return static_cast<ExtContentPolicyType>(aType);
3497 }
3498 }
3499
3500 namespace mozilla {
3501 std::ostream& operator<<(
3502 std::ostream& aOut,
3503 const mozilla::PreventDefaultResult aPreventDefaultResult);
3504 } // namespace mozilla
3505
3506 class MOZ_RAII nsAutoScriptBlocker {
3507 public:
nsAutoScriptBlocker()3508 explicit nsAutoScriptBlocker() { nsContentUtils::AddScriptBlocker(); }
~nsAutoScriptBlocker()3509 ~nsAutoScriptBlocker() { nsContentUtils::RemoveScriptBlocker(); }
3510
3511 private:
3512 };
3513
3514 class MOZ_STACK_CLASS nsAutoScriptBlockerSuppressNodeRemoved
3515 : public nsAutoScriptBlocker {
3516 public:
nsAutoScriptBlockerSuppressNodeRemoved()3517 nsAutoScriptBlockerSuppressNodeRemoved() {
3518 ++nsContentUtils::sDOMNodeRemovedSuppressCount;
3519 }
~nsAutoScriptBlockerSuppressNodeRemoved()3520 ~nsAutoScriptBlockerSuppressNodeRemoved() {
3521 --nsContentUtils::sDOMNodeRemovedSuppressCount;
3522 }
3523 };
3524
3525 namespace mozilla {
3526 namespace dom {
3527
3528 class TreeOrderComparator {
3529 public:
Equals(nsINode * aElem1,nsINode * aElem2)3530 bool Equals(nsINode* aElem1, nsINode* aElem2) const {
3531 return aElem1 == aElem2;
3532 }
LessThan(nsINode * aElem1,nsINode * aElem2)3533 bool LessThan(nsINode* aElem1, nsINode* aElem2) const {
3534 return nsContentUtils::PositionIsBefore(aElem1, aElem2);
3535 }
3536 };
3537
3538 } // namespace dom
3539 } // namespace mozilla
3540
3541 #define NS_INTERFACE_MAP_ENTRY_TEAROFF(_interface, _allocator) \
3542 if (aIID.Equals(NS_GET_IID(_interface))) { \
3543 foundInterface = static_cast<_interface*>(_allocator); \
3544 if (!foundInterface) { \
3545 *aInstancePtr = nullptr; \
3546 return NS_ERROR_OUT_OF_MEMORY; \
3547 } \
3548 } else
3549
3550 /*
3551 * In the following helper macros we exploit the fact that the result of a
3552 * series of additions will not be finite if any one of the operands in the
3553 * series is not finite.
3554 */
3555 #define NS_ENSURE_FINITE(f, rv) \
3556 if (!mozilla::IsFinite(f)) { \
3557 return (rv); \
3558 }
3559
3560 #define NS_ENSURE_FINITE2(f1, f2, rv) \
3561 if (!mozilla::IsFinite((f1) + (f2))) { \
3562 return (rv); \
3563 }
3564
3565 #define NS_ENSURE_FINITE4(f1, f2, f3, f4, rv) \
3566 if (!mozilla::IsFinite((f1) + (f2) + (f3) + (f4))) { \
3567 return (rv); \
3568 }
3569
3570 #define NS_ENSURE_FINITE5(f1, f2, f3, f4, f5, rv) \
3571 if (!mozilla::IsFinite((f1) + (f2) + (f3) + (f4) + (f5))) { \
3572 return (rv); \
3573 }
3574
3575 #define NS_ENSURE_FINITE6(f1, f2, f3, f4, f5, f6, rv) \
3576 if (!mozilla::IsFinite((f1) + (f2) + (f3) + (f4) + (f5) + (f6))) { \
3577 return (rv); \
3578 }
3579
3580 // Deletes a linked list iteratively to avoid blowing up the stack (bug 460444).
3581 #define NS_CONTENT_DELETE_LIST_MEMBER(type_, ptr_, member_) \
3582 { \
3583 type_* cur = (ptr_)->member_; \
3584 (ptr_)->member_ = nullptr; \
3585 while (cur) { \
3586 type_* next = cur->member_; \
3587 cur->member_ = nullptr; \
3588 delete cur; \
3589 cur = next; \
3590 } \
3591 }
3592
3593 #endif /* nsContentUtils_h___ */
3594