aboutsummaryrefslogtreecommitdiffstats
path: root/components/constellation
diff options
context:
space:
mode:
authorGregory Terzian <gterzian@users.noreply.github.com>2019-05-12 17:37:19 +0800
committerGregory Terzian <gterzian@users.noreply.github.com>2019-07-18 12:03:45 +0800
commit571beec179fe9fd5fff2c12b3c5dfa0a5d93df01 (patch)
tree2eda42b78fa99fd2cd51d733519d5ae9d8678a66 /components/constellation
parent973a3448a459464b79ea0ef5fb46141176cc7643 (diff)
downloadservo-571beec179fe9fd5fff2c12b3c5dfa0a5d93df01.tar.gz
servo-571beec179fe9fd5fff2c12b3c5dfa0a5d93df01.zip
clean-up navigation
security: check target and source origin before executing JS url implement replacement-enabled flag as a HistoryEntryReplacement enum add source origin string on loaddata add LoadOrigin iframe: remove optional load-data auxiliaries: add load-data into info constellation: remove url from Pipeline::new check load origin: link to whatwg issue switch loadorigin toplevel to constellation
Diffstat (limited to 'components/constellation')
-rw-r--r--components/constellation/constellation.rs123
-rw-r--r--components/constellation/pipeline.rs6
2 files changed, 63 insertions, 66 deletions
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index 2c5b2b6c603..85f5455dc88 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -145,11 +145,11 @@ use script_traits::{
use script_traits::{
ConstellationControlMsg, ConstellationMsg as FromCompositorMsg, DiscardBrowsingContext,
};
-use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData};
+use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData, LoadOrigin};
+use script_traits::{HistoryEntryReplacement, IFrameSizeMsg, WindowSizeData, WindowSizeType};
use script_traits::{
IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerSchedulerMsg,
};
-use script_traits::{IFrameSizeMsg, WindowSizeData, WindowSizeType};
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
use script_traits::{SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WebDriverCommandMsg};
use serde::{Deserialize, Serialize};
@@ -171,7 +171,7 @@ use style_traits::viewport::ViewportConstraints;
use style_traits::CSSPixel;
use webvr_traits::{WebVREvent, WebVRMsg};
-type PendingApprovalNavigations = HashMap<PipelineId, (LoadData, bool)>;
+type PendingApprovalNavigations = HashMap<PipelineId, (LoadData, HistoryEntryReplacement)>;
/// Servo supports tabs (referred to as browsers), so `Constellation` needs to
/// store browser specific data for bookkeeping.
@@ -1320,7 +1320,7 @@ where
// If there is already a pending page (self.pending_changes), it will not be overridden;
// However, if the id is not encompassed by another change, it will be.
FromCompositorMsg::LoadUrl(top_level_browsing_context_id, url) => {
- let load_data = LoadData::new(url, None, None, None);
+ let load_data = LoadData::new(LoadOrigin::Constellation, url, None, None, None);
let ctx_id = BrowsingContextId::from(top_level_browsing_context_id);
let pipeline_id = match self.browsing_contexts.get(&ctx_id) {
Some(ctx) => ctx.pipeline_id,
@@ -1333,7 +1333,12 @@ where
};
// Since this is a top-level load, initiated by the embedder, go straight to load_url,
// bypassing schedule_navigation.
- self.load_url(top_level_browsing_context_id, pipeline_id, load_data, false);
+ self.load_url(
+ top_level_browsing_context_id,
+ pipeline_id,
+ load_data,
+ HistoryEntryReplacement::Disabled,
+ );
},
FromCompositorMsg::IsReadyToSaveImage(pipeline_states) => {
let is_ready = self.handle_is_ready_to_save_image(pipeline_states);
@@ -1916,7 +1921,7 @@ where
warn!("creating replacement pipeline for about:failure");
let new_pipeline_id = PipelineId::new();
- let load_data = LoadData::new(failure_url, None, None, None);
+ let load_data = LoadData::new(LoadOrigin::Constellation, failure_url, None, None, None);
let sandbox = IFrameSandboxState::IFrameSandboxed;
let is_private = false;
self.new_pipeline(
@@ -2035,7 +2040,7 @@ where
);
self.embedder_proxy.send(msg);
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
- let load_data = LoadData::new(url, None, None, None);
+ let load_data = LoadData::new(LoadOrigin::Constellation, url, None, None, None);
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
let is_private = false;
let is_visible = true;
@@ -2196,7 +2201,9 @@ where
// see https://html.spec.whatwg.org/multipage/#the-iframe-element:completely-loaded
debug!("checking old pipeline? {:?}", load_info.old_pipeline_id);
if let Some(old_pipeline) = old_pipeline {
- replace |= !old_pipeline.completely_loaded;
+ if !old_pipeline.completely_loaded {
+ replace = HistoryEntryReplacement::Enabled;
+ }
debug!(
"old pipeline is {}completely loaded",
if old_pipeline.completely_loaded {
@@ -2207,16 +2214,6 @@ where
);
}
- let load_data = load_info.load_data.unwrap_or_else(|| {
- let url = match old_pipeline {
- Some(old_pipeline) => old_pipeline.url.clone(),
- None => ServoUrl::parse("about:blank").expect("infallible"),
- };
-
- // TODO - loaddata here should have referrer info (not None, None)
- LoadData::new(url, Some(parent_pipeline_id), None, None)
- });
-
let is_parent_private = {
let parent_browsing_context_id = match self.pipelines.get(&parent_pipeline_id) {
Some(pipeline) => pipeline.browsing_context_id,
@@ -2250,10 +2247,11 @@ where
},
};
- let replace = if replace {
- Some(NeedsToReload::No(browsing_context.pipeline_id))
- } else {
- None
+ let replace = match replace {
+ HistoryEntryReplacement::Enabled => {
+ Some(NeedsToReload::No(browsing_context.pipeline_id))
+ },
+ HistoryEntryReplacement::Disabled => None,
};
// https://github.com/rust-lang/rust/issues/59159
@@ -2268,7 +2266,7 @@ where
Some(parent_pipeline_id),
None,
browsing_context_size,
- load_data,
+ load_info.load_data,
load_info.sandbox,
is_private,
browsing_context_is_visible,
@@ -2285,7 +2283,7 @@ where
fn handle_script_new_iframe(
&mut self,
- load_info: IFrameLoadInfo,
+ load_info: IFrameLoadInfoWithData,
layout_sender: IpcSender<LayoutControlMsg>,
) {
let IFrameLoadInfo {
@@ -2295,12 +2293,7 @@ where
top_level_browsing_context_id,
is_private,
..
- } = load_info;
-
- let url = ServoUrl::parse("about:blank").expect("infallible");
-
- // TODO: Referrer?
- let load_data = LoadData::new(url.clone(), Some(parent_pipeline_id), None, None);
+ } = load_info.info;
let (script_sender, parent_browsing_context_id) =
match self.pipelines.get(&parent_pipeline_id) {
@@ -2326,9 +2319,8 @@ where
script_sender,
layout_sender,
self.compositor_proxy.clone(),
- url,
is_parent_visible,
- load_data,
+ load_info.load_data,
);
assert!(!self.pipelines.contains_key(&new_pipeline_id));
@@ -2353,17 +2345,13 @@ where
layout_sender: IpcSender<LayoutControlMsg>,
) {
let AuxiliaryBrowsingContextLoadInfo {
+ load_data,
opener_pipeline_id,
new_top_level_browsing_context_id,
new_browsing_context_id,
new_pipeline_id,
} = load_info;
- let url = ServoUrl::parse("about:blank").expect("infallible");
-
- // TODO: Referrer?
- let load_data = LoadData::new(url.clone(), None, None, None);
-
let (script_sender, opener_browsing_context_id) =
match self.pipelines.get(&opener_pipeline_id) {
Some(pipeline) => (pipeline.event_loop.clone(), pipeline.browsing_context_id),
@@ -2392,7 +2380,6 @@ where
script_sender,
layout_sender,
self.compositor_proxy.clone(),
- url,
is_opener_visible,
load_data,
);
@@ -2496,7 +2483,7 @@ where
top_level_browsing_context_id: TopLevelBrowsingContextId,
source_id: PipelineId,
load_data: LoadData,
- replace: bool,
+ replace: HistoryEntryReplacement,
) {
match self.pending_approval_navigations.entry(source_id) {
Entry::Occupied(_) => {
@@ -2522,13 +2509,15 @@ where
top_level_browsing_context_id: TopLevelBrowsingContextId,
source_id: PipelineId,
load_data: LoadData,
- replace: bool,
+ replace: HistoryEntryReplacement,
) -> Option<PipelineId> {
+ let replace_debug = match replace {
+ HistoryEntryReplacement::Enabled => "",
+ HistoryEntryReplacement::Disabled => "not",
+ };
debug!(
"Loading {} in pipeline {}, {}replacing.",
- load_data.url,
- source_id,
- if replace { "" } else { "not " }
+ load_data.url, source_id, replace_debug
);
// If this load targets an iframe, its framing element may exist
// in a separate script thread than the framed document that initiated
@@ -2569,7 +2558,7 @@ where
Some(parent_pipeline_id) => {
// Find the script thread for the pipeline containing the iframe
// and issue an iframe load through there.
- let msg = ConstellationControlMsg::Navigate(
+ let msg = ConstellationControlMsg::NavigateIframe(
parent_pipeline_id,
browsing_context_id,
load_data,
@@ -2612,10 +2601,9 @@ where
// Create the new pipeline
- let replace = if replace {
- Some(NeedsToReload::No(pipeline_id))
- } else {
- None
+ let replace = match replace {
+ HistoryEntryReplacement::Enabled => Some(NeedsToReload::No(pipeline_id)),
+ HistoryEntryReplacement::Disabled => None,
};
let new_pipeline_id = PipelineId::new();
@@ -2730,7 +2718,7 @@ where
&mut self,
pipeline_id: PipelineId,
new_url: ServoUrl,
- replacement_enabled: bool,
+ replacement_enabled: HistoryEntryReplacement,
) {
let (top_level_browsing_context_id, old_url) = match self.pipelines.get_mut(&pipeline_id) {
Some(pipeline) => {
@@ -2745,15 +2733,18 @@ where
},
};
- if !replacement_enabled {
- let diff = SessionHistoryDiff::HashDiff {
- pipeline_reloader: NeedsToReload::No(pipeline_id),
- new_url,
- old_url,
- };
- self.get_joint_session_history(top_level_browsing_context_id)
- .push_diff(diff);
- self.notify_history_changed(top_level_browsing_context_id);
+ match replacement_enabled {
+ HistoryEntryReplacement::Disabled => {
+ let diff = SessionHistoryDiff::HashDiff {
+ pipeline_reloader: NeedsToReload::No(pipeline_id),
+ new_url,
+ old_url,
+ };
+ self.get_joint_session_history(top_level_browsing_context_id)
+ .push_diff(diff);
+ self.notify_history_changed(top_level_browsing_context_id);
+ },
+ HistoryEntryReplacement::Enabled => {},
}
}
@@ -3395,7 +3386,12 @@ where
));
},
WebDriverCommandMsg::LoadUrl(top_level_browsing_context_id, load_data, reply) => {
- self.load_url_for_webdriver(top_level_browsing_context_id, load_data, reply, false);
+ self.load_url_for_webdriver(
+ top_level_browsing_context_id,
+ load_data,
+ reply,
+ HistoryEntryReplacement::Disabled,
+ );
},
WebDriverCommandMsg::Refresh(top_level_browsing_context_id, reply) => {
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
@@ -3412,7 +3408,12 @@ where
Some(pipeline) => pipeline.load_data.clone(),
None => return warn!("Pipeline {} refresh after closure.", pipeline_id),
};
- self.load_url_for_webdriver(top_level_browsing_context_id, load_data, reply, true);
+ self.load_url_for_webdriver(
+ top_level_browsing_context_id,
+ load_data,
+ reply,
+ HistoryEntryReplacement::Enabled,
+ );
},
WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd) => {
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
@@ -3595,7 +3596,7 @@ where
top_level_browsing_context_id: TopLevelBrowsingContextId,
load_data: LoadData,
reply: IpcSender<webdriver_msg::LoadStatus>,
- replace: bool,
+ replace: HistoryEntryReplacement,
) {
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index 8c770a1c274..a5757664497 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -215,8 +215,6 @@ impl Pipeline {
device_pixel_ratio: state.device_pixel_ratio,
};
- let url = state.load_data.url.clone();
-
let (script_chan, sampler_chan) = match state.event_loop {
Some(script_chan) => {
let new_layout_info = NewLayoutInfo {
@@ -336,7 +334,6 @@ impl Pipeline {
script_chan,
pipeline_chan,
state.compositor_proxy,
- url,
state.prev_visibility,
state.load_data,
);
@@ -356,7 +353,6 @@ impl Pipeline {
event_loop: Rc<EventLoop>,
layout_chan: IpcSender<LayoutControlMsg>,
compositor_proxy: CompositorProxy,
- url: ServoUrl,
is_visible: bool,
load_data: LoadData,
) -> Pipeline {
@@ -368,7 +364,7 @@ impl Pipeline {
event_loop: event_loop,
layout_chan: layout_chan,
compositor_proxy: compositor_proxy,
- url: url,
+ url: load_data.url.clone(),
children: vec![],
running_animations: false,
load_data: load_data,