aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/main/constellation.rs16
-rw-r--r--src/components/msg/constellation_msg.rs8
-rw-r--r--src/components/script/dom/element.rs16
-rw-r--r--src/components/script/dom/htmliframeelement.rs49
-rw-r--r--src/components/script/html/hubbub_html_parser.rs8
-rw-r--r--src/components/script/script_task.rs12
m---------src/support/spidermonkey/rust-mozjs0
-rw-r--r--src/test/html/test_sandboxed.html14
-rw-r--r--src/test/html/test_sandboxed_iframe.html24
9 files changed, 124 insertions, 23 deletions
diff --git a/src/components/main/constellation.rs b/src/components/main/constellation.rs
index 7ae71478306..271b72526bb 100644
--- a/src/components/main/constellation.rs
+++ b/src/components/main/constellation.rs
@@ -13,9 +13,9 @@ use geom::size::Size2D;
use geom::rect::Rect;
use gfx::opts::Opts;
use pipeline::Pipeline;
-use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FrameRectMsg};
+use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FrameRectMsg, IFrameSandboxState};
use servo_msg::constellation_msg::{InitLoadUrlMsg, LoadIframeUrlMsg, LoadUrlMsg};
-use servo_msg::constellation_msg::{Msg, NavigateMsg, NavigationType};
+use servo_msg::constellation_msg::{Msg, NavigateMsg, NavigationType, IFrameUnsandboxed};
use servo_msg::constellation_msg::{PipelineId, RendererReadyMsg, ResizedWindowMsg, SubpageId};
use servo_msg::constellation_msg;
use script::script_task::{SendEventMsg, ResizeInactiveMsg, ExecuteMsg};
@@ -328,8 +328,8 @@ impl Constellation {
FrameRectMsg(pipeline_id, subpage_id, rect) => {
self.handle_frame_rect_msg(pipeline_id, subpage_id, rect);
}
- LoadIframeUrlMsg(url, source_pipeline_id, subpage_id, size_future) => {
- self.handle_load_iframe_url_msg(url, source_pipeline_id, subpage_id, size_future);
+ LoadIframeUrlMsg(url, source_pipeline_id, subpage_id, size_future, sandbox) => {
+ self.handle_load_iframe_url_msg(url, source_pipeline_id, subpage_id, size_future, sandbox);
}
// Load a new page, usually -- but not always -- from a mouse click or typed url
// If there is already a pending page (self.pending_frames), it will not be overridden;
@@ -455,7 +455,8 @@ impl Constellation {
url: Url,
source_pipeline_id: PipelineId,
subpage_id: SubpageId,
- size_future: Future<Size2D<uint>>) {
+ size_future: Future<Size2D<uint>>,
+ sandbox: IFrameSandboxState) {
// A message from the script associated with pipeline_id that it has
// parsed an iframe during html parsing. This iframe will result in a
// new pipeline being spawned and a frame tree being added to pipeline_id's
@@ -489,9 +490,10 @@ impl Constellation {
source's Url is None. There should never be a LoadUrlIframeMsg from a pipeline
that was never given a url to load.");
+ let same_script = (source_url.host == url.host &&
+ source_url.port == url.port) && sandbox == IFrameUnsandboxed;
// FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
- let pipeline = @mut if (source_url.host == url.host &&
- source_url.port == url.port) {
+ let pipeline = @mut if same_script {
debug!("Constellation: loading same-origin iframe at %?", url);
// Reuse the script task if same-origin url's
Pipeline::with_script(next_pipeline_id,
diff --git a/src/components/msg/constellation_msg.rs b/src/components/msg/constellation_msg.rs
index 51bcbb08c46..c5b4dbb48d0 100644
--- a/src/components/msg/constellation_msg.rs
+++ b/src/components/msg/constellation_msg.rs
@@ -27,12 +27,18 @@ impl ConstellationChan {
}
}
+#[deriving(Eq)]
+pub enum IFrameSandboxState {
+ IFrameSandboxed,
+ IFrameUnsandboxed
+}
+
pub enum Msg {
ExitMsg(Chan<()>),
InitLoadUrlMsg(Url),
FrameRectMsg(PipelineId, SubpageId, Rect<f32>),
LoadUrlMsg(PipelineId, Url, Future<Size2D<uint>>),
- LoadIframeUrlMsg(Url, PipelineId, SubpageId, Future<Size2D<uint>>),
+ LoadIframeUrlMsg(Url, PipelineId, SubpageId, Future<Size2D<uint>>, IFrameSandboxState),
NavigateMsg(NavigationDirection),
RendererReadyMsg(PipelineId),
ResizedWindowMsg(Size2D<uint>),
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs
index be475bd1d85..0bb776628c9 100644
--- a/src/components/script/dom/element.rs
+++ b/src/components/script/dom/element.rs
@@ -139,9 +139,9 @@ impl<'self> Element {
return None;
}
- pub fn set_attr(&mut self, name: &DOMString, value: &DOMString) {
- let name = name.to_str();
- let value_cell = Cell::new(value.to_str());
+ pub fn set_attr(&mut self, raw_name: &DOMString, raw_value: &DOMString) {
+ let name = raw_name.to_str();
+ let value_cell = Cell::new(raw_value.to_str());
let mut found = false;
for attr in self.attrs.mut_iter() {
if eq_slice(attr.name, name) {
@@ -158,7 +158,15 @@ impl<'self> Element {
self.style_attribute = Some(
Stylesheet::from_attribute(
FromStr::from_str("http://www.example.com/").unwrap(),
- value.get_ref()));
+ raw_value.get_ref()));
+ }
+
+ //XXXjdm We really need something like a vtable so we can call AfterSetAttr.
+ // This hardcoding is awful.
+ if self.parent.abstract.unwrap().is_iframe_element() {
+ do self.parent.abstract.unwrap().with_mut_iframe_element |iframe| {
+ iframe.AfterSetAttr(raw_name, raw_value);
+ }
}
match self.parent.owner_doc {
diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs
index 288a988928a..4c45e570b54 100644
--- a/src/components/script/dom/htmliframeelement.rs
+++ b/src/components/script/dom/htmliframeelement.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 http://mozilla.org/MPL/2.0/. */
-use dom::bindings::utils::{DOMString, null_string, ErrorResult};
+use dom::bindings::utils::{DOMString, null_string, ErrorResult, str};
use dom::document::AbstractDocument;
use dom::htmlelement::HTMLElement;
use dom::windowproxy::WindowProxy;
@@ -11,14 +11,26 @@ use geom::rect::Rect;
use servo_msg::constellation_msg::{ConstellationChan, FrameRectMsg, PipelineId, SubpageId};
+use std::ascii::StrAsciiExt;
use std::comm::ChanOne;
use extra::url::Url;
use std::util::replace;
+enum SandboxAllowance {
+ AllowNothing = 0x00,
+ AllowSameOrigin = 0x01,
+ AllowTopNavigation = 0x02,
+ AllowForms = 0x04,
+ AllowScripts = 0x08,
+ AllowPointerLock = 0x10,
+ AllowPopups = 0x20
+}
+
pub struct HTMLIFrameElement {
parent: HTMLElement,
frame: Option<Url>,
size: Option<IFrameSize>,
+ sandbox: Option<u8>
}
struct IFrameSize {
@@ -39,6 +51,11 @@ impl IFrameSize {
}
}
+impl HTMLIFrameElement {
+ pub fn is_sandboxed(&self) -> bool {
+ self.sandbox.is_some()
+ }
+}
impl HTMLIFrameElement {
pub fn Src(&self) -> DOMString {
@@ -63,10 +80,32 @@ impl HTMLIFrameElement {
}
pub fn Sandbox(&self) -> DOMString {
- null_string
- }
-
- pub fn SetSandbox(&self, _sandbox: &DOMString) {
+ self.parent.parent.GetAttribute(&str(~"sandbox"))
+ }
+
+ pub fn SetSandbox(&mut self, sandbox: &DOMString) {
+ let mut rv = Ok(());
+ self.parent.parent.SetAttribute(&str(~"sandbox"), sandbox, &mut rv);
+ }
+
+ pub fn AfterSetAttr(&mut self, name: &DOMString, value: &DOMString) {
+ let name = name.to_str();
+ if "sandbox" == name {
+ let mut modes = AllowNothing as u8;
+ let words = value.to_str();
+ for word in words.split_iter(' ') {
+ modes |= match word.to_ascii_lower().as_slice() {
+ "allow-same-origin" => AllowSameOrigin,
+ "allow-forms" => AllowForms,
+ "allow-pointer-lock" => AllowPointerLock,
+ "allow-popups" => AllowPopups,
+ "allow-scripts" => AllowScripts,
+ "allow-top-navigation" => AllowTopNavigation,
+ _ => AllowNothing
+ } as u8;
+ }
+ self.sandbox = Some(modes);
+ }
}
pub fn AllowFullscreen(&self) -> bool {
diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs
index 64340a28b77..42c9e43cf48 100644
--- a/src/components/script/html/hubbub_html_parser.rs
+++ b/src/components/script/html/hubbub_html_parser.rs
@@ -93,7 +93,7 @@ enum JSMessage {
/// Messages generated by the HTML parser upon discovery of additional resources
pub enum HtmlDiscoveryMessage {
HtmlDiscoveredStyle(Stylesheet),
- HtmlDiscoveredIFrame((Url, SubpageId, Future<Size2D<uint>>)),
+ HtmlDiscoveredIFrame((Url, SubpageId, Future<Size2D<uint>>, bool)),
HtmlDiscoveredScript(JSResult)
}
@@ -272,7 +272,7 @@ pub fn build_element_from_tag(cx: *JSContext, tag: &str) -> AbstractNode<ScriptV
handle_element!(cx, tag, "ul", HTMLUListElementTypeId, HTMLUListElement, []);
handle_element!(cx, tag, "img", HTMLImageElementTypeId, HTMLImageElement, [(image: None)]);
- handle_element!(cx, tag, "iframe", HTMLIframeElementTypeId, HTMLIFrameElement, [(frame: None), (size: None)]);
+ handle_element!(cx, tag, "iframe", HTMLIframeElementTypeId, HTMLIFrameElement, [(frame: None), (size: None), (sandbox: None)]);
handle_element!(cx, tag, "h1", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading1)]);
handle_element!(cx, tag, "h2", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading2)]);
@@ -401,6 +401,7 @@ pub fn parse_html(cx: *JSContext,
let iframe_chan = Cell::new(discovery_chan.clone());
do node.with_mut_iframe_element |iframe_element| {
let iframe_chan = iframe_chan.take();
+ let sandboxed = iframe_element.is_sandboxed();
let elem = &mut iframe_element.parent.parent;
let src_opt = elem.get_attr("src").map(|x| x.to_str());
for src in src_opt.iter() {
@@ -427,7 +428,8 @@ pub fn parse_html(cx: *JSContext,
future_chan: Some(chan),
constellation_chan: constellation_chan.clone(),
});
- iframe_chan.send(HtmlDiscoveredIFrame((iframe_url, subpage_id, size_future)));
+ iframe_chan.send(HtmlDiscoveredIFrame((iframe_url, subpage_id,
+ size_future, sandboxed)));
}
}
}
diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs
index 759d37a6dc4..9d45dc7d8dc 100644
--- a/src/components/script/script_task.rs
+++ b/src/components/script/script_task.rs
@@ -22,7 +22,7 @@ use layout_interface::ReflowMsg;
use layout_interface;
use servo_msg::constellation_msg::{ConstellationChan, LoadUrlMsg, NavigationDirection};
use servo_msg::constellation_msg::{PipelineId, SubpageId, RendererReadyMsg};
-use servo_msg::constellation_msg::{LoadIframeUrlMsg};
+use servo_msg::constellation_msg::{LoadIframeUrlMsg, IFrameSandboxed, IFrameUnsandboxed};
use servo_msg::constellation_msg;
use std::cell::Cell;
@@ -641,12 +641,18 @@ impl ScriptTask {
Some(HtmlDiscoveredStyle(sheet)) => {
page.layout_chan.send(AddStylesheetMsg(sheet));
}
- Some(HtmlDiscoveredIFrame((iframe_url, subpage_id, size_future))) => {
+ Some(HtmlDiscoveredIFrame((iframe_url, subpage_id, size_future, sandboxed))) => {
page.next_subpage_id = SubpageId(*subpage_id + 1);
+ let sandboxed = if sandboxed {
+ IFrameSandboxed
+ } else {
+ IFrameUnsandboxed
+ };
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url,
pipeline_id,
subpage_id,
- size_future));
+ size_future,
+ sandboxed));
}
None => break
}
diff --git a/src/support/spidermonkey/rust-mozjs b/src/support/spidermonkey/rust-mozjs
-Subproject 353ef00db32e526f054f1f7899cd93425cfb1c5
+Subproject a9bc3b5cf968e279cfb082e58207c60e4f4a1a9
diff --git a/src/test/html/test_sandboxed.html b/src/test/html/test_sandboxed.html
new file mode 100644
index 00000000000..f0c485b5794
--- /dev/null
+++ b/src/test/html/test_sandboxed.html
@@ -0,0 +1,14 @@
+<html>
+<body>
+ <iframe sandbox="allow-scripts" src="test_sandboxed_iframe.html"
+ style="display:block; border: 1px; width: 400px; height: 400px"
+ frameborder="yes"
+ scrolling="yes"></iframe>
+hiiiiiiiii
+ <iframe sandbox="allow-scripts" src="test_sandboxed_iframe.html"
+ style="display:block; border: 1px; width: 400px; height: 400px"
+ frameborder="yes"
+ scrolling="yes"></iframe>
+byeeeeeeeeeeee
+</body>
+</html>
diff --git a/src/test/html/test_sandboxed_iframe.html b/src/test/html/test_sandboxed_iframe.html
new file mode 100644
index 00000000000..210a6134a1b
--- /dev/null
+++ b/src/test/html/test_sandboxed_iframe.html
@@ -0,0 +1,24 @@
+<html>
+<body>
+ <script>
+ var a = 1;
+ var b = 1;
+ var c = 2;
+ var step = 1;
+ window.alert(Date.now());
+ var next = new Date();
+ window.alert(next);
+ while (true) {
+ if ((new Date()) >= next) {
+ window.alert("step " + step + ": " + c);
+ a = b;
+ b = c;
+ c = a + b;
+ step++;
+ next = new Date(Date.now() + 500);
+ }
+ }
+ </script>
+hi there
+</body>
+</html>