fune/parser/html/nsParserUtils.cpp
Tom Ritter 449237fc51 Bug 1378552 - Reduce the liklihood of inadvertently misusing NullPrincipal::Create(). r=ckerschb
NullPrincipal::Create() (will null OA) may cause an OriginAttributes bypass.
We change Create() so OriginAttributes is no longer optional, and rename
Create() with no arguments to make it more explicit about what the caller is doing.

MozReview-Commit-ID: 7DQGlgh1tgJ
2018-03-22 13:36:20 -05:00

175 lines
5.6 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsParserUtils.h"
#include "NullPrincipal.h"
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/ScriptLoader.h"
#include "nsAttrName.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsContentCID.h"
#include "nsContentUtils.h"
#include "nsEscape.h"
#include "nsHTMLParts.h"
#include "nsHtml5Module.h"
#include "nsIComponentManager.h"
#include "nsIContent.h"
#include "nsIContentSink.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIDOMElement.h"
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsIDTD.h"
#include "nsIDocument.h"
#include "nsIDocumentEncoder.h"
#include "nsIFragmentContentSink.h"
#include "nsIParser.h"
#include "nsIScriptableUnescapeHTML.h"
#include "nsISupportsPrimitives.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsParserCIID.h"
#include "nsString.h"
#include "nsTreeSanitizer.h"
#include "nsXPCOM.h"
#define XHTML_DIV_TAG "div xmlns=\"http://www.w3.org/1999/xhtml\""
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS(nsParserUtils, nsIScriptableUnescapeHTML, nsIParserUtils)
NS_IMETHODIMP
nsParserUtils::ConvertToPlainText(const nsAString& aFromStr,
uint32_t aFlags,
uint32_t aWrapCol,
nsAString& aToStr)
{
return nsContentUtils::ConvertToPlainText(aFromStr, aToStr, aFlags, aWrapCol);
}
NS_IMETHODIMP
nsParserUtils::Unescape(const nsAString& aFromStr, nsAString& aToStr)
{
return nsContentUtils::ConvertToPlainText(
aFromStr,
aToStr,
nsIDocumentEncoder::OutputSelectionOnly |
nsIDocumentEncoder::OutputAbsoluteLinks,
0);
}
NS_IMETHODIMP
nsParserUtils::Sanitize(const nsAString& aFromStr,
uint32_t aFlags,
nsAString& aToStr)
{
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), "about:blank");
nsCOMPtr<nsIPrincipal> principal = NullPrincipal::CreateWithoutOriginAttributes();
nsCOMPtr<nsIDOMDocument> domDocument;
nsresult rv = NS_NewDOMDocument(getter_AddRefs(domDocument),
EmptyString(),
EmptyString(),
nullptr,
uri,
uri,
principal,
true,
nullptr,
DocumentFlavorHTML);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
rv = nsContentUtils::ParseDocumentHTML(aFromStr, document, false);
NS_ENSURE_SUCCESS(rv, rv);
nsTreeSanitizer sanitizer(aFlags);
sanitizer.Sanitize(document);
nsCOMPtr<nsIDocumentEncoder> encoder =
do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "text/html");
encoder->NativeInit(document,
NS_LITERAL_STRING("text/html"),
nsIDocumentEncoder::OutputDontRewriteEncodingDeclaration |
nsIDocumentEncoder::OutputNoScriptContent |
nsIDocumentEncoder::OutputEncodeBasicEntities |
nsIDocumentEncoder::OutputLFLineBreak |
nsIDocumentEncoder::OutputRaw);
return encoder->EncodeToString(aToStr);
}
NS_IMETHODIMP
nsParserUtils::ParseFragment(const nsAString& aFragment,
bool aIsXML,
nsIURI* aBaseURI,
nsIDOMElement* aContextElement,
nsIDOMDocumentFragment** aReturn)
{
return nsParserUtils::ParseFragment(
aFragment, 0, aIsXML, aBaseURI, aContextElement, aReturn);
}
NS_IMETHODIMP
nsParserUtils::ParseFragment(const nsAString& aFragment,
uint32_t aFlags,
bool aIsXML,
nsIURI* aBaseURI,
nsIDOMElement* aContextElement,
nsIDOMDocumentFragment** aReturn)
{
NS_ENSURE_ARG(aContextElement);
*aReturn = nullptr;
nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsINode> contextNode;
contextNode = do_QueryInterface(aContextElement);
document = contextNode->OwnerDoc();
nsAutoScriptBlockerSuppressNodeRemoved autoBlocker;
// stop scripts
RefPtr<ScriptLoader> loader;
bool scripts_enabled = false;
if (document) {
loader = document->ScriptLoader();
scripts_enabled = loader->GetEnabled();
}
if (scripts_enabled) {
loader->SetEnabled(false);
}
// Wrap things in a div or body for parsing, but it won't show up in
// the fragment.
nsresult rv = NS_OK;
AutoTArray<nsString, 2> tagStack;
nsCOMPtr<nsIContent> fragment;
if (aIsXML) {
// XHTML
tagStack.AppendElement(NS_LITERAL_STRING(XHTML_DIV_TAG));
rv = nsContentUtils::ParseFragmentXML(
aFragment, document, tagStack, true, aReturn);
fragment = do_QueryInterface(*aReturn);
} else {
NS_ADDREF(*aReturn = new DocumentFragment(document->NodeInfoManager()));
fragment = do_QueryInterface(*aReturn);
rv = nsContentUtils::ParseFragmentHTML(
aFragment, fragment, nsGkAtoms::body, kNameSpaceID_XHTML, false, true);
}
if (fragment) {
nsTreeSanitizer sanitizer(aFlags);
sanitizer.Sanitize(fragment);
}
if (scripts_enabled) {
loader->SetEnabled(true);
}
return rv;
}