mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 20:07:30 +09:00
Issue #2641 - Speculative load changes for referrerpolicy
This commit is contained in:
parent
19c4996881
commit
f6f046930d
20 changed files with 262 additions and 128 deletions
|
|
@ -472,6 +472,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
|
|||
nsAutoString media;
|
||||
nsAutoString anchor;
|
||||
nsAutoString crossOrigin;
|
||||
nsAutoString referrerPolicy;
|
||||
nsAutoString destination;
|
||||
|
||||
crossOrigin.SetIsVoid(true);
|
||||
|
|
@ -660,6 +661,15 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
|
|||
destination = value;
|
||||
destination.StripWhitespace();
|
||||
}
|
||||
} else if (attr.LowerCaseEqualsLiteral("referrerpolicy")) {
|
||||
// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#referrer-policy-attribute
|
||||
// The spec says that the referrer policy attribute is an enumerated attribute,
|
||||
// case insensitive and includes the empty string.
|
||||
// We will parse the value with AttributeReferrerPolicyFromString
|
||||
// later, which will handle parsing it as an enumerated attribute.
|
||||
if (referrerPolicy.IsEmpty()) {
|
||||
referrerPolicy = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -673,7 +683,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
|
|||
rv = ProcessLink(anchor, href, rel,
|
||||
// prefer RFC 5987 variant over non-I18zed version
|
||||
titleStar.IsEmpty() ? title : titleStar,
|
||||
type, media, crossOrigin, destination);
|
||||
type, media, crossOrigin, referrerPolicy, destination);
|
||||
}
|
||||
|
||||
href.Truncate();
|
||||
|
|
@ -682,6 +692,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
|
|||
type.Truncate();
|
||||
media.Truncate();
|
||||
anchor.Truncate();
|
||||
referrerPolicy.Truncate();
|
||||
crossOrigin.SetIsVoid(true);
|
||||
destination.Truncate();
|
||||
|
||||
|
|
@ -696,7 +707,7 @@ nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
|
|||
rv = ProcessLink(anchor, href, rel,
|
||||
// prefer RFC 5987 variant over non-I18zed version
|
||||
titleStar.IsEmpty() ? title : titleStar,
|
||||
type, media, crossOrigin, destination);
|
||||
type, media, crossOrigin, referrerPolicy, destination);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
@ -708,6 +719,7 @@ nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
|
|||
const nsSubstring& aRel, const nsSubstring& aTitle,
|
||||
const nsSubstring& aType, const nsSubstring& aMedia,
|
||||
const nsSubstring& aCrossOrigin,
|
||||
const nsAString& aReferrerPolicy,
|
||||
const nsSubstring& aDestination)
|
||||
{
|
||||
uint32_t linkTypes =
|
||||
|
|
@ -749,7 +761,7 @@ nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
|
|||
|
||||
bool isAlternate = linkTypes & nsStyleLinkElement::eALTERNATE;
|
||||
return ProcessStyleLink(nullptr, aHref, isAlternate, aTitle, aType,
|
||||
aMedia);
|
||||
aMedia, aReferrerPolicy);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
@ -758,7 +770,8 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
|
|||
bool aAlternate,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aType,
|
||||
const nsSubstring& aMedia)
|
||||
const nsSubstring& aMedia,
|
||||
const nsSubstring& aReferrerPolicy)
|
||||
{
|
||||
if (aAlternate && aTitle.IsEmpty()) {
|
||||
// alternates must have title return without error, for now
|
||||
|
|
@ -797,13 +810,18 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
|
|||
("nsContentSink::ProcessStyleLink, integrity=%s",
|
||||
NS_ConvertUTF16toUTF8(integrity).get()));
|
||||
}
|
||||
mozilla::net::ReferrerPolicy referrerPolicy =
|
||||
mozilla::net::AttributeReferrerPolicyFromString(aReferrerPolicy);
|
||||
if (referrerPolicy == net::RP_Unset) {
|
||||
referrerPolicy = mDocument->GetReferrerPolicy();
|
||||
}
|
||||
|
||||
// If this is a fragment parser, we don't want to observe.
|
||||
// We don't support CORS for processing instructions
|
||||
bool isAlternate;
|
||||
bool isExplicitlyEnabled;
|
||||
rv = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, aAlternate,
|
||||
CORS_NONE, mDocument->GetReferrerPolicy(),
|
||||
CORS_NONE, referrerPolicy,
|
||||
integrity, mRunsToCompletion ? nullptr : this,
|
||||
&isAlternate, &isExplicitlyEnabled);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ protected:
|
|||
const nsSubstring& aHref, const nsSubstring& aRel,
|
||||
const nsSubstring& aTitle, const nsSubstring& aType,
|
||||
const nsSubstring& aMedia, const nsSubstring& aCrossOrigin,
|
||||
const nsSubstring& aReferrerPolicy,
|
||||
const nsSubstring& aDestination);
|
||||
|
||||
virtual nsresult ProcessStyleLink(nsIContent* aElement,
|
||||
|
|
@ -161,7 +162,8 @@ protected:
|
|||
bool aAlternate,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aType,
|
||||
const nsSubstring& aMedia);
|
||||
const nsSubstring& aMedia,
|
||||
const nsSubstring& aReferrerPolicy);
|
||||
|
||||
void PrefetchOrPreloadHref(const nsAString &aHref,
|
||||
nsINode *aSource,
|
||||
|
|
|
|||
|
|
@ -411,6 +411,16 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
|||
|
||||
bool doneLoading = false;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Load the link's referrerpolicy attribute. If the link does not provide a
|
||||
// referrerpolicy attribute, ignore this and use the document's referrer
|
||||
// policy
|
||||
|
||||
net::ReferrerPolicy referrerPolicy = GetLinkReferrerPolicy();
|
||||
if (referrerPolicy == net::RP_Unset) {
|
||||
referrerPolicy = doc->GetReferrerPolicy();
|
||||
}
|
||||
|
||||
if (isInline) {
|
||||
nsAutoString text;
|
||||
if (!nsContentUtils::GetNodeTextContent(thisContent, false, text, fallible)) {
|
||||
|
|
@ -429,7 +439,7 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
|||
|
||||
// Parse the style sheet.
|
||||
rv = doc->CSSLoader()->
|
||||
LoadInlineStyle(thisContent, text, mLineNumber, title, media,
|
||||
LoadInlineStyle(thisContent, text, mLineNumber, title, media, referrerPolicy,
|
||||
scopeElement, aObserver, &doneLoading, &isAlternate, &isExplicitlyEnabled);
|
||||
} else {
|
||||
nsAutoString integrity;
|
||||
|
|
@ -440,15 +450,6 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
|||
NS_ConvertUTF16toUTF8(integrity).get()));
|
||||
}
|
||||
|
||||
// if referrer attributes are enabled in preferences, load the link's referrer
|
||||
// attribute. If the link does not provide a referrer attribute, ignore this
|
||||
// and use the document's referrer policy
|
||||
|
||||
net::ReferrerPolicy referrerPolicy = GetLinkReferrerPolicy();
|
||||
if (referrerPolicy == net::RP_Unset) {
|
||||
referrerPolicy = doc->GetReferrerPolicy();
|
||||
}
|
||||
|
||||
// XXXbz clone the URI here to work around content policies modifying URIs.
|
||||
nsCOMPtr<nsIURI> clonedURI;
|
||||
uri->Clone(getter_AddRefs(clonedURI));
|
||||
|
|
|
|||
|
|
@ -324,6 +324,12 @@ HTMLScriptElement::GetCORSMode() const
|
|||
return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
|
||||
}
|
||||
|
||||
mozilla::net::ReferrerPolicy
|
||||
HTMLScriptElement::GetReferrerPolicy()
|
||||
{
|
||||
return GetReferrerPolicyAsEnum();
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLScriptElement::HasScriptContent()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public:
|
|||
virtual void GetScriptCharset(nsAString& charset) override;
|
||||
virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) override;
|
||||
virtual CORSMode GetCORSMode() const override;
|
||||
virtual mozilla::net::ReferrerPolicy GetReferrerPolicy() override;
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
|
@ -96,6 +97,14 @@ public:
|
|||
{
|
||||
SetHTMLAttr(nsGkAtoms::integrity, aIntegrity, rv);
|
||||
}
|
||||
void SetReferrerPolicy(const nsAString& aReferrerPolicy, ErrorResult& aError)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrerPolicy, aError);
|
||||
}
|
||||
void GetReferrerPolicy(nsAString& aReferrerPolicy)
|
||||
{
|
||||
GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrerPolicy);
|
||||
}
|
||||
bool Async();
|
||||
void SetAsync(bool aValue, ErrorResult& rv);
|
||||
bool NoModule();
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
SimpleTest.waitForFocus(runTests);
|
||||
|
||||
function runTests() {
|
||||
var elements = [ "iframe", "img", "a", "area", "link" ];
|
||||
var elements = [ "iframe", "img", "a", "area", "link", "script"];
|
||||
|
||||
for (var i = 0; i < elements.length; ++i) {
|
||||
reflectLimitedEnumerated({
|
||||
|
|
|
|||
|
|
@ -1563,7 +1563,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
// Step 15. and later in the HTML5 spec
|
||||
nsresult rv = NS_OK;
|
||||
RefPtr<ScriptLoadRequest> request;
|
||||
mozilla::net::ReferrerPolicy ourRefPolicy = mDocument->GetReferrerPolicy();
|
||||
mozilla::net::ReferrerPolicy referrerPolicy = GetReferrerPolicy(aElement);
|
||||
if (aElement->GetScriptExternal()) {
|
||||
// external script
|
||||
nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
|
||||
|
|
@ -1593,7 +1593,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
aElement->GetScriptCharset(elementCharset);
|
||||
if (elementCharset.Equals(preloadCharset) &&
|
||||
ourCORSMode == request->CORSMode() &&
|
||||
ourRefPolicy == request->ReferrerPolicy() &&
|
||||
referrerPolicy == request->ReferrerPolicy() &&
|
||||
scriptKind == request->mKind) {
|
||||
rv = CheckContentPolicy(mDocument, aElement, request->mURI, type, false);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
@ -1639,7 +1639,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
nsCOMPtr<nsIPrincipal> principal = scriptContent->NodePrincipal();
|
||||
|
||||
request = CreateLoadRequest(scriptKind, scriptURI, aElement, principal,
|
||||
ourCORSMode, sriMetadata, ourRefPolicy);
|
||||
ourCORSMode, sriMetadata, referrerPolicy);
|
||||
request->mIsInline = false;
|
||||
request->SetScriptMode(aElement->GetScriptDeferred(),
|
||||
aElement->GetScriptAsync());
|
||||
|
|
@ -1760,7 +1760,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
mDocument->NodePrincipal(),
|
||||
CORS_NONE,
|
||||
SRIMetadata(), // SRI doesn't apply
|
||||
ourRefPolicy);
|
||||
referrerPolicy);
|
||||
request->mIsInline = true;
|
||||
request->mLineNo = aElement->GetScriptLineNumber();
|
||||
|
||||
|
|
@ -1826,6 +1826,17 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
return ProcessRequest(request) == NS_ERROR_HTMLPARSER_BLOCK;
|
||||
}
|
||||
|
||||
mozilla::net::ReferrerPolicy
|
||||
ScriptLoader::GetReferrerPolicy(nsIScriptElement* aElement)
|
||||
{
|
||||
mozilla::net::ReferrerPolicy scriptReferrerPolicy =
|
||||
aElement->GetReferrerPolicy();
|
||||
if (scriptReferrerPolicy != mozilla::net::RP_Unset) {
|
||||
return scriptReferrerPolicy;
|
||||
}
|
||||
return mDocument->GetReferrerPolicy();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class NotifyOffThreadScriptLoadCompletedRunnable : public Runnable
|
||||
|
|
|
|||
|
|
@ -619,6 +619,12 @@ private:
|
|||
void ContinueParserAsync(ScriptLoadRequest* aParserBlockingRequest);
|
||||
|
||||
|
||||
/**
|
||||
* Given a script element, get the referrer policy that should be applied to
|
||||
* load requests.
|
||||
*/
|
||||
mozilla::net::ReferrerPolicy GetReferrerPolicy(nsIScriptElement* aElement);
|
||||
|
||||
/**
|
||||
* Helper function to check the content policy for a given request.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsIDOMHTMLScriptElement.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
|
||||
#define NS_ISCRIPTELEMENT_IID \
|
||||
{ 0xe60fca9b, 0x1b96, 0x4e4e, \
|
||||
|
|
@ -263,6 +264,14 @@ public:
|
|||
return mozilla::CORS_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get referrer policy of the script element
|
||||
*/
|
||||
virtual mozilla::net::ReferrerPolicy GetReferrerPolicy()
|
||||
{
|
||||
return mozilla::net::RP_Unset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an error event
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ interface HTMLScriptElement : HTMLElement {
|
|||
[CEReactions, SetterThrows]
|
||||
attribute DOMString? crossOrigin;
|
||||
[CEReactions, SetterThrows]
|
||||
attribute DOMString referrerPolicy;
|
||||
[CEReactions, SetterThrows]
|
||||
attribute DOMString text;
|
||||
[CEReactions, SetterThrows, Pure]
|
||||
attribute DOMString nonce;
|
||||
|
|
|
|||
|
|
@ -655,7 +655,8 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
|
|||
bool aAlternate,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aType,
|
||||
const nsSubstring& aMedia)
|
||||
const nsSubstring& aMedia,
|
||||
const nsSubstring& aReferrerPolicy)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
mPrettyPrintXML = false;
|
||||
|
|
@ -714,7 +715,7 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
|
|||
|
||||
// Let nsContentSink deal with css.
|
||||
rv = nsContentSink::ProcessStyleLink(aElement, aHref, aAlternate,
|
||||
aTitle, aType, aMedia);
|
||||
aTitle, aType, aMedia, aReferrerPolicy);
|
||||
|
||||
// nsContentSink::ProcessStyleLink handles the bookkeeping here wrt
|
||||
// pending sheets.
|
||||
|
|
@ -1261,7 +1262,9 @@ nsXMLContentSink::HandleProcessingInstruction(const char16_t *aTarget,
|
|||
return DidProcessATokenImpl();
|
||||
}
|
||||
|
||||
rv = ProcessStyleLink(node, href, isAlternate, title, type, media);
|
||||
// <?xml-stylesheet?> processing instructions don't have a referrerpolicy
|
||||
// pseudo-attribute, so we pass in an empty string
|
||||
rv = ProcessStyleLink(node, href, isAlternate, title, type, media, EmptyString());
|
||||
return NS_SUCCEEDED(rv) ? DidProcessATokenImpl() : rv;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,8 @@ protected:
|
|||
bool aAlternate,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aType,
|
||||
const nsSubstring& aMedia) override;
|
||||
const nsSubstring& aMedia,
|
||||
const nsSubstring& aReferrerPolicy) override;
|
||||
|
||||
nsresult LoadXSLStyleSheet(nsIURI* aUrl);
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,9 @@ protected:
|
|||
bool aAlternate,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aType,
|
||||
const nsSubstring& aMedia) override;
|
||||
const nsSubstring& aMedia,
|
||||
const nsSubstring& aReferrerPolicy) override;
|
||||
|
||||
nsresult LoadXSLStyleSheet(nsIURI* aUrl);
|
||||
void StartLayout();
|
||||
|
||||
|
|
@ -332,7 +334,8 @@ nsXMLFragmentContentSink::ProcessStyleLink(nsIContent* aElement,
|
|||
bool aAlternate,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aType,
|
||||
const nsSubstring& aMedia)
|
||||
const nsSubstring& aMedia,
|
||||
const nsSubstring& aReferrerPolicy)
|
||||
{
|
||||
// don't process until moved to document
|
||||
return NS_OK;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue