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