diff --git a/.gitignore b/.gitignore index 630eb63b9bb..5c4c5fef0d3 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,4 @@ support/macos/Brewfile.lock.json # direnv .envrc +tests/wpt/web-platform-tests/ diff --git a/components/fonts/font_context.rs b/components/fonts/font_context.rs index 58c08b29d3e..22f1d73be39 100644 --- a/components/fonts/font_context.rs +++ b/components/fonts/font_context.rs @@ -16,7 +16,11 @@ use fonts_traits::StylesheetWebFontLoadFinishedCallback; use log::{debug, trace}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use malloc_size_of_derive::MallocSizeOf; -use net_traits::request::{Destination, Referrer, RequestBuilder}; +use net_traits::policy_container::PolicyContainer; +use net_traits::request::{ + CredentialsMode, Destination, InsecureRequestsPolicy, Referrer, RequestBuilder, RequestMode, + ServiceWorkersMode, +}; use net_traits::{CoreResourceThread, FetchResponseMsg, ResourceThreads, fetch_async}; use parking_lot::{Mutex, RwLock}; use servo_arc::Arc as ServoArc; @@ -83,6 +87,14 @@ pub struct FontContext { have_removed_web_fonts: AtomicBool, } +#[derive(Clone, Debug)] +pub struct WebFontDocumentContext { + pub policy_container: PolicyContainer, + pub document_url: ServoUrl, + pub has_trustworthy_ancestor_origin: bool, + pub insecure_requests_policy: InsecureRequestsPolicy, +} + impl MallocSizeOf for FontContext { fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { let font_cache_size = self @@ -387,6 +399,7 @@ pub(crate) struct WebFontDownloadState { local_fonts: HashMap>, font_context: Arc, initiator: WebFontLoadInitiator, + document_context: WebFontDocumentContext, } impl WebFontDownloadState { @@ -397,6 +410,7 @@ impl WebFontDownloadState { initiator: WebFontLoadInitiator, sources: Vec, local_fonts: HashMap>, + document_context: WebFontDocumentContext, ) -> WebFontDownloadState { match initiator { WebFontLoadInitiator::Stylesheet(ref stylesheet, _) => { @@ -421,6 +435,7 @@ impl WebFontDownloadState { local_fonts, font_context, initiator, + document_context, } } @@ -487,6 +502,7 @@ pub trait FontContextWebFontMethods { guard: &SharedRwLockReadGuard, device: &Device, finished_callback: StylesheetWebFontLoadFinishedCallback, + document_context: &WebFontDocumentContext, ) -> usize; fn load_web_font_for_script( &self, @@ -494,6 +510,7 @@ pub trait FontContextWebFontMethods { source_list: SourceList, descriptors: CSSFontFaceDescriptors, finished_callback: ScriptWebFontLoadFinishedCallback, + document_context: &WebFontDocumentContext, ); fn add_template_to_font_context( &self, @@ -513,6 +530,7 @@ impl FontContextWebFontMethods for Arc { guard: &SharedRwLockReadGuard, device: &Device, finished_callback: StylesheetWebFontLoadFinishedCallback, + document_context: &WebFontDocumentContext, ) -> usize { let mut number_loading = 0; for rule in stylesheet.effective_rules(device, guard) { @@ -535,6 +553,7 @@ impl FontContextWebFontMethods for Arc { font_face.sources(), css_font_face_descriptors, completion_handler, + document_context, ); } @@ -643,9 +662,16 @@ impl FontContextWebFontMethods for Arc { sources: SourceList, descriptors: CSSFontFaceDescriptors, finished_callback: ScriptWebFontLoadFinishedCallback, + document_context: &WebFontDocumentContext, ) { let completion_handler = WebFontLoadInitiator::Script(finished_callback); - self.start_loading_one_web_font(webview_id, &sources, descriptors, completion_handler); + self.start_loading_one_web_font( + webview_id, + &sources, + descriptors, + completion_handler, + document_context, + ); } fn add_template_to_font_context( @@ -667,6 +693,7 @@ impl FontContext { source_list: &SourceList, css_font_face_descriptors: CSSFontFaceDescriptors, completion_handler: WebFontLoadInitiator, + document_context: &WebFontDocumentContext, ) { let sources: Vec = source_list .0 @@ -708,6 +735,7 @@ impl FontContext { completion_handler, sources, local_fonts, + document_context.clone(), )); } @@ -792,10 +820,23 @@ impl RemoteWebFontDownloader { None => return, }; - // FIXME: This shouldn't use NoReferrer, but the current documents url - let request = - RequestBuilder::new(state.webview_id, url.clone().into(), Referrer::NoReferrer) - .destination(Destination::Font); + let document_context = &state.document_context; + + let document_origin = document_context.document_url.origin(); + + let request = RequestBuilder::new( + state.webview_id, + url.clone().into(), + Referrer::ReferrerUrl(document_context.document_url.clone()), + ) + .destination(Destination::Font) + .origin(document_origin) + .mode(RequestMode::CorsMode) + .credentials_mode(CredentialsMode::CredentialsSameOrigin) + .service_workers_mode(ServiceWorkersMode::All) + .policy_container(document_context.policy_container.clone()) + .insecure_requests_policy(document_context.insecure_requests_policy) + .has_trustworthy_ancestor_origin(document_context.has_trustworthy_ancestor_origin); let core_resource_thread_clone = state.core_resource_thread.clone(); diff --git a/components/layout/layout_impl.rs b/components/layout/layout_impl.rs index 0fbc8395c35..06e5338e46d 100644 --- a/components/layout/layout_impl.rs +++ b/components/layout/layout_impl.rs @@ -20,7 +20,7 @@ use embedder_traits::{Theme, UntrustedNodeAddress, ViewportDetails}; use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect}; use euclid::{Point2D, Scale, Size2D, Vector2D}; use fnv::FnvHashMap; -use fonts::{FontContext, FontContextWebFontMethods}; +use fonts::{FontContext, FontContextWebFontMethods, WebFontDocumentContext}; use fonts_traits::StylesheetWebFontLoadFinishedCallback; use fxhash::FxHashMap; use ipc_channel::ipc::IpcSender; @@ -197,11 +197,16 @@ impl Layout for LayoutThread { self.epoch.get() } - fn load_web_fonts_from_stylesheet(&self, stylesheet: ServoArc) { + fn load_web_fonts_from_stylesheet( + &self, + stylesheet: ServoArc, + document_context: &WebFontDocumentContext, + ) { let guard = stylesheet.shared_lock.read(); self.load_all_web_fonts_from_stylesheet_with_guard( &DocumentStyleSheet(stylesheet.clone()), &guard, + document_context, ); } @@ -213,10 +218,11 @@ impl Layout for LayoutThread { &mut self, stylesheet: ServoArc, before_stylesheet: Option>, + document_context: &WebFontDocumentContext, ) { let guard = stylesheet.shared_lock.read(); let stylesheet = DocumentStyleSheet(stylesheet.clone()); - self.load_all_web_fonts_from_stylesheet_with_guard(&stylesheet, &guard); + self.load_all_web_fonts_from_stylesheet_with_guard(&stylesheet, &guard, document_context); match before_stylesheet { Some(insertion_point) => self.stylist.insert_stylesheet_before( @@ -559,6 +565,7 @@ impl LayoutThread { &self, stylesheet: &DocumentStyleSheet, guard: &SharedRwLockReadGuard, + document_context: &WebFontDocumentContext, ) { if !stylesheet.is_effective_for_device(self.stylist.device(), guard) { return; @@ -578,6 +585,7 @@ impl LayoutThread { guard, self.stylist.device(), Arc::new(web_font_finished_loading_callback) as StylesheetWebFontLoadFinishedCallback, + document_context, ); } @@ -713,7 +721,11 @@ impl LayoutThread { for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets { self.stylist .append_stylesheet(stylesheet.clone(), guards.ua_or_user); - self.load_all_web_fonts_from_stylesheet_with_guard(stylesheet, guards.ua_or_user); + self.load_all_web_fonts_from_stylesheet_with_guard( + stylesheet, + guards.ua_or_user, + &reflow_request.document_context, + ); } if self.stylist.quirks_mode() != QuirksMode::NoQuirks { @@ -724,6 +736,7 @@ impl LayoutThread { self.load_all_web_fonts_from_stylesheet_with_guard( &ua_stylesheets.quirks_mode_stylesheet, guards.ua_or_user, + &reflow_request.document_context, ); } } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 68efa07537c..d66078ff34e 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -35,6 +35,7 @@ use embedder_traits::{ }; use encoding_rs::{Encoding, UTF_8}; use euclid::default::{Point2D, Rect, Size2D}; +use fonts::WebFontDocumentContext; use html5ever::{LocalName, Namespace, QualName, local_name, ns}; use hyper_serde::Serde; use ipc_channel::ipc; @@ -4922,9 +4923,13 @@ impl Document { .cloned(); if self.has_browsing_context() { + // Construct WebFontDocumentContext for font fetching + let document_context = self.window.new_document_context(); + self.window.layout_mut().add_stylesheet( sheet.clone(), insertion_point.as_ref().map(|s| s.sheet.clone()), + &document_context, ); } @@ -4938,10 +4943,14 @@ impl Document { } /// Given a stylesheet, load all web fonts from it in Layout. - pub(crate) fn load_web_fonts_from_stylesheet(&self, stylesheet: Arc) { + pub(crate) fn load_web_fonts_from_stylesheet( + &self, + stylesheet: Arc, + document_context: &WebFontDocumentContext, + ) { self.window .layout() - .load_web_fonts_from_stylesheet(stylesheet); + .load_web_fonts_from_stylesheet(stylesheet, document_context); } /// Remove a stylesheet owned by `owner` from the list of document sheets. diff --git a/components/script/dom/fontface.rs b/components/script/dom/fontface.rs index 89156cca3a8..c0ace7b84fb 100644 --- a/components/script/dom/fontface.rs +++ b/components/script/dom/fontface.rs @@ -540,6 +540,9 @@ impl FontFaceMethods for FontFace { ) .expect("Parsing shouldn't fail as descriptors are valid by construction"); + // Construct a WebFontDocumentContext object for the current document. + let document_context = global.as_window().new_document_context(); + // Step 4. Using the value of font face’s [[Urls]] slot, attempt to load a font as defined // in [CSS-FONTS-3], as if it was the value of a @font-face rule’s src descriptor. // TODO: FontFaceSet is not supported on Workers yet. The `as_window` call below should be @@ -549,6 +552,7 @@ impl FontFaceMethods for FontFace { sources, (&parsed_font_face_rule).into(), finished_callback, + &document_context, ); // Step 3. Set font face’s status attribute to "loading", return font face’s diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index dcaa025c778..436e21189cb 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -38,7 +38,7 @@ use embedder_traits::{ }; use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect}; use euclid::{Point2D, Rect, Scale, Size2D, Vector2D}; -use fonts::FontContext; +use fonts::{FontContext, WebFontDocumentContext}; use ipc_channel::ipc::{self, IpcSender}; use js::conversions::ToJSValConvertible; use js::glue::DumpJSStack; @@ -793,6 +793,15 @@ impl Window { }) ); } + + pub fn new_document_context(&self) -> WebFontDocumentContext { + WebFontDocumentContext { + policy_container: self.global().policy_container(), + document_url: self.global().api_base_url(), + has_trustworthy_ancestor_origin: self.global().has_trustworthy_ancestor_origin(), + insecure_requests_policy: self.global().insecure_requests_policy(), + } + } } // https://html.spec.whatwg.org/multipage/#atob @@ -2194,6 +2203,9 @@ impl Window { let highlighted_dom_node = document.highlighted_dom_node().map(|node| node.to_opaque()); + //Construct a new document context for the reflow. + let document_context = self.new_document_context(); + // Send new document and relevant styles to layout. let reflow = ReflowRequest { reflow_info: Reflow { @@ -2214,6 +2226,7 @@ impl Window { .take_image_animate_set(), theme: self.theme.get(), highlighted_dom_node, + document_context, }; let Some(results) = self.layout.borrow_mut().reflow(reflow) else { diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs index 5efaf78e542..77ade134f58 100644 --- a/components/script/stylesheet_loader.rs +++ b/components/script/stylesheet_loader.rs @@ -244,10 +244,12 @@ impl FetchResponseListener for StylesheetContext { Some(&loader), win.css_error_reporter(), ); + // Construct a new WebFontDocumentContext for the stylesheet + let document_context = win.new_document_context(); // Layout knows about this stylesheet, because Stylo added it to the Stylist, // but Layout doesn't know about any new web fonts that it contains. - document.load_web_fonts_from_stylesheet(stylesheet.clone()); + document.load_web_fonts_from_stylesheet(stylesheet.clone(), &document_context); }, } diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs index e82ee16e24b..cbbbbe58b8f 100644 --- a/components/shared/script_layout/lib.rs +++ b/components/shared/script_layout/lib.rs @@ -23,7 +23,7 @@ use constellation_traits::{LoadData, ScrollState}; use embedder_traits::{Theme, UntrustedNodeAddress, ViewportDetails}; use euclid::default::{Point2D, Rect}; use fnv::FnvHashMap; -use fonts::{FontContext, SystemFontServiceProxy}; +use fonts::{FontContext, SystemFontServiceProxy, WebFontDocumentContext}; use fxhash::FxHashMap; use ipc_channel::ipc::IpcSender; use libc::c_void; @@ -209,7 +209,11 @@ pub trait Layout { /// Load all fonts from the given stylesheet, returning the number of fonts that /// need to be loaded. - fn load_web_fonts_from_stylesheet(&self, stylesheet: ServoArc); + fn load_web_fonts_from_stylesheet( + &self, + stylesheet: ServoArc, + font_context: &WebFontDocumentContext, + ); /// Add a stylesheet to this Layout. This will add it to the Layout's `Stylist` as well as /// loading all web fonts defined in the stylesheet. The second stylesheet is the insertion @@ -218,6 +222,7 @@ pub trait Layout { &mut self, stylesheet: ServoArc, before_stylsheet: Option>, + font_context: &WebFontDocumentContext, ); /// Inform the layout that its ScriptThread is about to exit. @@ -444,6 +449,8 @@ pub struct ReflowRequest { pub theme: Theme, /// The node highlighted by the devtools, if any pub highlighted_dom_node: Option, + /// The current font context. + pub document_context: WebFontDocumentContext, } /// A pending restyle. diff --git a/tests/wpt/meta/referrer-policy/css-integration/font-face/internal-stylesheet.html.ini b/tests/wpt/meta/referrer-policy/css-integration/font-face/internal-stylesheet.html.ini deleted file mode 100644 index 748075fc224..00000000000 --- a/tests/wpt/meta/referrer-policy/css-integration/font-face/internal-stylesheet.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[internal-stylesheet.html] - [Font from internal stylesheet.] - expected: FAIL diff --git a/tests/wpt/mozilla/tests/css/css/ahem.css b/tests/wpt/mozilla/tests/css/css/ahem.css index 51eede74aaa..17e8238b427 100644 --- a/tests/wpt/mozilla/tests/css/css/ahem.css +++ b/tests/wpt/mozilla/tests/css/css/ahem.css @@ -1,3 +1,7 @@ +@font-face { + font-family: Ahem; + src: url('/fonts/Ahem.ttf'); +} body { font-family: 'ahem'; font-size: 100px;