tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit a643ccf3b03b9c6925c17afcd601e85a07866d19
parent c226407064adf2a042558dde3333be5a6d5dbb80
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date:   Fri, 24 Oct 2025 20:28:08 +0000

Bug 1994008 - Pass the right base URI to cached inline sheets. r=firefox-style-system-reviewers,layout-reviewers,dshin

With the dependent bugs closed, this fix is trivial.

Differential Revision: https://phabricator.services.mozilla.com/D269944

Diffstat:
Mlayout/style/Loader.cpp | 10+++++++---
Mlayout/style/StyleSheet.cpp | 4+++-
Mservo/components/style/stylesheets/stylesheet.rs | 18++++++++++++------
Mservo/ports/geckolib/glue.rs | 7+++++--
Atesting/web-platform/tests/css/css-values/inline-cache-base-uri-cssom-ref.html | 4++++
Atesting/web-platform/tests/css/css-values/inline-cache-base-uri-cssom.html | 14++++++++++++++
6 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp @@ -1822,14 +1822,18 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadInlineStyle( if (!isSheetFromCache) { sheet = MakeRefPtr<StyleSheet>(eAuthorSheetFeatures, aInfo.mCORSMode, SRIMetadata{}); - nsIReferrerInfo* referrerInfo = - aInfo.mContent->OwnerDoc()->ReferrerInfoForInternalCSSAndSVGResources(); - sheet->SetURIs(nullptr, baseURI, referrerInfo, sheetPrincipal); // If an extension creates an inline stylesheet, we don't want to consider // it same-origin with the page. // FIXME(emilio): That's rather odd. sheet->SetOriginClean(LoaderPrincipal()->Subsumes(sheetPrincipal)); } + // We allow sharing inline sheets with e.g. different base URIs, iff there's + // no dependency on that base URI. However, we still need to keep track of the + // right URIs in case the sheet is then mutated. EnsureUniqueInner will make + // sure the StylesheetContents get fixed up. + nsIReferrerInfo* referrerInfo = + aInfo.mContent->OwnerDoc()->ReferrerInfoForInternalCSSAndSVGResources(); + sheet->SetURIs(nullptr, baseURI, referrerInfo, sheetPrincipal); auto matched = PrepareSheet(*sheet, aInfo.mTitle, aInfo.mMedia, nullptr, isAlternate, aInfo.mIsExplicitlyEnabled); diff --git a/layout/style/StyleSheet.cpp b/layout/style/StyleSheet.cpp @@ -352,7 +352,9 @@ StyleSheetInfo::StyleSheetInfo(StyleSheetInfo& aCopy, StyleSheet* aPrimarySheet) // We don't rebuild the child because we're making a copy without // children. mSourceMapURL(aCopy.mSourceMapURL), - mContents(Servo_StyleSheet_Clone(aCopy.mContents.get()).Consume()) + mContents(Servo_StyleSheet_Clone(aCopy.mContents.get(), + aPrimarySheet->URLData()) + .Consume()) #ifdef DEBUG , mPrincipalSet(aCopy.mPrincipalSet) diff --git a/servo/components/style/stylesheets/stylesheet.rs b/servo/components/style/stylesheets/stylesheet.rs @@ -184,27 +184,33 @@ impl StylesheetContents { ) -> EffectiveRulesIterator<'a, 'b> { self.iter_rules::<EffectiveRules>(device, guard) } -} -impl DeepCloneWithLock for StylesheetContents { - fn deep_clone_with_lock(&self, lock: &SharedRwLock, guard: &SharedRwLockReadGuard) -> Self { + /// Perform a deep clone, of this stylesheet, with an explicit URL data if needed. + pub fn deep_clone( + &self, + lock: &SharedRwLock, + url_data: Option<&UrlExtraData>, + guard: &SharedRwLockReadGuard, + ) -> Arc<Self> { // Make a deep clone of the rules, using the new lock. let rules = self .rules .read_with(guard) .deep_clone_with_lock(lock, guard); - Self { + let url_data = url_data.cloned().unwrap_or_else(|| self.url_data.clone()); + + Arc::new(Self { rules: Arc::new(lock.wrap(rules)), quirks_mode: self.quirks_mode, origin: self.origin, - url_data: self.url_data.clone(), + url_data, namespaces: self.namespaces.clone(), source_map_url: self.source_map_url.clone(), source_url: self.source_url.clone(), use_counters: self.use_counters.clone(), _forbid_construction: (), - } + }) } } diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs @@ -2064,11 +2064,14 @@ pub extern "C" fn Servo_StyleSheet_GetRules(sheet: &StylesheetContents) -> Stron #[no_mangle] pub extern "C" fn Servo_StyleSheet_Clone( contents: &StylesheetContents, + data: *mut URLExtraData, ) -> Strong<StylesheetContents> { - use style::shared_lock::DeepCloneWithLock; let global_style_data = &*GLOBAL_STYLE_DATA; let guard = global_style_data.shared_lock.read(); - Arc::new(contents.deep_clone_with_lock(&global_style_data.shared_lock, &guard)).into() + let url_data = unsafe { UrlExtraData::from_ptr_ref(&data) }; + contents + .deep_clone(&global_style_data.shared_lock, Some(url_data), &guard) + .into() } #[no_mangle] diff --git a/testing/web-platform/tests/css/css-values/inline-cache-base-uri-cssom-ref.html b/testing/web-platform/tests/css/css-values/inline-cache-base-uri-cssom-ref.html @@ -0,0 +1,4 @@ +<!doctype html> +<style> + :root { background-color: lime } +</style> diff --git a/testing/web-platform/tests/css/css-values/inline-cache-base-uri-cssom.html b/testing/web-platform/tests/css/css-values/inline-cache-base-uri-cssom.html @@ -0,0 +1,14 @@ +<!doctype html> +<title>Relative URI in potentially-cached stylesheet</title> +<link rel="help" href="https://drafts.csswg.org/css-values-4/#relative-urls"> +<link rel="match" href="inline-cache-base-uri-cssom-ref.html"> +<style> + :root { background-color: red; } +</style> +<base href="/images/"> +<style> + :root { background-color: red; } +</style> +<script> +document.styleSheets[1].insertRule(`:root { background-image: url(green.png) }`); +</script>