aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/canvasrenderingcontext2d.rs
diff options
context:
space:
mode:
authorTetsuharu OHZEKI <saneyuki.snyk@gmail.com>2015-03-25 03:07:34 +0900
committerTetsuharu OHZEKI <saneyuki.snyk@gmail.com>2015-03-25 15:13:34 +0900
commitbc06526610d901a6a80c3146353c82d13c54f2b4 (patch)
treee4b8a63c48323035e754b2e45bbfda448f77b16c /components/script/dom/canvasrenderingcontext2d.rs
parent05c6d046ddbfbbe626a69bed32cf681569e86eb7 (diff)
downloadservo-bc06526610d901a6a80c3146353c82d13c54f2b4.tar.gz
servo-bc06526610d901a6a80c3146353c82d13c54f2b4.zip
Add guards to almost CanvasRenderingContext2D methods according to the spec.
http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas_CR/ says "Except where otherwise specified, for the 2D context interface, any method call with a numeric argument whose value is infinite or a NaN value must be ignored." We might define the annotation to generate this behavior in glue code. However, at now, I use this workaround way.
Diffstat (limited to 'components/script/dom/canvasrenderingcontext2d.rs')
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs90
1 files changed, 89 insertions, 1 deletions
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index 621bb629df0..37108922fc5 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasWin
use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods;
use dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrCanvasRenderingContext2D;
use dom::bindings::codegen::UnionTypes::StringOrCanvasGradientOrCanvasPattern;
-use dom::bindings::error::Error::{IndexSize, TypeError};
+use dom::bindings::error::Error::{IndexSize, NotSupported, TypeError};
use dom::bindings::error::Fallible;
use dom::bindings::global::{GlobalRef, GlobalField};
use dom::bindings::js::{JS, JSRef, LayoutJS, Temporary};
@@ -207,22 +207,44 @@ impl LayoutCanvasRenderingContext2DHelpers for LayoutJS<CanvasRenderingContext2D
}
}
+// We add a guard to each of methods by the spec:
+// http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas_CR/
+//
+// > Except where otherwise specified, for the 2D context interface,
+// > any method call with a numeric argument whose value is infinite or a NaN value must be ignored.
+//
+// Restricted values are guarded in glue code. Therefore we need not add a guard.
+//
+// FIXME: this behavior should might be generated by some annotattions to idl.
impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> {
fn Canvas(self) -> Temporary<HTMLCanvasElement> {
Temporary::new(self.canvas)
}
fn Scale(self, x: f64, y: f64) {
+ if !(x.is_finite() && y.is_finite()) {
+ return;
+ }
+
self.transform.set(self.transform.get().scale(x as f32, y as f32));
self.update_transform()
}
fn Translate(self, x: f64, y: f64) {
+ if !(x.is_finite() && y.is_finite()) {
+ return;
+ }
+
self.transform.set(self.transform.get().translate(x as f32, y as f32));
self.update_transform()
}
fn Transform(self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
+ if !(a.is_finite() && b.is_finite() && c.is_finite() &&
+ d.is_finite() && e.is_finite() && f.is_finite()) {
+ return;
+ }
+
self.transform.set(self.transform.get().mul(&Matrix2D::new(a as f32,
b as f32,
c as f32,
@@ -233,6 +255,11 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
}
fn SetTransform(self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
+ if !(a.is_finite() && b.is_finite() && c.is_finite() &&
+ d.is_finite() && e.is_finite() && f.is_finite()) {
+ return;
+ }
+
self.transform.set(Matrix2D::new(a as f32,
b as f32,
c as f32,
@@ -243,16 +270,31 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
}
fn FillRect(self, x: f64, y: f64, width: f64, height: f64) {
+ if !(x.is_finite() && y.is_finite() &&
+ width.is_finite() && height.is_finite()) {
+ return;
+ }
+
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
self.renderer.send(CanvasMsg::FillRect(rect)).unwrap();
}
fn ClearRect(self, x: f64, y: f64, width: f64, height: f64) {
+ if !(x.is_finite() && y.is_finite() &&
+ width.is_finite() && height.is_finite()) {
+ return;
+ }
+
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
self.renderer.send(CanvasMsg::ClearRect(rect)).unwrap();
}
fn StrokeRect(self, x: f64, y: f64, width: f64, height: f64) {
+ if !(x.is_finite() && y.is_finite() &&
+ width.is_finite() && height.is_finite()) {
+ return;
+ }
+
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
self.renderer.send(CanvasMsg::StrokeRect(rect)).unwrap();
}
@@ -272,6 +314,9 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
// https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage
fn DrawImage(self, image: HTMLCanvasElementOrCanvasRenderingContext2D,
dx: f64, dy: f64) -> Fallible<()> {
+ if !(dx.is_finite() && dy.is_finite()) {
+ return Ok(());
+ }
// From rules described in the spec:
// If the sx, sy, sw, and sh arguments are omitted, they must default to 0, 0,
@@ -311,6 +356,10 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
// https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage
fn DrawImage_(self, image: HTMLCanvasElementOrCanvasRenderingContext2D,
dx: f64, dy: f64, dw: f64, dh: f64) -> Fallible<()> {
+ if !(dx.is_finite() && dy.is_finite() &&
+ dw.is_finite() && dh.is_finite()) {
+ return Ok(());
+ }
// From rules described in the spec:
// If the sx, sy, sw, and sh arguments are omitted, they must default to 0, 0,
@@ -347,6 +396,11 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
fn DrawImage__(self, image: HTMLCanvasElementOrCanvasRenderingContext2D,
sx: f64, sy: f64, sw: f64, sh: f64,
dx: f64, dy: f64, dw: f64, dh: f64) -> Fallible<()> {
+ if !(sx.is_finite() && sy.is_finite() && sw.is_finite() && sh.is_finite() &&
+ dx.is_finite() && dy.is_finite() && dw.is_finite() && dh.is_finite()) {
+ return Ok(());
+ }
+
match image {
HTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(image) => {
let canvas = image.root();
@@ -366,19 +420,37 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
}
fn MoveTo(self, x: f64, y: f64) {
+ if !(x.is_finite() && y.is_finite()) {
+ return;
+ }
+
self.renderer.send(CanvasMsg::MoveTo(Point2D(x as f32, y as f32))).unwrap();
}
fn LineTo(self, x: f64, y: f64) {
+ if !(x.is_finite() && y.is_finite()) {
+ return;
+ }
+
self.renderer.send(CanvasMsg::LineTo(Point2D(x as f32, y as f32))).unwrap();
}
fn QuadraticCurveTo(self, cpx: f64, cpy: f64, x: f64, y: f64) {
+ if !(cpx.is_finite() && cpy.is_finite() &&
+ x.is_finite() && y.is_finite()) {
+ return;
+ }
+
self.renderer.send(CanvasMsg::QuadraticCurveTo(Point2D(cpx as f32, cpy as f32),
Point2D(x as f32, y as f32))).unwrap();
}
fn BezierCurveTo(self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, x: f64, y: f64) {
+ if !(cp1x.is_finite() && cp1y.is_finite() && cp2x.is_finite() && cp2y.is_finite() &&
+ x.is_finite() && y.is_finite()) {
+ return;
+ }
+
self.renderer.send(CanvasMsg::BezierCurveTo(Point2D(cp1x as f32, cp1y as f32),
Point2D(cp2x as f32, cp2y as f32),
Point2D(x as f32, y as f32))).unwrap();
@@ -463,6 +535,10 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
}
fn CreateImageData(self, sw: f64, sh: f64) -> Fallible<Temporary<ImageData>> {
+ if !(sw.is_finite() && sh.is_finite()) {
+ return Err(NotSupported);
+ }
+
if sw == 0.0 || sh == 0.0 {
return Err(IndexSize)
}
@@ -491,6 +567,12 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
}
fn PutImageData(self, imagedata: JSRef<ImageData>, dx: Finite<f64>, dy: Finite<f64>) {
+ // XXX:
+ // By the spec: http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas_CR/#dom-context-2d-putimagedata
+ // "If any of the arguments to the method are infinite or NaN, the method must throw a NotSupportedError exception"
+ // But this arguments are stricted value, so if they are not finite values,
+ // they will be TypeError by WebIDL spec before call this methods.
+
let data = imagedata.get_data_array(&self.global.root().r());
let image_data_rect = Rect(Point2D(dx.to_i32().unwrap(), dy.to_i32().unwrap()), imagedata.get_size());
let dirty_rect = None;
@@ -499,6 +581,12 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
fn PutImageData_(self, imagedata: JSRef<ImageData>, dx: Finite<f64>, dy: Finite<f64>,
dirtyX: Finite<f64>, dirtyY: Finite<f64>, dirtyWidth: Finite<f64>, dirtyHeight: Finite<f64>) {
+ // XXX:
+ // By the spec: http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas_CR/#dom-context-2d-putimagedata
+ // "If any of the arguments to the method are infinite or NaN, the method must throw a NotSupportedError exception"
+ // But this arguments are stricted value, so if they are not finite values,
+ // they will be TypeError by WebIDL spec before call this methods.
+
let data = imagedata.get_data_array(&self.global.root().r());
let image_data_rect = Rect(Point2D(dx.to_i32().unwrap(), dy.to_i32().unwrap()),
Size2D(imagedata.Width().to_i32().unwrap(),