Bug 1761242 - Make link asset parsing accessible in nsNetUtils.h r=necko-reviewers,dragana

Differential Revision: https://phabricator.services.mozilla.com/D142053
This commit is contained in:
Manuel Bucher
2022-04-01 13:45:20 +00:00
parent 2827af7cb1
commit 1b60ffbc06
5 changed files with 178 additions and 178 deletions

View File

@@ -148,7 +148,7 @@ bool HTMLLinkElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
}
if (aAttribute == nsGkAtoms::as) {
ParseAsValue(aValue, aResult);
net::ParseAsValue(aValue, aResult);
return true;
}
@@ -419,79 +419,13 @@ void HTMLLinkElement::GetAs(nsAString& aResult) {
GetEnumAttr(nsGkAtoms::as, "", aResult);
}
enum ASDestination : uint8_t {
DESTINATION_INVALID,
DESTINATION_AUDIO,
DESTINATION_DOCUMENT,
DESTINATION_EMBED,
DESTINATION_FONT,
DESTINATION_IMAGE,
DESTINATION_MANIFEST,
DESTINATION_OBJECT,
DESTINATION_REPORT,
DESTINATION_SCRIPT,
DESTINATION_SERVICEWORKER,
DESTINATION_SHAREDWORKER,
DESTINATION_STYLE,
DESTINATION_TRACK,
DESTINATION_VIDEO,
DESTINATION_WORKER,
DESTINATION_XSLT,
DESTINATION_FETCH
};
static const nsAttrValue::EnumTable kAsAttributeTable[] = {
{"", DESTINATION_INVALID}, {"audio", DESTINATION_AUDIO},
{"font", DESTINATION_FONT}, {"image", DESTINATION_IMAGE},
{"script", DESTINATION_SCRIPT}, {"style", DESTINATION_STYLE},
{"track", DESTINATION_TRACK}, {"video", DESTINATION_VIDEO},
{"fetch", DESTINATION_FETCH}, {nullptr, 0}};
/* static */
void HTMLLinkElement::ParseAsValue(const nsAString& aValue,
nsAttrValue& aResult) {
DebugOnly<bool> success =
aResult.ParseEnumValue(aValue, kAsAttributeTable, false,
// default value is a empty string
// if aValue is not a value we
// understand
&kAsAttributeTable[0]);
MOZ_ASSERT(success);
}
/* static */
nsContentPolicyType HTMLLinkElement::AsValueToContentPolicy(
const nsAttrValue& aValue) {
switch (aValue.GetEnumValue()) {
case DESTINATION_INVALID:
return nsIContentPolicy::TYPE_INVALID;
case DESTINATION_AUDIO:
return nsIContentPolicy::TYPE_INTERNAL_AUDIO;
case DESTINATION_TRACK:
return nsIContentPolicy::TYPE_INTERNAL_TRACK;
case DESTINATION_VIDEO:
return nsIContentPolicy::TYPE_INTERNAL_VIDEO;
case DESTINATION_FONT:
return nsIContentPolicy::TYPE_FONT;
case DESTINATION_IMAGE:
return nsIContentPolicy::TYPE_IMAGE;
case DESTINATION_SCRIPT:
return nsIContentPolicy::TYPE_SCRIPT;
case DESTINATION_STYLE:
return nsIContentPolicy::TYPE_STYLESHEET;
case DESTINATION_FETCH:
return nsIContentPolicy::TYPE_INTERNAL_FETCH_PRELOAD;
}
return nsIContentPolicy::TYPE_INVALID;
}
void HTMLLinkElement::GetContentPolicyMimeTypeMedia(
nsAttrValue& aAsAttr, nsContentPolicyType& aPolicyType, nsString& aMimeType,
nsAString& aMedia) {
nsAutoString as;
GetAttr(kNameSpaceID_None, nsGkAtoms::as, as);
ParseAsValue(as, aAsAttr);
aPolicyType = AsValueToContentPolicy(aAsAttr);
net::ParseAsValue(as, aAsAttr);
aPolicyType = net::AsValueToContentPolicy(aAsAttr);
nsAutoString type;
GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
@@ -542,9 +476,9 @@ void HTMLLinkElement::
GetContentPolicyMimeTypeMedia(asAttr, policyType, mimeType, media);
if (policyType == nsIContentPolicy::TYPE_INVALID ||
!CheckPreloadAttrs(asAttr, mimeType, media, OwnerDoc())) {
!net::CheckPreloadAttrs(asAttr, mimeType, media, OwnerDoc())) {
// Ignore preload with a wrong or empty as attribute.
WarnIgnoredPreload(*OwnerDoc(), *uri);
net::WarnIgnoredPreload(*OwnerDoc(), *uri);
return;
}
@@ -601,11 +535,11 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
GetContentPolicyMimeTypeMedia(asAttr, asPolicyType, mimeType, media);
if (asPolicyType == nsIContentPolicy::TYPE_INVALID ||
!CheckPreloadAttrs(asAttr, mimeType, media, OwnerDoc())) {
!net::CheckPreloadAttrs(asAttr, mimeType, media, OwnerDoc())) {
// Ignore preload with a wrong or empty as attribute, but be sure to cancel
// the old one.
CancelPrefetchOrPreload();
WarnIgnoredPreload(*OwnerDoc(), *uri);
net::WarnIgnoredPreload(*OwnerDoc(), *uri);
return;
}
@@ -623,8 +557,8 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
if (aName == nsGkAtoms::as) {
if (aOldValue) {
oldPolicyType = AsValueToContentPolicy(*aOldValue);
if (!CheckPreloadAttrs(*aOldValue, mimeType, media, OwnerDoc())) {
oldPolicyType = net::AsValueToContentPolicy(*aOldValue);
if (!net::CheckPreloadAttrs(*aOldValue, mimeType, media, OwnerDoc())) {
oldPolicyType = nsIContentPolicy::TYPE_INVALID;
}
} else {
@@ -638,7 +572,7 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
}
nsAutoString oldMimeType;
nsContentUtils::SplitMimeType(oldType, oldMimeType, notUsed);
if (CheckPreloadAttrs(asAttr, oldMimeType, media, OwnerDoc())) {
if (net::CheckPreloadAttrs(asAttr, oldMimeType, media, OwnerDoc())) {
oldPolicyType = asPolicyType;
} else {
oldPolicyType = nsIContentPolicy::TYPE_INVALID;
@@ -649,7 +583,7 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
if (aOldValue) {
aOldValue->ToString(oldMedia);
}
if (CheckPreloadAttrs(asAttr, mimeType, oldMedia, OwnerDoc())) {
if (net::CheckPreloadAttrs(asAttr, mimeType, oldMedia, OwnerDoc())) {
oldPolicyType = asPolicyType;
} else {
oldPolicyType = nsIContentPolicy::TYPE_INVALID;
@@ -695,95 +629,6 @@ void HTMLLinkElement::CancelPreload() {
}
}
// We will use official mime-types from:
// https://www.iana.org/assignments/media-types/media-types.xhtml#font
// We do not support old deprecated mime-types for preload feature.
// (We currectly do not support font/collection)
static uint32_t StyleLinkElementFontMimeTypesNum = 5;
static const char* StyleLinkElementFontMimeTypes[] = {
"font/otf", "font/sfnt", "font/ttf", "font/woff", "font/woff2"};
bool IsFontMimeType(const nsAString& aType) {
if (aType.IsEmpty()) {
return true;
}
for (uint32_t i = 0; i < StyleLinkElementFontMimeTypesNum; i++) {
if (aType.EqualsASCII(StyleLinkElementFontMimeTypes[i])) {
return true;
}
}
return false;
}
bool HTMLLinkElement::CheckPreloadAttrs(const nsAttrValue& aAs,
const nsAString& aType,
const nsAString& aMedia,
Document* aDocument) {
nsContentPolicyType policyType = AsValueToContentPolicy(aAs);
if (policyType == nsIContentPolicy::TYPE_INVALID) {
return false;
}
// Check if media attribute is valid.
if (!aMedia.IsEmpty()) {
RefPtr<MediaList> mediaList =
MediaList::Create(NS_ConvertUTF16toUTF8(aMedia));
if (!mediaList->Matches(*aDocument)) {
return false;
}
}
if (aType.IsEmpty()) {
return true;
}
if (policyType == nsIContentPolicy::TYPE_INTERNAL_FETCH_PRELOAD) {
return true;
}
nsAutoString type(aType);
ToLowerCase(type);
if (policyType == nsIContentPolicy::TYPE_MEDIA) {
if (aAs.GetEnumValue() == DESTINATION_TRACK) {
return type.EqualsASCII("text/vtt");
}
Maybe<MediaContainerType> mimeType = MakeMediaContainerType(aType);
if (!mimeType) {
return false;
}
DecoderDoctorDiagnostics diagnostics;
CanPlayStatus status =
DecoderTraits::CanHandleContainerType(*mimeType, &diagnostics);
// Preload if this return CANPLAY_YES and CANPLAY_MAYBE.
return status != CANPLAY_NO;
}
if (policyType == nsIContentPolicy::TYPE_FONT) {
return IsFontMimeType(type);
}
if (policyType == nsIContentPolicy::TYPE_IMAGE) {
return imgLoader::SupportImageWithMimeType(
NS_ConvertUTF16toUTF8(type), AcceptedMimeTypes::IMAGES_AND_DOCUMENTS);
}
if (policyType == nsIContentPolicy::TYPE_SCRIPT) {
return nsContentUtils::IsJavascriptMIMEType(type);
}
if (policyType == nsIContentPolicy::TYPE_STYLESHEET) {
return type.EqualsASCII("text/css");
}
return false;
}
void HTMLLinkElement::WarnIgnoredPreload(const Document& aDoc, nsIURI& aURI) {
AutoTArray<nsString, 1> params;
{
nsCString uri = nsContentUtils::TruncatedURLForDisplay(&aURI);
AppendUTF8toUTF16(uri, *params.AppendElement());
}
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "DOM"_ns, &aDoc,
nsContentUtils::eDOM_PROPERTIES,
"PreloadIgnoredInvalidAttr", params);
}
bool HTMLLinkElement::IsCSSMimeTypeAttributeForLinkElement(
const Element& aSelf) {
// Processing the type attribute per