diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 80833ad5cf0..807b7287f8b 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -22,7 +22,6 @@ use constellation_traits::{NavigationHistoryBehavior, ScriptToConstellationMessa use content_security_policy::sandboxing_directive::SandboxingFlagSet; use content_security_policy::{CspList, PolicyDisposition}; use cookie::Cookie; -use cssparser::match_ignore_ascii_case; use data_url::mime::Mime; use devtools_traits::ScriptToDevtoolsControlMsg; use dom_struct::dom_struct; @@ -6003,21 +6002,6 @@ fn update_with_current_instant(marker: &Cell>) { } } -/// -pub(crate) fn determine_policy_for_token(token: &str) -> ReferrerPolicy { - match_ignore_ascii_case! { token, - "never" | "no-referrer" => ReferrerPolicy::NoReferrer, - "no-referrer-when-downgrade" => ReferrerPolicy::NoReferrerWhenDowngrade, - "origin" => ReferrerPolicy::Origin, - "same-origin" => ReferrerPolicy::SameOrigin, - "strict-origin" => ReferrerPolicy::StrictOrigin, - "default" | "strict-origin-when-cross-origin" => ReferrerPolicy::StrictOriginWhenCrossOrigin, - "origin-when-cross-origin" => ReferrerPolicy::OriginWhenCrossOrigin, - "always" | "unsafe-url" => ReferrerPolicy::UnsafeUrl, - _ => ReferrerPolicy::EmptyString, - } -} - /// Specifies the type of focus event that is sent to a pipeline #[derive(Clone, Copy, PartialEq)] pub(crate) enum FocusType { diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 5cb0ddf6e28..8338ec0a3f7 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -106,7 +106,7 @@ use crate::dom::customelementregistry::{ CallbackReaction, CustomElementDefinition, CustomElementReaction, CustomElementState, is_valid_custom_element_name, }; -use crate::dom::document::{Document, LayoutDocumentHelpers, determine_policy_for_token}; +use crate::dom::document::{Document, LayoutDocumentHelpers}; use crate::dom::documentfragment::DocumentFragment; use crate::dom::domrect::DOMRect; use crate::dom::domrectlist::DOMRectList; @@ -5481,7 +5481,7 @@ pub(crate) fn reflect_referrer_policy_attribute(element: &Element) -> DOMString pub(crate) fn referrer_policy_for_element(element: &Element) -> ReferrerPolicy { element .get_attribute(&ns!(), &local_name!("referrerpolicy")) - .map(|attribute| determine_policy_for_token(&attribute.value())) + .map(|attribute| ReferrerPolicy::from(&**attribute.value())) .unwrap_or(element.owner_document().get_referrer_policy()) } diff --git a/components/script/dom/html/htmliframeelement.rs b/components/script/dom/html/htmliframeelement.rs index 57986b2cc42..ac751a11479 100644 --- a/components/script/dom/html/htmliframeelement.rs +++ b/components/script/dom/html/htmliframeelement.rs @@ -35,7 +35,7 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::DomGlobal; use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom}; use crate::dom::bindings::str::{DOMString, USVString}; -use crate::dom::document::{Document, determine_policy_for_token}; +use crate::dom::document::Document; use crate::dom::domtokenlist::DOMTokenList; use crate::dom::element::{ AttributeMutation, Element, LayoutElementHelpers, reflect_referrer_policy_attribute, @@ -336,7 +336,7 @@ impl HTMLIFrameElement { // Note: despite not being explicitly stated in the spec steps, this falls back to // document's referrer policy here because it satisfies the expectations that when unset, // the iframe should inherit the referrer policy of its parent - let referrer_policy = match determine_policy_for_token(referrer_policy_token.str()) { + let referrer_policy = match ReferrerPolicy::from(referrer_policy_token.str()) { ReferrerPolicy::EmptyString => document.get_referrer_policy(), policy => policy, }; diff --git a/components/script/dom/html/htmlimageelement.rs b/components/script/dom/html/htmlimageelement.rs index e395ce33bd0..0036ac1ddd8 100644 --- a/components/script/dom/html/htmlimageelement.rs +++ b/components/script/dom/html/htmlimageelement.rs @@ -59,7 +59,7 @@ use crate::dom::bindings::reflector::DomGlobal; use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom}; use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::csp::{GlobalCspReporting, Violation}; -use crate::dom::document::{Document, determine_policy_for_token}; +use crate::dom::document::Document; use crate::dom::element::{ AttributeMutation, CustomElementCreationMode, Element, ElementCreator, LayoutElementHelpers, cors_setting_for_element, referrer_policy_for_element, reflect_cross_origin_attribute, @@ -1872,15 +1872,10 @@ impl VirtualMethods for HTMLImageElement { // The element's referrerpolicy attribute's state is changed. let referrer_policy_state_changed = match mutation { AttributeMutation::Removed | AttributeMutation::Set(None) => { - let referrer_policy = determine_policy_for_token(&attr.value()); - - referrer_policy != ReferrerPolicy::EmptyString + ReferrerPolicy::from(&**attr.value()) != ReferrerPolicy::EmptyString }, AttributeMutation::Set(Some(old_value)) => { - let new_referrer_policy = determine_policy_for_token(&attr.value()); - let old_referrer_policy = determine_policy_for_token(old_value); - - new_referrer_policy != old_referrer_policy + ReferrerPolicy::from(&**attr.value()) != ReferrerPolicy::from(&**old_value) }, }; diff --git a/components/script/dom/html/htmlmetaelement.rs b/components/script/dom/html/htmlmetaelement.rs index ea5292c3059..621e44417b0 100644 --- a/components/script/dom/html/htmlmetaelement.rs +++ b/components/script/dom/html/htmlmetaelement.rs @@ -8,6 +8,7 @@ use compositing_traits::viewport_description::ViewportDescription; use dom_struct::dom_struct; use html5ever::{LocalName, Prefix, local_name, ns}; use js::rust::HandleObject; +use net_traits::ReferrerPolicy; use servo_config::pref; use style::str::HTML_SPACE_CHARACTERS; @@ -17,7 +18,7 @@ use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; -use crate::dom::document::{Document, determine_policy_for_token}; +use crate::dom::document::Document; use crate::dom::element::{AttributeMutation, Element}; use crate::dom::html::htmlelement::HTMLElement; use crate::dom::html::htmlheadelement::HTMLHeadElement; @@ -97,28 +98,32 @@ impl HTMLMetaElement { // From spec: For historical reasons, unlike other standard metadata names, the processing model for referrer // is not responsive to element removals, and does not use tree order. Only the most-recently-inserted or // most-recently-modified meta element in this state has an effect. - // 1. If element is not in a document tree, then return. + // Step 1. If element is not in a document tree, then return. let meta_node = self.upcast::(); if !meta_node.is_in_a_document_tree() { return; } - // 2. If element does not have a name attribute whose value is an ASCII case-insensitive match for "referrer", - // then return. + // Step 2. If element does not have a name attribute whose value is an ASCII + // case-insensitive match for "referrer", then return. if self.upcast::().get_name() != Some(atom!("referrer")) { return; } - // 3. If element does not have a content attribute, or that attribute's value is the empty string, then return. - let content = self + // Step 3. If element does not have a content attribute, or that attribute's value is the + // empty string, then return. + if let Some(content) = self .upcast::() - .get_attribute(&ns!(), &local_name!("content")); - if let Some(attr) = content { - let attr = attr.value(); - let attr_val = attr.trim(); - if !attr_val.is_empty() { - doc.set_referrer_policy(determine_policy_for_token(attr_val)); - } + .get_attribute(&ns!(), &local_name!("content")) + .filter(|attr| !attr.value().is_empty()) + { + // Step 4. Let value be the value of element's content attribute, converted to ASCII + // lowercase. + // Step 5. If value is one of the values given in the first column of the following + // table, then set value to the value given in the second column: + // Step 6. If value is a referrer policy, then set element's node document's policy + // container's referrer policy to policy. + doc.set_referrer_policy(ReferrerPolicy::from_with_legacy(&content.value())); } } diff --git a/components/script/dom/processingoptions.rs b/components/script/dom/processingoptions.rs index d4a75305ba0..62d2f544b6f 100644 --- a/components/script/dom/processingoptions.rs +++ b/components/script/dom/processingoptions.rs @@ -30,7 +30,7 @@ use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::DomGlobal; use crate::dom::bindings::root::DomRoot; use crate::dom::csp::{GlobalCspReporting, Violation}; -use crate::dom::document::{Document, determine_policy_for_token}; +use crate::dom::document::Document; use crate::dom::element::Element; use crate::dom::globalscope::GlobalScope; use crate::dom::medialist::MediaList; @@ -100,7 +100,7 @@ impl LinkProcessingOptions { // Step 4. If attribs["referrerpolicy"] exists and is an ASCII case-insensitive match for // some referrer policy, then set options's referrer policy to that referrer policy. if let Some(referrer_policy) = link_object.value_for_key_in_link_header("referrerpolicy") { - self.referrer_policy = determine_policy_for_token(referrer_policy); + self.referrer_policy = ReferrerPolicy::from(referrer_policy); } // Step 5. If attribs["nonce"] exists, then set options's nonce to attribs["nonce"]. if let Some(nonce) = link_object.value_for_key_in_link_header("nonce") { diff --git a/components/script/dom/servoparser/prefetch.rs b/components/script/dom/servoparser/prefetch.rs index 77ea2bded9a..b6e16d4f01b 100644 --- a/components/script/dom/servoparser/prefetch.rs +++ b/components/script/dom/servoparser/prefetch.rs @@ -24,7 +24,7 @@ use servo_url::{ImmutableOrigin, ServoUrl}; use crate::dom::bindings::reflector::DomGlobal; use crate::dom::bindings::trace::{CustomTraceable, JSTraceable}; -use crate::dom::document::{Document, determine_policy_for_token}; +use crate::dom::document::Document; use crate::dom::html::htmlscriptelement::script_fetch_request; use crate::dom::processingoptions::determine_cors_settings_for_token; use crate::fetch::create_a_potential_cors_request; @@ -263,7 +263,7 @@ impl PrefetchSink { fn get_referrer_policy(&self, tag: &Tag, name: LocalName) -> ReferrerPolicy { self.get_attr(tag, name) - .map(|attr| determine_policy_for_token(&attr.value)) + .map(|attr| ReferrerPolicy::from(&*attr.value)) .unwrap_or(self.referrer_policy) } diff --git a/components/shared/net/lib.rs b/components/shared/net/lib.rs index f62dd0ab4ce..12d603934b5 100644 --- a/components/shared/net/lib.rs +++ b/components/shared/net/lib.rs @@ -133,6 +133,19 @@ pub enum ReferrerPolicy { } impl ReferrerPolicy { + /// + pub fn from_with_legacy(value: &str) -> Self { + // Step 5. If value is one of the values given in the first column of the following table, + // then set value to the value given in the second column: + match value.to_ascii_lowercase().as_str() { + "never" => ReferrerPolicy::NoReferrer, + "default" => ReferrerPolicy::StrictOriginWhenCrossOrigin, + "always" => ReferrerPolicy::UnsafeUrl, + "origin-when-crossorigin" => ReferrerPolicy::OriginWhenCrossOrigin, + _ => ReferrerPolicy::from(value), + } + } + /// pub fn parse_header_for_response(headers: &Option>) -> Self { // Step 4. Return policy. @@ -145,6 +158,23 @@ impl ReferrerPolicy { } } +impl From<&str> for ReferrerPolicy { + /// + fn from(value: &str) -> Self { + match value.to_ascii_lowercase().as_str() { + "no-referrer" => ReferrerPolicy::NoReferrer, + "no-referrer-when-downgrade" => ReferrerPolicy::NoReferrerWhenDowngrade, + "origin" => ReferrerPolicy::Origin, + "same-origin" => ReferrerPolicy::SameOrigin, + "strict-origin" => ReferrerPolicy::StrictOrigin, + "strict-origin-when-cross-origin" => ReferrerPolicy::StrictOriginWhenCrossOrigin, + "origin-when-cross-origin" => ReferrerPolicy::OriginWhenCrossOrigin, + "unsafe-url" => ReferrerPolicy::UnsafeUrl, + _ => ReferrerPolicy::EmptyString, + } + } +} + impl Display for ReferrerPolicy { fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let string = match self {