diff options
Diffstat (limited to 'components')
32 files changed, 312 insertions, 59 deletions
diff --git a/components/config/prefs.rs b/components/config/prefs.rs index a1e8f96b906..4196a8cce2c 100644 --- a/components/config/prefs.rs +++ b/components/config/prefs.rs @@ -459,6 +459,11 @@ mod gen { } }, network: { + enforce_tls: { + enabled: bool, + localhost: bool, + onion: bool, + }, http_cache: { #[serde(rename = "network.http-cache.disabled")] disabled: bool, diff --git a/components/malloc_size_of/Cargo.toml b/components/malloc_size_of/Cargo.toml index 1b4872e67f1..c33175ad026 100644 --- a/components/malloc_size_of/Cargo.toml +++ b/components/malloc_size_of/Cargo.toml @@ -22,10 +22,12 @@ servo = [ "webrender_api", "xml5ever", "content-security-policy", - "uuid" + "uuid", + "accountable-refcell", ] [dependencies] +accountable-refcell = { version = "0.2.0", optional = true } app_units = "0.7" content-security-policy = {version = "0.3.0", features = ["serde"], optional = true} crossbeam-channel = { version = "0.3", optional = true } diff --git a/components/malloc_size_of/lib.rs b/components/malloc_size_of/lib.rs index 8593ccc3622..62673268ad9 100644 --- a/components/malloc_size_of/lib.rs +++ b/components/malloc_size_of/lib.rs @@ -46,6 +46,7 @@ //! Note: WebRender has a reduced fork of this crate, so that we can avoid //! publishing this crate on crates.io. +extern crate accountable_refcell; extern crate app_units; #[cfg(feature = "servo")] extern crate content_security_policy; @@ -970,3 +971,10 @@ impl<T: MallocSizeOf> DerefMut for Measurable<T> { &mut self.0 } } + +#[cfg(feature = "servo")] +impl<T: MallocSizeOf> MallocSizeOf for accountable_refcell::RefCell<T> { + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + self.borrow().size_of(ops) + } +} diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index 9fca70fae0b..101cf467444 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -265,7 +265,7 @@ pub fn main_fetch( .hsts_list .read() .unwrap() - .switch_known_hsts_host_domain_url_to_https(request.current_url_mut()); + .apply_hsts_rules(request.current_url_mut()); // Step 11. // Not applicable: see fetch_async. diff --git a/components/net/hsts.rs b/components/net/hsts.rs index 01b9cf71eb6..dfaab4f2b60 100644 --- a/components/net/hsts.rs +++ b/components/net/hsts.rs @@ -3,9 +3,12 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use embedder_traits::resources::{self, Resource}; +use headers::{Header, HeaderMapExt, HeaderName, HeaderValue}; +use http::HeaderMap; use net_traits::pub_domains::reg_suffix; use net_traits::IncludeSubdomains; -use servo_url::ServoUrl; +use servo_config::pref; +use servo_url::{Host, ServoUrl}; use std::collections::HashMap; use std::net::{Ipv4Addr, Ipv6Addr}; @@ -138,16 +141,156 @@ impl HstsList { } } - /// Step 10 of https://fetch.spec.whatwg.org/#concept-main-fetch. - pub fn switch_known_hsts_host_domain_url_to_https(&self, url: &mut ServoUrl) { - if url.scheme() != "http" { + /// Step 2.9 of https://fetch.spec.whatwg.org/#concept-main-fetch. + pub fn apply_hsts_rules(&self, url: &mut ServoUrl) { + if url.scheme() != "http" && url.scheme() != "ws" { return; } - if url - .domain() - .map_or(false, |domain| self.is_host_secure(domain)) - { - url.as_mut_url().set_scheme("https").unwrap(); + + let upgrade_scheme = if pref!(network.enforce_tls.enabled) { + if (!pref!(network.enforce_tls.localhost) && + match url.host() { + Some(Host::Domain(domain)) => { + domain.ends_with(".localhost") || domain == "localhost" + }, + Some(Host::Ipv4(ipv4)) => ipv4.is_loopback(), + Some(Host::Ipv6(ipv6)) => ipv6.is_loopback(), + _ => false, + }) || + (!pref!(network.enforce_tls.onion) && + url.domain() + .map_or(false, |domain| domain.ends_with(".onion"))) + { + url.domain() + .map_or(false, |domain| self.is_host_secure(domain)) + } else { + true + } + } else { + url.domain() + .map_or(false, |domain| self.is_host_secure(domain)) + }; + + if upgrade_scheme { + let upgraded_scheme = match url.scheme() { + "ws" => "wss", + _ => "https", + }; + url.as_mut_url().set_scheme(upgraded_scheme).unwrap(); + } + } + + pub fn update_hsts_list_from_response(&mut self, url: &ServoUrl, headers: &HeaderMap) { + if url.scheme() != "https" && url.scheme() != "wss" { + return; + } + + if let Some(header) = headers.typed_get::<StrictTransportSecurity>() { + if let Some(host) = url.domain() { + let include_subdomains = if header.include_subdomains { + IncludeSubdomains::Included + } else { + IncludeSubdomains::NotIncluded + }; + + if let Some(entry) = + HstsEntry::new(host.to_owned(), include_subdomains, Some(header.max_age)) + { + info!("adding host {} to the strict transport security list", host); + info!("- max-age {}", header.max_age); + if header.include_subdomains { + info!("- includeSubdomains"); + } + + self.push(entry); + } + } } } } + +// TODO: Remove this with the next update of the `headers` crate +// https://github.com/hyperium/headers/issues/61 +#[derive(Clone, Debug, PartialEq)] +struct StrictTransportSecurity { + include_subdomains: bool, + max_age: u64, +} + +enum Directive { + MaxAge(u64), + IncludeSubdomains, + Unknown, +} + +// taken from https://github.com/hyperium/headers +impl Header for StrictTransportSecurity { + fn name() -> &'static HeaderName { + &http::header::STRICT_TRANSPORT_SECURITY + } + + fn decode<'i, I: Iterator<Item = &'i HeaderValue>>( + values: &mut I, + ) -> Result<Self, headers::Error> { + values + .just_one() + .and_then(|v| v.to_str().ok()) + .map(|s| { + s.split(';') + .map(str::trim) + .map(|sub| { + if sub.eq_ignore_ascii_case("includeSubDomains") { + Some(Directive::IncludeSubdomains) + } else { + let mut sub = sub.splitn(2, '='); + match (sub.next(), sub.next()) { + (Some(left), Some(right)) + if left.trim().eq_ignore_ascii_case("max-age") => + { + right + .trim() + .trim_matches('"') + .parse() + .ok() + .map(Directive::MaxAge) + }, + _ => Some(Directive::Unknown), + } + } + }) + .fold(Some((None, None)), |res, dir| match (res, dir) { + (Some((None, sub)), Some(Directive::MaxAge(age))) => Some((Some(age), sub)), + (Some((age, None)), Some(Directive::IncludeSubdomains)) => { + Some((age, Some(()))) + }, + (Some((Some(_), _)), Some(Directive::MaxAge(_))) | + (Some((_, Some(_))), Some(Directive::IncludeSubdomains)) | + (_, None) => None, + (res, _) => res, + }) + .and_then(|res| match res { + (Some(age), sub) => Some(StrictTransportSecurity { + max_age: age, + include_subdomains: sub.is_some(), + }), + _ => None, + }) + .ok_or_else(headers::Error::invalid) + }) + .unwrap_or_else(|| Err(headers::Error::invalid())) + } + + fn encode<E: Extend<HeaderValue>>(&self, _values: &mut E) {} +} + +trait IterExt: Iterator { + fn just_one(&mut self) -> Option<Self::Item> { + let one = self.next()?; + match self.next() { + Some(_) => None, + None => Some(one), + } + } +} + +impl<T: Iterator> IterExt for T {} diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 7868556adfe..e48174443a2 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -1381,7 +1381,7 @@ fn http_network_fetch( .map(|_| uuid::Uuid::new_v4().to_simple().to_string()); if log_enabled!(log::Level::Info) { - info!("request for {} ({:?})", url, request.method); + info!("{:?} request for {}", request.method, url); for header in request.headers.iter() { info!(" - {:?}", header); } @@ -1563,9 +1563,10 @@ fn http_network_fetch( // Substep 2 - // TODO Determine if response was retrieved over HTTPS - // TODO Servo needs to decide what ciphers are to be treated as "deprecated" - response.https_state = HttpsState::None; + response.https_state = match url.scheme() { + "https" => HttpsState::Modern, + _ => HttpsState::None, + }; // TODO Read request @@ -1592,6 +1593,12 @@ fn http_network_fetch( if credentials_flag { set_cookies_from_headers(&url, &response.headers, &context.state.cookie_jar); } + context + .state + .hsts_list + .write() + .unwrap() + .update_hsts_list_from_response(&url, &response.headers); // TODO these steps // Step 16 diff --git a/components/net/tests/fetch.rs b/components/net/tests/fetch.rs index f33321cc438..d26343684f0 100644 --- a/components/net/tests/fetch.rs +++ b/components/net/tests/fetch.rs @@ -12,6 +12,7 @@ use crate::{ use crossbeam_channel::{unbounded, Sender}; use devtools_traits::HttpRequest as DevtoolsHttpRequest; use devtools_traits::HttpResponse as DevtoolsHttpResponse; +use headers::StrictTransportSecurity; use headers::{AccessControlAllowCredentials, AccessControlAllowHeaders, AccessControlAllowOrigin}; use headers::{AccessControlAllowMethods, AccessControlMaxAge, HeaderMapExt}; use headers::{CacheControl, ContentLength, ContentType, Expires, LastModified, Pragma, UserAgent}; @@ -27,7 +28,9 @@ use net::fetch::methods::{self, CancellationListener, FetchContext}; use net::filemanager_thread::FileManager; use net::hsts::HstsEntry; use net::test::HttpState; -use net_traits::request::{Destination, Origin, RedirectMode, Referrer, Request, RequestMode}; +use net_traits::request::{ + Destination, Origin, RedirectMode, Referrer, Request, RequestBuilder, RequestMode, +}; use net_traits::response::{CacheState, Response, ResponseBody, ResponseType}; use net_traits::{ FetchTaskTarget, IncludeSubdomains, NetworkError, ReferrerPolicy, ResourceFetchTiming, @@ -681,6 +684,66 @@ fn test_fetch_with_hsts() { } #[test] +fn test_load_adds_host_to_hsts_list_when_url_is_https() { + let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| { + response + .headers_mut() + .typed_insert(StrictTransportSecurity::excluding_subdomains( + Duration::from_secs(31536000), + )); + *response.body_mut() = b"Yay!".to_vec().into(); + }; + let cert_path = Path::new("../../resources/self_signed_certificate_for_testing.crt") + .canonicalize() + .unwrap(); + let key_path = Path::new("../../resources/privatekey_for_testing.key") + .canonicalize() + .unwrap(); + let (server, mut url) = make_ssl_server(handler, cert_path.clone(), key_path.clone()); + url.as_mut_url().set_scheme("https").unwrap(); + + let certs = fs::read_to_string(cert_path).expect("Couldn't find certificate file"); + let tls_config = create_tls_config(&certs, ALPN_H2_H1); + + let mut context = FetchContext { + state: Arc::new(HttpState::new(tls_config)), + user_agent: DEFAULT_USER_AGENT.into(), + devtools_chan: None, + filemanager: FileManager::new(create_embedder_proxy()), + cancellation_listener: Arc::new(Mutex::new(CancellationListener::new(None))), + timing: ServoArc::new(Mutex::new(ResourceFetchTiming::new( + ResourceTimingType::Navigation, + ))), + }; + + let mut request = RequestBuilder::new(url.clone()) + .method(Method::GET) + .body(None) + .destination(Destination::Document) + .origin(url.clone().origin()) + .pipeline_id(Some(TEST_PIPELINE_ID)) + .build(); + + let response = fetch_with_context(&mut request, &mut context); + + let _ = server.close(); + + assert!(response + .internal_response + .unwrap() + .status + .unwrap() + .0 + .is_success()); + assert!(context + .state + .hsts_list + .read() + .unwrap() + .is_host_secure(url.host_str().unwrap())); +} + +#[test] fn test_fetch_with_sri_network_error() { static MESSAGE: &'static [u8] = b"alert('Hello, Network Error');"; let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| { diff --git a/components/net/tests/http_loader.rs b/components/net/tests/http_loader.rs index fc4fd7153ed..7c9bc9ee470 100644 --- a/components/net/tests/http_loader.rs +++ b/components/net/tests/http_loader.rs @@ -543,7 +543,7 @@ fn test_load_doesnt_send_request_body_on_any_redirect() { } #[test] -fn test_load_doesnt_add_host_to_sts_list_when_url_is_http_even_if_sts_headers_are_present() { +fn test_load_doesnt_add_host_to_hsts_list_when_url_is_http_even_if_hsts_headers_are_present() { let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| { response .headers_mut() diff --git a/components/net/websocket_loader.rs b/components/net/websocket_loader.rs index 3fd213e399b..76dccfc2270 100644 --- a/components/net/websocket_loader.rs +++ b/components/net/websocket_loader.rs @@ -100,6 +100,12 @@ impl<'a> Handler for Client<'a> { } } + self.http_state + .hsts_list + .write() + .unwrap() + .update_hsts_list_from_response(self.resource_url, &headers); + let _ = self .event_sender .send(WebSocketNetworkEvent::ConnectionEstablished { @@ -185,6 +191,7 @@ pub fn init( thread::Builder::new() .name(format!("WebSocket connection to {}", req_builder.url)) .spawn(move || { + let mut req_builder = req_builder; let protocols = match req_builder.mode { RequestMode::WebSocket { protocols } => protocols, _ => panic!( @@ -192,6 +199,16 @@ pub fn init( ), }; + // https://fetch.spec.whatwg.org/#websocket-opening-handshake + // By standard, we should work with an http(s):// URL (req_url), + // but as ws-rs expects to be called with a ws(s):// URL (net_url) + // we upgrade ws to wss, so we don't have to convert http(s) back to ws(s). + http_state + .hsts_list + .read() + .unwrap() + .apply_hsts_rules(&mut req_builder.url); + let scheme = req_builder.url.scheme(); let mut req_url = req_builder.url.clone(); if scheme == "ws" { diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 3889402a346..8a200bc375f 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -19,6 +19,7 @@ unrooted_must_root_lint = ["script_plugins/unrooted_must_root_lint"] default = ["unrooted_must_root_lint"] webgl_backtrace = ["backtrace", "canvas_traits/webgl_backtrace"] js_backtrace = ["backtrace"] +refcell_backtrace = ["accountable-refcell"] uwp = ["js/uwp"] vslatestinstalled = ["js/vslatestinstalled"] @@ -31,6 +32,7 @@ serde_json = "1.0" tinyfiledialogs = "3.0" [dependencies] +accountable-refcell = {version = "0.2.0", optional = true} app_units = "0.7" backtrace = {version = "0.3", optional = true} base64 = "0.10.1" diff --git a/components/script/body.rs b/components/script/body.rs index e38dd1b0a98..06b864fa4e9 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::compartments::{AlreadyInCompartment, InCompartment}; +use crate::dom::bindings::cell::Ref; use crate::dom::bindings::codegen::Bindings::FormDataBinding::FormDataMethods; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::DomObject; @@ -25,7 +26,6 @@ use js::rust::wrappers::JS_ParseJSON; use js::typedarray::{ArrayBuffer, CreateWith}; use mime::{self, Mime}; use script_traits::serializable::BlobImpl; -use std::cell::Ref; use std::ptr; use std::rc::Rc; use std::str; diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index a25fcac3667..f81a3cf9817 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::AttrBinding::{self, AttrMethods}; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom}; @@ -19,7 +19,6 @@ use dom_struct::dom_struct; use html5ever::{LocalName, Namespace, Prefix}; use servo_atoms::Atom; use std::borrow::ToOwned; -use std::cell::Ref; use std::mem; use style::attr::{AttrIdentifier, AttrValue}; diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs index f8a3f27093e..984445c8072 100644 --- a/components/script/dom/audiobuffer.rs +++ b/components/script/dom/audiobuffer.rs @@ -4,7 +4,7 @@ use crate::compartments::enter_realm; use crate::dom::audionode::MAX_CHANNEL_COUNT; -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::AudioBufferBinding::{ self, AudioBufferMethods, AudioBufferOptions, }; @@ -21,7 +21,6 @@ use js::rust::wrappers::DetachArrayBuffer; use js::rust::CustomAutoRooterGuard; use js::typedarray::{CreateWith, Float32Array}; use servo_media::audio::buffer_source_node::AudioBuffer as ServoMediaAudioBuffer; -use std::cell::Ref; use std::cmp::min; use std::ptr::{self, NonNull}; diff --git a/components/script/dom/bindings/cell.rs b/components/script/dom/bindings/cell.rs index 525ac069fe3..e3f5ad71bee 100644 --- a/components/script/dom/bindings/cell.rs +++ b/components/script/dom/bindings/cell.rs @@ -4,7 +4,13 @@ //! A shareable mutable container for the DOM. -use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut}; +#[cfg(feature = "refcell_backtrace")] +pub use accountable_refcell::{ref_filter_map, Ref, RefCell, RefMut}; +#[cfg(not(feature = "refcell_backtrace"))] +pub use ref_filter_map::ref_filter_map; +use std::cell::{BorrowError, BorrowMutError}; +#[cfg(not(feature = "refcell_backtrace"))] +pub use std::cell::{Ref, RefCell, RefMut}; use style::thread_state::{self, ThreadState}; /// A mutable field in the DOM. diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index fad367bb454..7ede2395c04 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -8,7 +8,7 @@ use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted}; use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence}; use bluetooth_traits::scanfilter::{RequestDeviceoptions, ServiceUUIDSequence}; use crate::compartments::{AlreadyInCompartment, InCompartment}; -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::BluetoothBinding::{self, BluetoothDataFilterInit}; use crate::dom::bindings::codegen::Bindings::BluetoothBinding::{BluetoothMethods, RequestDeviceOptions}; use crate::dom::bindings::codegen::Bindings::BluetoothBinding::BluetoothLEScanFilterInit; @@ -39,7 +39,6 @@ use js::conversions::ConversionResult; use js::jsapi::JSObject; use js::jsval::{ObjectValue, UndefinedValue}; use profile_traits::ipc as ProfiledIpc; -use std::cell::Ref; use std::collections::HashMap; use std::rc::Rc; use std::str::FromStr; diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs index 87aa8bd59fa..6baa6a855d9 100644 --- a/components/script/dom/characterdata.rs +++ b/components/script/dom/characterdata.rs @@ -4,7 +4,7 @@ //! DOM bindings for `CharacterData`. -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods; use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeBinding::NodeMethods; use crate::dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods; @@ -24,7 +24,6 @@ use crate::dom::processinginstruction::ProcessingInstruction; use crate::dom::text::Text; use crate::dom::virtualmethods::vtable_for; use dom_struct::dom_struct; -use std::cell::Ref; // https://dom.spec.whatwg.org/#characterdata #[dom_struct] diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index c2058f73240..1f24a96c6a0 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -8,7 +8,7 @@ use crate::dom::activation::{synthetic_click_activation, ActivationSource}; use crate::dom::attr::Attr; use crate::dom::beforeunloadevent::BeforeUnloadEvent; use crate::dom::bindings::callback::ExceptionHandling; -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{ref_filter_map, DomRefCell, Ref, RefMut}; use crate::dom::bindings::codegen::Bindings::BeforeUnloadEventBinding::BeforeUnloadEventBinding::BeforeUnloadEventMethods; use crate::dom::bindings::codegen::Bindings::DocumentBinding; use crate::dom::bindings::codegen::Bindings::DocumentBinding::{ @@ -133,7 +133,6 @@ use num_traits::ToPrimitive; use percent_encoding::percent_decode; use profile_traits::ipc as profile_ipc; use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType}; -use ref_filter_map::ref_filter_map; use ref_slice::ref_slice; use script_layout_interface::message::{Msg, ReflowGoal}; use script_traits::{AnimationState, DocumentActivity, MouseButton, MouseEventType}; @@ -146,7 +145,7 @@ use servo_config::pref; use servo_media::{ClientContextId, ServoMedia}; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use std::borrow::Cow; -use std::cell::{Cell, Ref, RefMut}; +use std::cell::Cell; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::{HashMap, HashSet, VecDeque}; use std::default::Default; diff --git a/components/script/dom/dommatrixreadonly.rs b/components/script/dom/dommatrixreadonly.rs index f8d73f628c1..acfd02bd56d 100644 --- a/components/script/dom/dommatrixreadonly.rs +++ b/components/script/dom/dommatrixreadonly.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::DOMMatrixBinding::{DOMMatrixInit, DOMMatrixMethods}; use crate::dom::bindings::codegen::Bindings::DOMMatrixReadOnlyBinding::{ DOMMatrixReadOnlyMethods, Wrap, @@ -26,7 +26,7 @@ use js::jsapi::JSObject; use js::rust::CustomAutoRooterGuard; use js::typedarray::CreateWith; use js::typedarray::{Float32Array, Float64Array}; -use std::cell::{Cell, Ref}; +use std::cell::Cell; use std::f64; use std::ptr; use std::ptr::NonNull; diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 7f956520ad2..00e70f2df02 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -6,7 +6,7 @@ use crate::dom::activation::Activatable; use crate::dom::attr::{Attr, AttrHelpersForLayout}; -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{ref_filter_map, DomRefCell, Ref, RefMut}; use crate::dom::bindings::codegen::Bindings::AttrBinding::AttrMethods; use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use crate::dom::bindings::codegen::Bindings::ElementBinding; @@ -98,7 +98,6 @@ use js::jsval::JSVal; use msg::constellation_msg::InputMethodType; use net_traits::request::CorsSettings; use net_traits::ReferrerPolicy; -use ref_filter_map::ref_filter_map; use script_layout_interface::message::ReflowGoal; use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint}; use selectors::matching::{ElementSelectorFlags, MatchingContext}; @@ -107,7 +106,7 @@ use selectors::Element as SelectorsElement; use servo_arc::Arc; use servo_atoms::Atom; use std::borrow::Cow; -use std::cell::{Cell, Ref, RefMut}; +use std::cell::Cell; use std::default::Default; use std::fmt; use std::mem; diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 89410a6b6b0..e800a89bdf1 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::attr::Attr; -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{ref_filter_map, DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::HTMLCanvasElementBinding; use crate::dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::{ HTMLCanvasElementMethods, RenderingContext, @@ -44,7 +44,6 @@ use js::rust::HandleValue; use profile_traits::ipc; use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource}; use servo_config::pref; -use std::cell::Ref; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; const DEFAULT_WIDTH: u32 = 300; @@ -192,7 +191,7 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<HTMLCanvasElement> { impl HTMLCanvasElement { pub fn context(&self) -> Option<Ref<CanvasContext>> { - ref_filter_map::ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref()) + ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref()) } fn get_or_init_2d_context(&self) -> Option<DomRoot<CanvasRenderingContext2D>> { diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index b4089fed6e3..b788c113b8e 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -1081,6 +1081,13 @@ impl HTMLFormElement { .iter() .position(|c| &**c == control) .map(|idx| controls.remove(idx)); + + // https://html.spec.whatwg.org/multipage#forms.html#the-form-element:past-names-map-5 + // "If an element listed in a form element's past names map + // changes form owner, then its entries must be removed + // from that map." + let mut past_names_map = self.past_names_map.borrow_mut(); + past_names_map.retain(|_k, v| v.0 != control); } } diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 5b6bd321534..fd2a58f8d7d 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -5,7 +5,7 @@ use crate::document_loader::{LoadBlocker, LoadType}; use crate::dom::activation::Activatable; use crate::dom::attr::Attr; -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, RefMut}; use crate::dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectBinding::DOMRectMethods; use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementBinding::ElementMethods; use crate::dom::bindings::codegen::Bindings::HTMLImageElementBinding; @@ -67,7 +67,7 @@ use num_traits::ToPrimitive; use servo_url::origin::ImmutableOrigin; use servo_url::origin::MutableOrigin; use servo_url::ServoUrl; -use std::cell::{Cell, RefMut}; +use std::cell::Cell; use std::char; use std::collections::HashSet; use std::default::Default; diff --git a/components/script/dom/mediastream.rs b/components/script/dom/mediastream.rs index 2ae573b290e..88729b57ce5 100644 --- a/components/script/dom/mediastream.rs +++ b/components/script/dom/mediastream.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::MediaStreamBinding::{self, MediaStreamMethods}; use crate::dom::bindings::error::Fallible; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; @@ -14,7 +14,6 @@ use crate::dom::mediastreamtrack::MediaStreamTrack; use crate::dom::window::Window; use dom_struct::dom_struct; use servo_media::streams::MediaStreamType; -use std::cell::Ref; #[dom_struct] pub struct MediaStream { diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 6706b535092..0c5de3f67fb 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -6,7 +6,7 @@ use crate::document_loader::DocumentLoader; use crate::dom::attr::Attr; -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref, RefMut}; use crate::dom::bindings::codegen::Bindings::AttrBinding::AttrMethods; use crate::dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods; use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; @@ -86,7 +86,7 @@ use servo_arc::Arc; use servo_url::ServoUrl; use smallvec::SmallVec; use std::borrow::ToOwned; -use std::cell::{Cell, Ref, RefMut, UnsafeCell}; +use std::cell::{Cell, UnsafeCell}; use std::cmp; use std::default::Default; use std::iter; diff --git a/components/script/dom/offscreencanvas.rs b/components/script/dom/offscreencanvas.rs index 6d7cafed6f6..704918510a6 100644 --- a/components/script/dom/offscreencanvas.rs +++ b/components/script/dom/offscreencanvas.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{ref_filter_map, DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::OffscreenCanvasBinding::{ OffscreenCanvasMethods, OffscreenRenderingContext, Wrap as OffscreenCanvasWrap, }; @@ -22,9 +22,7 @@ use euclid::default::Size2D; use ipc_channel::ipc::IpcSharedMemory; use js::rust::HandleValue; use profile_traits::ipc; -use ref_filter_map; use std::cell::Cell; -use std::cell::Ref; #[unrooted_must_root_lint::must_root] #[derive(Clone, JSTraceable, MallocSizeOf)] @@ -94,7 +92,7 @@ impl OffscreenCanvas { } pub fn context(&self) -> Option<Ref<OffscreenCanvasContext>> { - ref_filter_map::ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref()) + ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref()) } pub fn fetch_all_data(&self) -> Option<(Option<IpcSharedMemory>, Size2D<u32>)> { diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index 29fd8a15c18..dcd206e3eaf 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::body::{consume_body, BodyOperations, BodyType}; -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::HeadersBinding::{HeadersInit, HeadersMethods}; use crate::dom::bindings::codegen::Bindings::RequestBinding; use crate::dom::bindings::codegen::Bindings::RequestBinding::ReferrerPolicy; @@ -38,7 +38,7 @@ use net_traits::request::RequestMode as NetTraitsRequestMode; use net_traits::request::{Origin, Window}; use net_traits::ReferrerPolicy as MsgReferrerPolicy; use servo_url::ServoUrl; -use std::cell::{Cell, Ref}; +use std::cell::Cell; use std::rc::Rc; use std::str::FromStr; diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs index 0e756513b9a..802e803b17f 100644 --- a/components/script/dom/response.rs +++ b/components/script/dom/response.rs @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::body::{consume_body, consume_body_with_promise, BodyOperations, BodyType}; -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::HeadersBinding::{HeadersInit, HeadersMethods}; use crate::dom::bindings::codegen::Bindings::ResponseBinding; use crate::dom::bindings::codegen::Bindings::ResponseBinding::{ @@ -26,7 +26,7 @@ use hyper::StatusCode; use hyper_serde::Serde; use net_traits::response::ResponseBody as NetTraitsResponseBody; use servo_url::ServoUrl; -use std::cell::{Cell, Ref}; +use std::cell::Cell; use std::mem; use std::rc::Rc; use std::str::FromStr; diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index e4f5f89c6d3..3b040a170b1 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::WebGLProgramBinding; use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use crate::dom::bindings::inheritance::Castable; @@ -19,7 +19,7 @@ use canvas_traits::webgl::{webgl_channel, WebGLProgramId, WebGLResult}; use canvas_traits::webgl::{ActiveAttribInfo, ActiveUniformInfo, WebGLCommand, WebGLError}; use dom_struct::dom_struct; use fnv::FnvHashSet; -use std::cell::{Cell, Ref}; +use std::cell::Cell; #[dom_struct] pub struct WebGLProgram { diff --git a/components/script/dom/webglvertexarrayobjectoes.rs b/components/script/dom/webglvertexarrayobjectoes.rs index e54eaf3f04a..1d802968ae1 100644 --- a/components/script/dom/webglvertexarrayobjectoes.rs +++ b/components/script/dom/webglvertexarrayobjectoes.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{ref_filter_map, DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use crate::dom::bindings::codegen::Bindings::WebGLVertexArrayObjectOESBinding; use crate::dom::bindings::inheritance::Castable; @@ -15,8 +15,7 @@ use canvas_traits::webgl::{ ActiveAttribInfo, WebGLCommand, WebGLError, WebGLResult, WebGLVertexArrayId, }; use dom_struct::dom_struct; -use ref_filter_map::ref_filter_map; -use std::cell::{Cell, Ref}; +use std::cell::Cell; #[dom_struct] pub struct WebGLVertexArrayObjectOES { diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 8624208423e..f29fd70f99f 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::compartments::InCompartment; -use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::RequestBinding::RequestInit; use crate::dom::bindings::codegen::Bindings::WorkerBinding::WorkerType; use crate::dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScopeMethods; @@ -52,7 +52,6 @@ use net_traits::request::{ use net_traits::IpcSend; use script_traits::WorkerGlobalScopeInit; use servo_url::{MutableOrigin, ServoUrl}; -use std::cell::Ref; use std::default::Default; use std::rc::Rc; use std::sync::atomic::{AtomicBool, Ordering}; diff --git a/components/script_plugins/lib.rs b/components/script_plugins/lib.rs index f686f64f6fe..0bd43021a2e 100644 --- a/components/script_plugins/lib.rs +++ b/components/script_plugins/lib.rs @@ -125,6 +125,8 @@ fn is_unrooted_ty(sym: &Symbols, cx: &LateContext, ty: &ty::TyS, in_new_function match_def_path(cx, did.did, &[sym::core, sym.cell, sym.RefMut]) || match_def_path(cx, did.did, &[sym::core, sym.slice, sym.Iter]) || match_def_path(cx, did.did, &[sym::core, sym.slice, sym.IterMut]) || + match_def_path(cx, did.did, &[sym.accountable_refcell, sym.Ref]) || + match_def_path(cx, did.did, &[sym.accountable_refcell, sym.RefMut]) || match_def_path( cx, did.did, @@ -175,6 +177,7 @@ fn is_unrooted_ty(sym: &Symbols, cx: &LateContext, ty: &ty::TyS, in_new_function ty::Ref(..) => false, // don't recurse down &ptrs ty::RawPtr(..) => false, // don't recurse down *ptrs ty::FnDef(..) | ty::FnPtr(_) => false, + _ => true, } }); @@ -412,6 +415,7 @@ symbols! { rc Rc cell + accountable_refcell Ref RefMut slice diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index 7e97468b7eb..fd4cc3f8c4d 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -29,6 +29,7 @@ uwp = ["servo_config/uwp", "script/uwp"] webrender_debugger = ["webrender/debugger"] no_static_freetype = ["webrender/no_static_freetype"] oculusvr = ["webvr/oculusvr"] +refcell_backtrace = ["script/refcell_backtrace"] webdriver = ["webdriver_server"] webgl_backtrace = [ "script/webgl_backtrace", |