diff --git a/browser/base/content/browser-media.js b/browser/base/content/browser-media.js
index 5719f27d861c9..6343b3c0d87c0 100644
--- a/browser/base/content/browser-media.js
+++ b/browser/base/content/browser-media.js
@@ -34,11 +34,23 @@ var gEMEHandler = {
}
return true;
},
- getLearnMoreLink(msgId) {
- let text = gNavigatorBundle.getString("emeNotifications." + msgId + ".learnMoreLabel");
+ getEMEDisabledFragment(msgId) {
+ let mainMessage = gNavigatorBundle.getString("emeNotifications.drmContentDisabled.message");
+ let [prefix, suffix] = mainMessage.split(/%(?:1\$)?S/).map(s => document.createTextNode(s));
+ let text = gNavigatorBundle.getString("emeNotifications.drmContentDisabled.learnMoreLabel");
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
- return "";
+ let link = document.createElement("label");
+ link.className = "text-link";
+ link.setAttribute("href", baseURL + "drm-content");
+ link.textContent = text;
+
+ let fragment = document.createDocumentFragment();
+ [prefix, link, suffix].forEach(n => fragment.appendChild(n));
+ return fragment;
+ },
+ getMessageWithBrandName(notificationId) {
+ let msgId = "emeNotifications." + notificationId + ".message";
+ return gNavigatorBundle.getFormattedString(msgId, [this._brandShortName]);
},
receiveMessage({target: browser, data: data}) {
let parsedData;
@@ -56,8 +68,8 @@ var gEMEHandler = {
let notificationId;
let buttonCallback;
- let params = [];
- switch (status) {
+ // Notification message can be either a string or a DOM fragment.
+ let notificationMessage; switch (status) {
case "available":
case "cdm-created":
// Only show the chain icon for proprietary CDMs. Clearkey is not one.
@@ -70,18 +82,18 @@ var gEMEHandler = {
case "api-disabled":
case "cdm-disabled":
notificationId = "drmContentDisabled";
- buttonCallback = gEMEHandler.ensureEMEEnabled.bind(gEMEHandler, browser, keySystem)
- params = [this.getLearnMoreLink(notificationId)];
+ buttonCallback = gEMEHandler.ensureEMEEnabled.bind(gEMEHandler, browser, keySystem);
+ notificationMessage = this.getEMEDisabledFragment();
break;
case "cdm-insufficient-version":
notificationId = "drmContentCDMInsufficientVersion";
- params = [this._brandShortName];
+ notificationMessage = this.getMessageWithBrandName(notificationId);
break;
case "cdm-not-installed":
notificationId = "drmContentCDMInstalling";
- params = [this._brandShortName];
+ notificationMessage = this.getMessageWithBrandName(notificationId);
break;
case "cdm-not-supported":
@@ -92,45 +104,28 @@ var gEMEHandler = {
Cu.reportError(new Error("Unknown message ('" + status + "') dealing with EME key request: " + data));
return;
}
+
+ // Now actually create the notification
- this.showNotificationBar(browser, notificationId, keySystem, params, buttonCallback);
- },
- showNotificationBar(browser, notificationId, keySystem, labelParams, callback) {
let box = gBrowser.getNotificationBox(browser);
if (box.getNotificationWithValue(notificationId)) {
return;
}
- let msgPrefix = "emeNotifications." + notificationId + ".";
- let msgId = msgPrefix + "message";
-
- let message = labelParams.length ?
- gNavigatorBundle.getFormattedString(msgId, labelParams) :
- gNavigatorBundle.getString(msgId);
-
let buttons = [];
- if (callback) {
+ if (buttonCallback) {
+ let msgPrefix = "emeNotifications." + notificationId + ".";
let btnLabelId = msgPrefix + "button.label";
let btnAccessKeyId = msgPrefix + "button.accesskey";
buttons.push({
label: gNavigatorBundle.getString(btnLabelId),
accessKey: gNavigatorBundle.getString(btnAccessKeyId),
- callback
+ callback: buttonCallback,
});
}
let iconURL = "chrome://browser/skin/drm-icon.svg#chains-black";
-
- // Do a little dance to get rich content into the notification:
- let fragment = document.createDocumentFragment();
- let descriptionContainer = document.createElement("description");
- // eslint-disable-next-line no-unsanitized/property
- descriptionContainer.innerHTML = message;
- while (descriptionContainer.childNodes.length) {
- fragment.appendChild(descriptionContainer.childNodes[0]);
- }
-
- box.appendNotification(fragment, notificationId, iconURL, box.PRIORITY_WARNING_MEDIUM,
+ box.appendNotification(notificationMessage, notificationId, iconURL, box.PRIORITY_WARNING_MEDIUM,
buttons);
},
showPopupNotificationForSuccess(browser, keySystem) {
diff --git a/browser/components/customizableui/CustomizableWidgets.jsm b/browser/components/customizableui/CustomizableWidgets.jsm
index 399ed94fb7fe3..ca07353aecf0f 100644
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -421,7 +421,7 @@ const CustomizableWidgets = [
// Put it all together...
let contents = bundle.getFormattedString("appMenuRemoteTabs.mobilePromo.text2", formatArgs);
// eslint-disable-next-line no-unsanitized/property
- promoParentElt.innerHTML = contents;
+ promoParentElt.unsafeSetInnerHTML(contents);
// We manually manage the "click" event to open the promo links because
// allowing the "text-link" widget handle it has 2 problems: (1) it only
// supports button 0 and (2) it's tricky to intercept when it does the
diff --git a/browser/modules/ExtensionsUI.jsm b/browser/modules/ExtensionsUI.jsm
index a7a856daa5d69..814265ea809a9 100644
--- a/browser/modules/ExtensionsUI.jsm
+++ b/browser/modules/ExtensionsUI.jsm
@@ -487,10 +487,10 @@ this.ExtensionsUI = {
let doc = this.browser.ownerDocument;
// eslint-disable-next-line no-unsanitized/property
doc.getElementById("addon-installed-notification-header")
- .innerHTML = msg1;
+ .unsafeSetInnerHTML(msg1);
// eslint-disable-next-line no-unsanitized/property
doc.getElementById("addon-installed-notification-message")
- .innerHTML = msg2;
+ .unsafeSetInnerHTML(msg2);
} else if (topic == "dismissed") {
resolve();
}
diff --git a/browser/modules/webrtcUI.jsm b/browser/modules/webrtcUI.jsm
index 9c54ad9ff6c0e..31ad49f7a83fb 100644
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -626,21 +626,26 @@ function prompt(aBrowser, aRequest) {
bundle.getString("getUserMedia.shareScreen.learnMoreLabel");
let baseURL =
Services.urlFormatter.formatURLPref("app.support.baseURL");
- let learnMore =
- "";
+
+ let learnMore = chromeWin.document.createElement("label");
+ learnMore.className = "text-link";
+ learnMore.setAttribute("href", baseURL + "screenshare-safety");
+ learnMore.textContent = learnMoreText;
if (type == "screen") {
string = bundle.getFormattedString("getUserMedia.shareScreenWarning.message",
- [learnMore]);
+ ["<>"]);
} else {
let brand =
doc.getElementById("bundle_brand").getString("brandShortName");
string = bundle.getFormattedString("getUserMedia.shareFirefoxWarning.message",
- [brand, learnMore]);
+ [brand, "<>"]);
}
- // eslint-disable-next-line no-unsanitized/property
- warning.innerHTML = string;
+
+ let [pre, post] = string.split("<>");
+ warning.textContent = pre;
+ warning.appendChild(learnMore);
+ warning.appendChild(chromeWin.document.createTextNode(post));
}
let perms = Services.perms;
diff --git a/devtools/client/responsive.html/components/browser.js b/devtools/client/responsive.html/components/browser.js
index d529bbbf2fd70..6395ff5ebf32d 100644
--- a/devtools/client/responsive.html/components/browser.js
+++ b/devtools/client/responsive.html/components/browser.js
@@ -15,6 +15,12 @@ const { DOM: dom, createClass, addons, PropTypes } =
const e10s = require("../utils/e10s");
const message = require("../utils/message");
+// Allow creation of HTML fragments without automatic sanitization, even
+// though we're in a chrome-privileged document.
+// This is, unfortunately, necessary in order to React to function
+// correctly.
+document.allowUnsafeHTML = true;
+
module.exports = createClass({
/**
diff --git a/devtools/shared/gcli/source/lib/gcli/util/util.js b/devtools/shared/gcli/source/lib/gcli/util/util.js
index 650e84b8f1f68..a9f9475dbfc13 100644
--- a/devtools/shared/gcli/source/lib/gcli/util/util.js
+++ b/devtools/shared/gcli/source/lib/gcli/util/util.js
@@ -498,7 +498,11 @@ exports.setContents = function(elem, contents) {
return;
}
- if ('innerHTML' in elem) {
+ if ('unsafeSetInnerHTML' in elem) {
+ // FIXME: Stop relying on unsanitized HTML.
+ elem.unsafeSetInnerHTML(contents);
+ }
+ else if ('innerHTML' in elem) {
elem.innerHTML = contents;
}
else {
diff --git a/devtools/shared/tests/browser/browser_l10n_localizeMarkup.js b/devtools/shared/tests/browser/browser_l10n_localizeMarkup.js
index 9fc2264671c7f..ecf5c52ad2090 100644
--- a/devtools/shared/tests/browser/browser_l10n_localizeMarkup.js
+++ b/devtools/shared/tests/browser/browser_l10n_localizeMarkup.js
@@ -18,7 +18,7 @@ add_task(function* () {
info("Create the test markup");
let div = document.createElement("div");
- div.innerHTML =
+ div.unsafeSetInnerHTML(
`
Text will disappear
@@ -32,7 +32,7 @@ add_task(function* () {
- `;
+ `);
info("Use localization helper to localize the test markup");
localizeMarkup(div);
diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp
index fffc66f222fe5..661e1aaf70484 100644
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -3722,6 +3722,12 @@ Element::SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError)
SetInnerHTMLInternal(aInnerHTML, aError);
}
+void
+Element::UnsafeSetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError)
+{
+ SetInnerHTMLInternal(aInnerHTML, aError, true);
+}
+
void
Element::GetOuterHTML(nsAString& aOuterHTML)
{
diff --git a/dom/base/Element.h b/dom/base/Element.h
index d4248444f1b14..50a19ea5bb914 100644
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -1128,6 +1128,7 @@ class Element : public FragmentOrElement
NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
virtual void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
+ void UnsafeSetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
void GetOuterHTML(nsAString& aOuterHTML);
void SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError);
void InsertAdjacentHTML(const nsAString& aPosition, const nsAString& aText,
diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp
index 608241975b452..6edfc3f34f07e 100644
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -2388,7 +2388,8 @@ ContainsMarkup(const nsAString& aStr)
}
void
-FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError)
+FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError,
+ bool aNeverSanitize)
{
FragmentOrElement* target = this;
// Handle template case.
@@ -2442,6 +2443,9 @@ FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult
contextNameSpaceID = shadowRoot->GetHost()->GetNameSpaceID();
}
+ auto sanitize = (aNeverSanitize ? nsContentUtils::NeverSanitize
+ : nsContentUtils::SanitizeSystemPrivileged);
+
if (doc->IsHTMLDocument()) {
int32_t oldChildCount = target->GetChildCount();
aError = nsContentUtils::ParseFragmentHTML(aInnerHTML,
@@ -2450,14 +2454,17 @@ FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult
contextNameSpaceID,
doc->GetCompatibilityMode() ==
eCompatibility_NavQuirks,
- true);
+ true,
+ sanitize);
mb.NodesAdded();
// HTML5 parser has notified, but not fired mutation events.
nsContentUtils::FireMutationEventsForDirectParsing(doc, target,
oldChildCount);
} else {
RefPtr df =
- nsContentUtils::CreateContextualFragment(target, aInnerHTML, true, aError);
+ nsContentUtils::CreateContextualFragment(target, aInnerHTML, true,
+ sanitize,
+ aError);
if (!aError.Failed()) {
// Suppress assertion about node removal mutation events that can't have
// listeners anyway, because no one has had the chance to register mutation
diff --git a/dom/base/FragmentOrElement.h b/dom/base/FragmentOrElement.h
index f0e6684416e36..43df06a1becae 100644
--- a/dom/base/FragmentOrElement.h
+++ b/dom/base/FragmentOrElement.h
@@ -375,7 +375,8 @@ class FragmentOrElement : public nsIContent
protected:
void GetMarkup(bool aIncludeSelf, nsAString& aMarkup);
- void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError);
+ void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError,
+ bool aNeverSanitize = false);
// Override from nsINode
virtual nsINode::nsSlots* CreateSlots() override;
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 0401c1e1de3d4..eaa092ef736f1 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -160,6 +160,7 @@
#include "nsIOfflineCacheUpdate.h"
#include "nsIParser.h"
#include "nsIParserService.h"
+#include "nsIParserUtils.h"
#include "nsIPermissionManager.h"
#include "nsIPluginHost.h"
#include "nsIRequest.h"
@@ -200,6 +201,7 @@
#include "nsTextFragment.h"
#include "nsTextNode.h"
#include "nsThreadUtils.h"
+#include "nsTreeSanitizer.h"
#include "nsUnicodeProperties.h"
#include "nsViewManager.h"
#include "nsViewportInfo.h"
@@ -4916,6 +4918,7 @@ already_AddRefed
nsContentUtils::CreateContextualFragment(nsINode* aContextNode,
const nsAString& aFragment,
bool aPreventScriptExecution,
+ SanitizeFragments aSanitize,
ErrorResult& aRv)
{
if (!aContextNode) {
@@ -4951,14 +4954,16 @@ nsContentUtils::CreateContextualFragment(nsINode* aContextNode,
contextAsContent->GetNameSpaceID(),
(document->GetCompatibilityMode() ==
eCompatibility_NavQuirks),
- aPreventScriptExecution);
+ aPreventScriptExecution,
+ aSanitize);
} else {
aRv = ParseFragmentHTML(aFragment, frag,
nsGkAtoms::body,
kNameSpaceID_XHTML,
(document->GetCompatibilityMode() ==
eCompatibility_NavQuirks),
- aPreventScriptExecution);
+ aPreventScriptExecution,
+ aSanitize);
}
return frag.forget();
@@ -5022,7 +5027,8 @@ nsContentUtils::CreateContextualFragment(nsINode* aContextNode,
nsCOMPtr frag;
aRv = ParseFragmentXML(aFragment, document, tagStack,
- aPreventScriptExecution, getter_AddRefs(frag));
+ aPreventScriptExecution, getter_AddRefs(frag),
+ aSanitize);
return frag.forget().downcast();
}
@@ -5049,7 +5055,8 @@ nsContentUtils::ParseFragmentHTML(const nsAString& aSourceBuffer,
nsIAtom* aContextLocalName,
int32_t aContextNamespace,
bool aQuirks,
- bool aPreventScriptExecution)
+ bool aPreventScriptExecution,
+ SanitizeFragments aSanitize)
{
AutoTimelineMarker m(aTargetNode->OwnerDoc()->GetDocShell(), "Parse HTML");
@@ -5063,13 +5070,41 @@ nsContentUtils::ParseFragmentHTML(const nsAString& aSourceBuffer,
NS_ADDREF(sHTMLFragmentParser = new nsHtml5StringParser());
// Now sHTMLFragmentParser owns the object
}
+
+ nsIContent* target = aTargetNode;
+
+ // If this is a chrome-privileged document, create a fragment first, and
+ // sanitize it before insertion.
+ RefPtr fragment;
+ if (aSanitize != NeverSanitize && !aTargetNode->OwnerDoc()->AllowUnsafeHTML()) {
+ fragment = new DocumentFragment(aTargetNode->OwnerDoc()->NodeInfoManager());
+ target = fragment;
+ }
+
nsresult rv =
sHTMLFragmentParser->ParseFragment(aSourceBuffer,
- aTargetNode,
+ target,
aContextLocalName,
aContextNamespace,
aQuirks,
aPreventScriptExecution);
+
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (fragment) {
+ // Don't fire mutation events for nodes removed by the sanitizer.
+ nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker;
+
+ nsTreeSanitizer sanitizer(nsIParserUtils::SanitizerAllowStyle |
+ nsIParserUtils::SanitizerAllowComments);
+ sanitizer.Sanitize(fragment);
+
+ ErrorResult error;
+ aTargetNode->AppendChild(*fragment, error);
+ rv = error.StealNSResult();
+ }
+
+
return rv;
}
@@ -5104,7 +5139,8 @@ nsContentUtils::ParseFragmentXML(const nsAString& aSourceBuffer,
nsIDocument* aDocument,
nsTArray& aTagStack,
bool aPreventScriptExecution,
- nsIDOMDocumentFragment** aReturn)
+ nsIDOMDocumentFragment** aReturn,
+ SanitizeFragments aSanitize)
{
AutoTimelineMarker m(aDocument->GetDocShell(), "Parse XML");
@@ -5143,6 +5179,20 @@ nsContentUtils::ParseFragmentXML(const nsAString& aSourceBuffer,
rv = sXMLFragmentSink->FinishFragmentParsing(aReturn);
sXMLFragmentParser->Reset();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // If this is a chrome-privileged document, sanitize the fragment before
+ // returning.
+ if (aSanitize != NeverSanitize && !aDocument->AllowUnsafeHTML()) {
+ // Don't fire mutation events for nodes removed by the sanitizer.
+ nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker;
+
+ RefPtr fragment = static_cast(*aReturn);
+
+ nsTreeSanitizer sanitizer(nsIParserUtils::SanitizerAllowStyle |
+ nsIParserUtils::SanitizerAllowComments);
+ sanitizer.Sanitize(fragment);
+ }
return rv;
}
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index fe7b5ab0ef088..8925be83107bc 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1499,6 +1499,11 @@ class nsContentUtils
*/
static bool IsValidNodeName(nsIAtom *aLocalName, nsIAtom *aPrefix,
int32_t aNamespaceID);
+
+ enum SanitizeFragments {
+ SanitizeSystemPrivileged,
+ NeverSanitize,
+ };
/**
* Creates a DocumentFragment from text using a context node to resolve
@@ -1513,6 +1518,8 @@ class nsContentUtils
* @param aFragment the string which is parsed to a DocumentFragment
* @param aReturn the resulting fragment
* @param aPreventScriptExecution whether to mark scripts as already started
+ * @param aSanitize whether the fragment should be sanitized prior to
+ * injection
*/
static nsresult CreateContextualFragment(nsINode* aContextNode,
const nsAString& aFragment,
@@ -1521,7 +1528,16 @@ class nsContentUtils
static already_AddRefed
CreateContextualFragment(nsINode* aContextNode, const nsAString& aFragment,
bool aPreventScriptExecution,
+ SanitizeFragments aSanitize,
mozilla::ErrorResult& aRv);
+ static already_AddRefed
+ CreateContextualFragment(nsINode* aContextNode, const nsAString& aFragment,
+ bool aPreventScriptExecution,
+ mozilla::ErrorResult& aRv)
+ {
+ return CreateContextualFragment(aContextNode, aFragment, aPreventScriptExecution,
+ SanitizeSystemPrivileged, aRv);
+ }
/**
* Invoke the fragment parsing algorithm (innerHTML) using the HTML parser.
@@ -1534,6 +1550,8 @@ class nsContentUtils
* @param aPreventScriptExecution true to prevent scripts from executing;
* don't set to false when parsing into a target node that has been
* bound to tree.
+ * @param aSanitize whether the fragment should be sanitized prior to
+ * injection
* @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
* fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
* long and NS_OK otherwise.
@@ -1543,7 +1561,8 @@ class nsContentUtils
nsIAtom* aContextLocalName,
int32_t aContextNamespace,
bool aQuirks,
- bool aPreventScriptExecution);
+ bool aPreventScriptExecution,
+ SanitizeFragments aSanitize = SanitizeSystemPrivileged);
/**
* Invoke the fragment parsing algorithm (innerHTML) using the XML parser.
@@ -1553,6 +1572,8 @@ class nsContentUtils
* @param aTagStack the namespace mapping context
* @param aPreventExecution whether to mark scripts as already started
* @param aReturn the result fragment
+ * @param aSanitize whether the fragment should be sanitized prior to
+ * injection
* @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
* fragments is made, a return code from the XML parser.
*/
@@ -1560,7 +1581,8 @@ class nsContentUtils
nsIDocument* aDocument,
nsTArray& aTagStack,
bool aPreventScriptExecution,
- nsIDOMDocumentFragment** aReturn);
+ nsIDOMDocumentFragment** aReturn,
+ SanitizeFragments aSanitize = SanitizeSystemPrivileged);
/**
* Parse a string into a document using the HTML parser.
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index b46c6b3502de0..0eb5bb9fbdb27 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1354,6 +1354,7 @@ nsIDocument::nsIDocument()
mIsContentDocument(false),
mMightHaveStaleServoData(false),
mBufferingCSPViolations(false),
+ mAllowUnsafeHTML(false),
mIsScopedStyleEnabled(eScopedStyle_Unknown),
mCompatMode(eCompatibility_FullStandards),
mReadyState(ReadyState::READYSTATE_UNINITIALIZED),
@@ -6095,6 +6096,13 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value*
return true;
}
+bool
+nsIDocument::AllowUnsafeHTML() const
+{
+ return (!nsContentUtils::IsSystemPrincipal(NodePrincipal()) ||
+ mAllowUnsafeHTML);
+}
+
bool
nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
{
diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h
index 13a61d84f5681..a9d56b2166303 100644
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2803,6 +2803,8 @@ class nsIDocument : public nsINode,
CreateAttributeNS(const nsAString& aNamespaceURI,
const nsAString& aQualifiedName,
mozilla::ErrorResult& rv);
+ void SetAllowUnsafeHTML(bool aAllow) { mAllowUnsafeHTML = aAllow; }
+ bool AllowUnsafeHTML() const;
void GetInputEncoding(nsAString& aInputEncoding) const;
already_AddRefed GetLocation() const;
void GetReferrer(nsAString& aReferrer) const;
@@ -3384,6 +3386,10 @@ class nsIDocument : public nsINode,
// True if any CSP violation reports for this doucment will be buffered in
// mBufferedCSPViolations instead of being sent immediately.
bool mBufferingCSPViolations : 1;
+
+ // True if unsafe HTML fragments should be allowed in chrome-privileged
+ // documents.
+ bool mAllowUnsafeHTML : 1;
// Whether