mirror of
https://github.com/servo/servo.git
synced 2025-08-02 12:10:29 +01:00
Auto merge of #14646 - canaltinova:origin-clean, r=jdm
Support origins in CSSOM stylesheets <!-- Please describe your changes on the following line: --> I still need to pass the origin clean flag to constructors. `style::stylesheets::Stylesheet` has an origin field but I don't think that's relevant. I can get href in htmllinkelement.rs like this: ```rust let element = self.upcast::<Element>(); let href = element.get_string_attribute(&local_name!("href")); ``` But I'm not sure how to proceed after here. @Manishearth any opinions? --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #14327 (github issue number if applicable). <!-- Either: --> - [X] There are tests for these changes <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14646) <!-- Reviewable:end -->
This commit is contained in:
commit
15c542d3a1
8 changed files with 103 additions and 9 deletions
|
@ -5,7 +5,7 @@
|
|||
use dom::bindings::codegen::Bindings::CSSStyleSheetBinding;
|
||||
use dom::bindings::codegen::Bindings::CSSStyleSheetBinding::CSSStyleSheetMethods;
|
||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
|
||||
use dom::bindings::error::{ErrorResult, Fallible};
|
||||
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||
use dom::bindings::js::{JS, MutNullableJS, Root};
|
||||
use dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||
use dom::bindings::str::DOMString;
|
||||
|
@ -13,6 +13,7 @@ use dom::cssrulelist::{CSSRuleList, RulesSource};
|
|||
use dom::element::Element;
|
||||
use dom::stylesheet::StyleSheet;
|
||||
use dom::window::Window;
|
||||
use std::cell::Cell;
|
||||
use std::sync::Arc;
|
||||
use style::stylesheets::Stylesheet as StyleStyleSheet;
|
||||
|
||||
|
@ -23,6 +24,7 @@ pub struct CSSStyleSheet {
|
|||
rulelist: MutNullableJS<CSSRuleList>,
|
||||
#[ignore_heap_size_of = "Arc"]
|
||||
style_stylesheet: Arc<StyleStyleSheet>,
|
||||
origin_clean: Cell<bool>,
|
||||
}
|
||||
|
||||
impl CSSStyleSheet {
|
||||
|
@ -36,6 +38,7 @@ impl CSSStyleSheet {
|
|||
owner: JS::from_ref(owner),
|
||||
rulelist: MutNullableJS::new(None),
|
||||
style_stylesheet: stylesheet,
|
||||
origin_clean: Cell::new(true),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,25 +74,34 @@ impl CSSStyleSheet {
|
|||
pub fn style_stylesheet(&self) -> &StyleStyleSheet {
|
||||
&self.style_stylesheet
|
||||
}
|
||||
|
||||
pub fn set_origin_clean(&self, origin_clean: bool) {
|
||||
self.origin_clean.set(origin_clean);
|
||||
}
|
||||
}
|
||||
|
||||
impl CSSStyleSheetMethods for CSSStyleSheet {
|
||||
// https://drafts.csswg.org/cssom/#dom-cssstylesheet-cssrules
|
||||
fn CssRules(&self) -> Root<CSSRuleList> {
|
||||
// XXXManishearth check origin clean flag
|
||||
// https://github.com/servo/servo/issues/14327
|
||||
self.rulelist()
|
||||
fn GetCssRules(&self) -> Fallible<Root<CSSRuleList>> {
|
||||
if !self.origin_clean.get() {
|
||||
return Err(Error::Security);
|
||||
}
|
||||
Ok(self.rulelist())
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom/#dom-cssstylesheet-insertrule
|
||||
fn InsertRule(&self, rule: DOMString, index: u32) -> Fallible<u32> {
|
||||
// XXXManishearth check origin clean flag
|
||||
if !self.origin_clean.get() {
|
||||
return Err(Error::Security);
|
||||
}
|
||||
self.rulelist().insert_rule(&rule, index, /* nested */ false)
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom/#dom-cssstylesheet-deleterule
|
||||
fn DeleteRule(&self, index: u32) -> ErrorResult {
|
||||
// XXXManishearth check origin clean flag
|
||||
if !self.origin_clean.get() {
|
||||
return Err(Error::Security);
|
||||
}
|
||||
self.rulelist().remove_rule(index)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -319,6 +319,12 @@ impl StylesheetOwner for HTMLLinkElement {
|
|||
|
||||
None
|
||||
}
|
||||
|
||||
fn set_origin_clean(&self, origin_clean: bool) {
|
||||
if let Some(stylesheet) = self.get_cssom_stylesheet() {
|
||||
stylesheet.set_origin_clean(origin_clean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HTMLLinkElementMethods for HTMLLinkElement {
|
||||
|
|
|
@ -191,6 +191,12 @@ impl StylesheetOwner for HTMLStyleElement {
|
|||
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_origin_clean(&self, origin_clean: bool) {
|
||||
if let Some(stylesheet) = self.get_cssom_stylesheet() {
|
||||
stylesheet.set_origin_clean(origin_clean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
[Exposed=Window]
|
||||
interface CSSStyleSheet : StyleSheet {
|
||||
// readonly attribute CSSRule? ownerRule;
|
||||
[SameObject] readonly attribute CSSRuleList cssRules;
|
||||
[Throws, SameObject] readonly attribute CSSRuleList cssRules;
|
||||
[Throws] unsigned long insertRule(DOMString rule, unsigned long index);
|
||||
[Throws] void deleteRule(unsigned long index);
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@ use hyper::mime::{Mime, TopLevel, SubLevel};
|
|||
use hyper_serde::Serde;
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use net_traits::{FetchResponseListener, FetchMetadata, Metadata, NetworkError, ReferrerPolicy};
|
||||
use net_traits::{FetchResponseListener, FetchMetadata, FilteredMetadata, Metadata, NetworkError, ReferrerPolicy};
|
||||
use net_traits::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType};
|
||||
use network_listener::{NetworkListener, PreInvoke};
|
||||
use parking_lot::RwLock;
|
||||
|
@ -47,6 +47,9 @@ pub trait StylesheetOwner {
|
|||
/// Returns None if there are still pending loads, or whether any load has
|
||||
/// failed since the loads started.
|
||||
fn load_finished(&self, successful: bool) -> Option<bool>;
|
||||
|
||||
/// Sets origin_clean flag.
|
||||
fn set_origin_clean(&self, origin_clean: bool);
|
||||
}
|
||||
|
||||
pub enum StylesheetContextSource {
|
||||
|
@ -81,6 +84,7 @@ pub struct StylesheetContext {
|
|||
data: Vec<u8>,
|
||||
/// The node document for elem when the load was initiated.
|
||||
document: Trusted<Document>,
|
||||
origin_clean: bool,
|
||||
}
|
||||
|
||||
impl PreInvoke for StylesheetContext {}
|
||||
|
@ -92,6 +96,16 @@ impl FetchResponseListener for StylesheetContext {
|
|||
|
||||
fn process_response(&mut self,
|
||||
metadata: Result<FetchMetadata, NetworkError>) {
|
||||
if let Ok(FetchMetadata::Filtered { ref filtered, .. }) = metadata {
|
||||
match *filtered {
|
||||
FilteredMetadata::Opaque |
|
||||
FilteredMetadata::OpaqueRedirect => {
|
||||
self.origin_clean = false;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
self.metadata = metadata.ok().map(|m| {
|
||||
match m {
|
||||
FetchMetadata::Unfiltered(m) => m,
|
||||
|
@ -169,6 +183,7 @@ impl FetchResponseListener for StylesheetContext {
|
|||
|
||||
let owner = elem.upcast::<Element>().as_stylesheet_owner()
|
||||
.expect("Stylesheet not loaded by <style> or <link> element!");
|
||||
owner.set_origin_clean(self.origin_clean);
|
||||
if owner.parser_inserted() {
|
||||
document.decrement_script_blocking_stylesheet_count();
|
||||
}
|
||||
|
@ -206,6 +221,7 @@ impl<'a> StylesheetLoader<'a> {
|
|||
metadata: None,
|
||||
data: vec![],
|
||||
document: Trusted::new(&*document),
|
||||
origin_clean: true,
|
||||
}));
|
||||
|
||||
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||
|
|
|
@ -45867,6 +45867,12 @@
|
|||
"url": "/cssom/overflow-serialization.html"
|
||||
}
|
||||
],
|
||||
"cssom/stylesheet-same-origin.sub.html": [
|
||||
{
|
||||
"path": "cssom/stylesheet-same-origin.sub.html",
|
||||
"url": "/cssom/stylesheet-same-origin.sub.html"
|
||||
}
|
||||
],
|
||||
"html/semantics/embedded-content/the-iframe-element/iframe-synchronously-discard.html": [
|
||||
{
|
||||
"path": "html/semantics/embedded-content/the-iframe-element/iframe-synchronously-discard.html",
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
body {
|
||||
padding: 10px;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSSOM - CSSStylesheet should support origins</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<link id="crossorigin" href="http://www1.{{host}}:{{ports[http][1]}}/stylesheet-same-origin.css" rel="stylesheet">
|
||||
<link id="sameorigin" href="stylesheet-same-origin.css" rel="stylesheet">
|
||||
|
||||
<script>
|
||||
var crossorigin = document.getElementById("crossorigin").sheet;
|
||||
var sameorigin = document.getElementById("sameorigin").sheet;
|
||||
|
||||
test(function() {
|
||||
assert_throws("SecurityError",
|
||||
function () {
|
||||
crossorigin.cssRules;
|
||||
},
|
||||
"Cross origin stylesheet.cssRules should throw SecurityError.");
|
||||
assert_throws("SecurityError",
|
||||
function () {
|
||||
crossorigin.insertRule("#test { margin: 10px; }", 1);
|
||||
},
|
||||
"Cross origin stylesheet.insertRule should throw SecurityError.");
|
||||
|
||||
assert_throws("SecurityError",
|
||||
function () {
|
||||
crossorigin.deleteRule(0);
|
||||
},
|
||||
"Cross origin stylesheet.deleteRule should throw SecurityError.");
|
||||
}, "Origin-clean check in cross-origin CSSOM Stylesheets");
|
||||
|
||||
test(function() {
|
||||
assert_equals(sameorigin.cssRules.length, 1, "Same origin stylesheet.cssRules should be accessible.");
|
||||
sameorigin.insertRule("#test { margin: 10px; }", 1);
|
||||
assert_equals(sameorigin.cssRules.length, 2, "Same origin stylesheet.insertRule should be accessible.");
|
||||
sameorigin.deleteRule(0);
|
||||
assert_equals(sameorigin.cssRules.length, 1, "Same origin stylesheet.deleteRule should be accessible.");
|
||||
}, "Origin-clean check in same-origin CSSOM Stylesheets");
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue