aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/globalscope.rs54
-rw-r--r--components/script/dom/htmlcanvaselement.rs30
-rw-r--r--components/script/dom/window.rs17
3 files changed, 62 insertions, 39 deletions
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index 77d1ee37c03..b3345b90fc0 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -2422,7 +2422,8 @@ impl GlobalScope {
headers: &Option<Serde<HeaderMap>>,
) -> Option<CspList> {
// TODO: Implement step 1 (local scheme special case)
- let mut csp = headers.as_ref()?.get_all("content-security-policy").iter();
+ let headers = headers.as_ref()?;
+ let mut csp = headers.get_all("content-security-policy").iter();
// This silently ignores the CSP if it contains invalid Unicode.
// We should probably report an error somewhere.
let c = csp.next().and_then(|c| c.to_str().ok())?;
@@ -2435,6 +2436,19 @@ impl GlobalScope {
PolicyDisposition::Enforce,
));
}
+ let csp_report = headers
+ .get_all("content-security-policy-report-only")
+ .iter();
+ // This silently ignores the CSP if it contains invalid Unicode.
+ // We should probably report an error somewhere.
+ for c in csp_report {
+ let c = c.to_str().ok()?;
+ csp_list.append(CspList::parse(
+ c,
+ PolicySource::Header,
+ PolicyDisposition::Report,
+ ));
+ }
Some(csp_list)
}
@@ -2822,36 +2836,16 @@ impl GlobalScope {
}))
}
- #[allow(unsafe_code)]
- pub(crate) fn is_js_evaluation_allowed(&self, cx: SafeJSContext) -> bool {
+ pub(crate) fn is_js_evaluation_allowed(&self, source: &str) -> bool {
let Some(csp_list) = self.get_csp_list() else {
return true;
};
- let scripted_caller = unsafe { describe_scripted_caller(*cx) }.unwrap_or_default();
- let is_js_evaluation_allowed = csp_list.is_js_evaluation_allowed() == CheckResult::Allowed;
-
- if !is_js_evaluation_allowed {
- // FIXME: Don't fire event if `script-src` and `default-src`
- // were not passed.
- for policy in csp_list.0 {
- let report = CSPViolationReportBuilder::default()
- .resource("eval".to_owned())
- .effective_directive("script-src".to_owned())
- .report_only(policy.disposition == PolicyDisposition::Report)
- .source_file(scripted_caller.filename.clone())
- .line_number(scripted_caller.line)
- .column_number(scripted_caller.col)
- .build(self);
- let task = CSPViolationReportTask::new(self, report);
+ let (is_js_evaluation_allowed, violations) = csp_list.is_js_evaluation_allowed(source);
- self.task_manager()
- .dom_manipulation_task_source()
- .queue(task);
- }
- }
+ self.report_csp_violations(violations);
- is_js_evaluation_allowed
+ is_js_evaluation_allowed == CheckResult::Allowed
}
pub(crate) fn create_image_bitmap(
@@ -3464,10 +3458,13 @@ impl GlobalScope {
unreachable!();
}
+ #[allow(unsafe_code)]
pub(crate) fn report_csp_violations(&self, violations: Vec<Violation>) {
+ let scripted_caller =
+ unsafe { describe_scripted_caller(*GlobalScope::get_cx()) }.unwrap_or_default();
for violation in violations {
let (sample, resource) = match violation.resource {
- ViolationResource::Inline { .. } => (None, "inline".to_owned()),
+ ViolationResource::Inline { sample } => (sample, "inline".to_owned()),
ViolationResource::Url(url) => (None, url.into()),
ViolationResource::TrustedTypePolicy { sample } => {
(Some(sample), "trusted-types-policy".to_owned())
@@ -3475,6 +3472,8 @@ impl GlobalScope {
ViolationResource::TrustedTypeSink { sample } => {
(Some(sample), "trusted-types-sink".to_owned())
},
+ ViolationResource::Eval { sample } => (sample, "eval".to_owned()),
+ ViolationResource::WasmEval => (None, "wasm-eval".to_owned()),
};
let report = CSPViolationReportBuilder::default()
.resource(resource)
@@ -3482,6 +3481,9 @@ impl GlobalScope {
.effective_directive(violation.directive.name)
.original_policy(violation.policy.to_string())
.report_only(violation.policy.disposition == PolicyDisposition::Report)
+ .source_file(scripted_caller.filename.clone())
+ .line_number(scripted_caller.line)
+ .column_number(scripted_caller.col + 1)
.build(self);
let task = CSPViolationReportTask::new(self, report);
self.task_manager()
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index 303c781c8b3..bb27d28cea8 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -407,15 +407,23 @@ impl HTMLCanvasElement {
&self,
image_type: &EncodedImageType,
quality: Option<f64>,
- bytes: &[u8],
+ snapshot: &Snapshot,
encoder: &mut W,
) {
+ // We can't use self.Width() or self.Height() here, since the size of the canvas
+ // may have changed since the snapshot was created. Truncating the dimensions to a
+ // u32 can't panic, since the data comes from a canvas which is always smaller than
+ // u32::MAX.
+ let canvas_data = snapshot.data();
+ let width = snapshot.size().width as u32;
+ let height = snapshot.size().height as u32;
+
match image_type {
EncodedImageType::Png => {
// FIXME(nox): https://github.com/image-rs/image-png/issues/86
// FIXME(nox): https://github.com/image-rs/image-png/issues/87
PngEncoder::new(encoder)
- .write_image(bytes, self.Width(), self.Height(), ColorType::Rgba8)
+ .write_image(canvas_data, width, height, ColorType::Rgba8)
.unwrap();
},
EncodedImageType::Jpeg => {
@@ -435,14 +443,14 @@ impl HTMLCanvasElement {
};
jpeg_encoder
- .write_image(bytes, self.Width(), self.Height(), ColorType::Rgba8)
+ .write_image(canvas_data, width, height, ColorType::Rgba8)
.unwrap();
},
EncodedImageType::Webp => {
// No quality support because of https://github.com/image-rs/image/issues/1984
WebPEncoder::new_lossless(encoder)
- .write_image(bytes, self.Width(), self.Height(), ColorType::Rgba8)
+ .write_image(canvas_data, width, height, ColorType::Rgba8)
.unwrap();
},
}
@@ -567,7 +575,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
self.encode_for_mime_type(
&image_type,
Self::maybe_quality(quality),
- snapshot.data(),
+ &snapshot,
&mut encoder,
);
encoder.into_inner();
@@ -589,8 +597,8 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
return Err(Error::Security);
}
- // Step 2. and 3.
- // If this canvas element's bitmap has pixels (i.e., neither its horizontal dimension
+ // Step 2. Let result be null.
+ // Step 3. If this canvas element's bitmap has pixels (i.e., neither its horizontal dimension
// nor its vertical dimension is zero),
// then set result to a copy of this canvas element's bitmap.
let result = if self.Width() == 0 || self.Height() == 0 {
@@ -627,12 +635,12 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
// type and quality if given.
let mut encoded: Vec<u8> = vec![];
- this.encode_for_mime_type(&image_type, quality, snapshot.data(), &mut encoded);
+ this.encode_for_mime_type(&image_type, quality, &snapshot, &mut encoded);
let blob_impl = BlobImpl::new_from_bytes(encoded, image_type.as_mime_type());
- // Step 4.2.1 & 4.2.2
- // Set result to a new Blob object, created in the relevant realm of this canvas element
- // Invoke callback with « result » and "report".
+ // Step 4.2.1 Set result to a new Blob object, created in the relevant realm of this canvas element
let blob = Blob::new(&this.global(), blob_impl, CanGc::note());
+
+ // Step 4.2.2 Invoke callback with « result » and "report".
let _ = callback.Call__(Some(&blob), ExceptionHandling::Report, CanGc::note());
} else {
let _ = callback.Call__(None, ExceptionHandling::Report, CanGc::note());
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 418c737acd4..e210476a5df 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -1389,7 +1389,17 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
// https://drafts.csswg.org/cssom-view/#dom-window-resizeto
fn ResizeTo(&self, width: i32, height: i32) {
// Step 1
- //TODO determine if this operation is allowed
+ let window_proxy = match self.window_proxy.get() {
+ Some(proxy) => proxy,
+ None => return,
+ };
+
+ // If target is not an auxiliary browsing context that was created by a script
+ // (as opposed to by an action of the user), then return.
+ if !window_proxy.is_auxiliary() {
+ return;
+ }
+
let dpr = self.device_pixel_ratio();
let size = Size2D::new(width, height).to_f32() * dpr;
self.send_to_embedder(EmbedderMsg::ResizeTo(self.webview_id(), size.to_i32()));
@@ -2392,7 +2402,10 @@ impl Window {
return (None, Rect::zero());
}
- let response = self.layout.borrow().query_offset_parent(node.to_opaque());
+ let response = self
+ .layout
+ .borrow()
+ .query_offset_parent(node.to_trusted_node_address());
let element = response.node_address.and_then(|parent_node_address| {
let node = unsafe { from_untrusted_node_address(parent_node_address) };
DomRoot::downcast(node)