diff options
author | Anthony Ramine <n.oxyde@gmail.com> | 2017-10-10 16:14:40 +0200 |
---|---|---|
committer | Anthony Ramine <n.oxyde@gmail.com> | 2017-10-11 13:56:07 +0200 |
commit | 605c679fee29302321878a74b88aa7165519b516 (patch) | |
tree | c52ffde5e21c61b3a5cbdc5aa308247741bb708d | |
parent | 826352ab4cae13f5154d13ab53885d80a8057337 (diff) | |
download | servo-605c679fee29302321878a74b88aa7165519b516.tar.gz servo-605c679fee29302321878a74b88aa7165519b516.zip |
Fix URL attributes
URL attributes should always use AttrValue::Url, and the input should be
resolved against the document's base URL at setting time always.
-rw-r--r-- | components/script/dom/element.rs | 33 | ||||
-rw-r--r-- | components/script/dom/htmlbaseelement.rs | 32 | ||||
-rw-r--r-- | components/script/dom/htmlbodyelement.rs | 10 | ||||
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 9 | ||||
-rw-r--r-- | components/script/dom/htmlimageelement.rs | 4 | ||||
-rwxr-xr-x | components/script/dom/htmlinputelement.rs | 1 | ||||
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 3 | ||||
-rw-r--r-- | components/script/dom/htmlmediaelement.rs | 11 | ||||
-rw-r--r-- | components/script/dom/htmlscriptelement.rs | 11 | ||||
-rw-r--r-- | components/script/dom/macros.rs | 5 | ||||
-rw-r--r-- | tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_invalid.html.ini | 5 |
11 files changed, 76 insertions, 48 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 438d01f4d0a..c16eb7f0699 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -1302,21 +1302,30 @@ impl Element { pub fn get_url_attribute(&self, local_name: &LocalName) -> DOMString { assert!(*local_name == local_name.to_ascii_lowercase()); - if !self.has_attribute(local_name) { - return DOMString::new(); - } - let url = self.get_string_attribute(local_name); - let doc = document_from_node(self); - let base = doc.base_url(); - // https://html.spec.whatwg.org/multipage/#reflect - // XXXManishearth this doesn't handle `javascript:` urls properly - match base.join(&url) { - Ok(parsed) => DOMString::from(parsed.into_string()), - Err(_) => DOMString::from(""), + let attr = match self.get_attribute(&ns!(), local_name) { + Some(attr) => attr, + None => return DOMString::new(), + }; + let value = attr.value(); + match *value { + AttrValue::Url(ref value, _) => { + // XXXManishearth this doesn't handle `javascript:` urls properly + let base = document_from_node(self).base_url(); + let value = base.join(value) + .map(|parsed| parsed.into_string()) + .unwrap_or_else(|_| value.clone()); + DOMString::from(value) + }, + _ => panic!("attribute value should be AttrValue::Url(..)"), } } + pub fn set_url_attribute(&self, local_name: &LocalName, value: DOMString) { - self.set_string_attribute(local_name, value); + let value = AttrValue::from_url( + document_from_node(self).base_url(), + value.into(), + ); + self.set_attribute(local_name, value); } pub fn get_string_attribute(&self, local_name: &LocalName) -> DOMString { diff --git a/components/script/dom/htmlbaseelement.rs b/components/script/dom/htmlbaseelement.rs index ada9539833a..c1c3c07aaf0 100644 --- a/components/script/dom/htmlbaseelement.rs +++ b/components/script/dom/htmlbaseelement.rs @@ -16,7 +16,6 @@ use dom::virtualmethods::VirtualMethods; use dom_struct::dom_struct; use html5ever::{LocalName, Prefix}; use servo_url::ServoUrl; -use style::attr::AttrValue; #[dom_struct] pub struct HTMLBaseElement { @@ -67,28 +66,31 @@ impl HTMLBaseElement { impl HTMLBaseElementMethods for HTMLBaseElement { // https://html.spec.whatwg.org/multipage/#dom-base-href fn Href(&self) -> DOMString { - let document = document_from_node(self); - // Step 1. - if !self.upcast::<Element>().has_attribute(&local_name!("href")) { - return DOMString::from(document.base_url().as_str()); - } + let document = document_from_node(self); // Step 2. - let fallback_base_url = document.fallback_base_url(); + let attr = self.upcast::<Element>().get_attribute(&ns!(), &local_name!("href")); + let value = attr.as_ref().map(|attr| attr.value()); + let url = value.as_ref().map_or("", |value| &**value); // Step 3. - let url = self.upcast::<Element>().get_url_attribute(&local_name!("href")); - - // Step 4. - let url_record = fallback_base_url.join(&*url); - - // Step 5, 6. - DOMString::from(url_record.as_ref().map(|url| url.as_str()).unwrap_or("")) + let url_record = document.fallback_base_url().join(url); + + match url_record { + Err(_) => { + // Step 4. + url.into() + } + Ok(url_record) => { + // Step 5. + url_record.into_string().into() + }, + } } // https://html.spec.whatwg.org/multipage/#dom-base-href - make_url_setter!(SetHref, "href"); + make_setter!(SetHref, "href"); } impl VirtualMethods for HTMLBaseElement { diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs index 53fb0637b0d..580dc0a8808 100644 --- a/components/script/dom/htmlbodyelement.rs +++ b/components/script/dom/htmlbodyelement.rs @@ -4,6 +4,7 @@ use cssparser::RGBA; use dom::attr::Attr; +use dom::bindings::codegen::Bindings::AttrBinding::AttrBinding::AttrMethods; use dom::bindings::codegen::Bindings::HTMLBodyElementBinding::{self, HTMLBodyElementMethods}; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::inheritance::Castable; @@ -73,7 +74,12 @@ impl HTMLBodyElementMethods for HTMLBodyElement { make_legacy_color_setter!(SetText, "text"); // https://html.spec.whatwg.org/multipage/#dom-body-background - make_getter!(Background, "background"); + fn Background(&self) -> DOMString { + self.upcast::<Element>() + .get_attribute(&ns!(), &local_name!("background")) + .map(|attr| attr.Value()) + .unwrap_or_default() + } // https://html.spec.whatwg.org/multipage/#dom-body-background make_url_setter!(SetBackground, "background"); @@ -154,7 +160,7 @@ impl VirtualMethods for HTMLBodyElement { local_name!("bgcolor") | local_name!("text") => AttrValue::from_legacy_color(value.into()), local_name!("background") => { - AttrValue::from_url(document_from_node(self).url(), value.into()) + AttrValue::from_url(document_from_node(self).base_url(), value.into()) }, _ => self.super_type().unwrap().parse_plain_attribute(name, value), } diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 245d61a8d63..2346358aabd 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -568,14 +568,10 @@ pub fn Navigate(iframe: &HTMLIFrameElement, direction: TraversalDirection) -> Er impl HTMLIFrameElementMethods for HTMLIFrameElement { // https://html.spec.whatwg.org/multipage/#dom-iframe-src - fn Src(&self) -> DOMString { - self.upcast::<Element>().get_string_attribute(&local_name!("src")) - } + make_url_getter!(Src, "src"); // https://html.spec.whatwg.org/multipage/#dom-iframe-src - fn SetSrc(&self, src: DOMString) { - self.upcast::<Element>().set_url_attribute(&local_name!("src"), src) - } + make_url_setter!(SetSrc, "src"); // https://html.spec.whatwg.org/multipage/#dom-iframe-sandbox fn Sandbox(&self) -> DomRoot<DOMTokenList> { @@ -765,6 +761,7 @@ impl VirtualMethods for HTMLIFrameElement { fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { match name { + &local_name!("src") => AttrValue::from_url(document_from_node(self).base_url(), value.into()), &local_name!("sandbox") => AttrValue::from_serialized_tokenlist(value.into()), &local_name!("width") => AttrValue::from_dimension(value.into()), &local_name!("height") => AttrValue::from_dimension(value.into()), diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 027221a88f0..a9b2f01e283 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -824,8 +824,9 @@ impl HTMLImageElementMethods for HTMLImageElement { // https://html.spec.whatwg.org/multipage/#dom-img-src make_url_getter!(Src, "src"); + // https://html.spec.whatwg.org/multipage/#dom-img-src - make_setter!(SetSrc, "src"); + make_url_setter!(SetSrc, "src"); // https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin fn GetCrossOrigin(&self) -> Option<DOMString> { @@ -980,6 +981,7 @@ impl VirtualMethods for HTMLImageElement { fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { match name { + &local_name!("src") => AttrValue::from_url(document_from_node(self).base_url(), value.into()), &local_name!("name") => AttrValue::from_atomic(value.into()), &local_name!("width") | &local_name!("height") => AttrValue::from_dimension(value.into()), &local_name!("hspace") | &local_name!("vspace") => AttrValue::from_u32(value.into(), 0), diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index ce76eb8ced5..3a16551d4c3 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -1056,6 +1056,7 @@ impl VirtualMethods for HTMLInputElement { fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { match name { + &local_name!("src") => AttrValue::from_url(document_from_node(self).base_url(), value.into()), &local_name!("accept") => AttrValue::from_comma_separated_tokenlist(value.into()), &local_name!("name") => AttrValue::from_atomic(value.into()), &local_name!("size") => AttrValue::from_limited_u32(value.into(), DEFAULT_INPUT_SIZE), diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 320b425331b..9bf1ba73991 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -208,6 +208,7 @@ impl VirtualMethods for HTMLLinkElement { fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { match name { + &local_name!("href") => AttrValue::from_url(document_from_node(self).base_url(), value.into()), &local_name!("rel") => AttrValue::from_serialized_tokenlist(value.into()), _ => self.super_type().unwrap().parse_plain_attribute(name, value), } @@ -373,7 +374,7 @@ impl HTMLLinkElementMethods for HTMLLinkElement { make_url_getter!(Href, "href"); // https://html.spec.whatwg.org/multipage/#dom-link-href - make_setter!(SetHref, "href"); + make_url_setter!(SetHref, "href"); // https://html.spec.whatwg.org/multipage/#dom-link-rel make_getter!(Rel, "rel"); diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 739025544e7..965dd83cee4 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -46,6 +46,7 @@ use std::collections::VecDeque; use std::mem; use std::rc::Rc; use std::sync::{Arc, Mutex}; +use style::attr::AttrValue; use task_source::TaskSource; use time::{self, Timespec, Duration}; @@ -837,8 +838,9 @@ impl HTMLMediaElementMethods for HTMLMediaElement { // https://html.spec.whatwg.org/multipage/#dom-media-src make_url_getter!(Src, "src"); + // https://html.spec.whatwg.org/multipage/#dom-media-src - make_setter!(SetSrc, "src"); + make_url_setter!(SetSrc, "src"); // https://html.spec.whatwg.org/multipage/#dom-media-srcobject fn GetSrcObject(&self) -> Option<DomRoot<Blob>> { @@ -913,6 +915,13 @@ impl VirtualMethods for HTMLMediaElement { Some(self.upcast::<HTMLElement>() as &VirtualMethods) } + fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { + match name { + &local_name!("src") => AttrValue::from_url(document_from_node(self).base_url(), value.into()), + _ => self.super_type().unwrap().parse_plain_attribute(name, value), + } + } + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { self.super_type().unwrap().attribute_mutated(attr, mutation); diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 7cdebdbcba4..5ad655ce659 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -42,6 +42,7 @@ use std::io::{Read, Write}; use std::path::PathBuf; use std::process::{Command, Stdio}; use std::sync::{Arc, Mutex}; +use style::attr::AttrValue; use style::str::{HTML_SPACE_CHARACTERS, StaticStringVec}; use uuid::Uuid; @@ -653,6 +654,13 @@ impl VirtualMethods for HTMLScriptElement { Some(self.upcast::<HTMLElement>() as &VirtualMethods) } + fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { + match name { + &local_name!("src") => AttrValue::from_url(document_from_node(self).base_url(), value.into()), + _ => self.super_type().unwrap().parse_plain_attribute(name, value), + } + } + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { self.super_type().unwrap().attribute_mutated(attr, mutation); match *attr.local_name() { @@ -702,8 +710,9 @@ impl VirtualMethods for HTMLScriptElement { impl HTMLScriptElementMethods for HTMLScriptElement { // https://html.spec.whatwg.org/multipage/#dom-script-src make_url_getter!(Src, "src"); + // https://html.spec.whatwg.org/multipage/#dom-script-src - make_setter!(SetSrc, "src"); + make_url_setter!(SetSrc, "src"); // https://html.spec.whatwg.org/multipage/#dom-script-type make_getter!(Type, "type"); diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index 9029a2b694a..68aa8351bb9 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -194,11 +194,8 @@ macro_rules! make_url_setter( fn $attr(&self, value: DOMString) { use dom::bindings::inheritance::Castable; use dom::element::Element; - use dom::node::document_from_node; - let value = AttrValue::from_url(document_from_node(self).url(), - value.into()); let element = self.upcast::<Element>(); - element.set_attribute(&local_name!($htmlname), value); + element.set_url_attribute(&local_name!($htmlname), value); } ); ); diff --git a/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_invalid.html.ini b/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_invalid.html.ini deleted file mode 100644 index 1324d90c64b..00000000000 --- a/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_invalid.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[base_href_invalid.html] - type: testharness - [base element with unparseable href should have .href getter return attr value] - expected: FAIL - |