Auto merge of #24275 - iinuwa:bugfix/24274, r=jdm

Add check for empty data on ImageData constructor.

<!-- Please describe your changes on the following line: -->
This commit implements the nonzero check for ImageData::new_with_jsobject() according to the ImageData spec.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #24274 (GitHub issue number if applicable)

<!-- Either: -->
- [X] There are tests for these changes OR
- [ ] These changes do not require tests because ___

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/24275)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2019-09-26 16:05:00 -04:00 committed by GitHub
commit 5fd4467cb3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 57 deletions

View file

@ -42,15 +42,14 @@ impl ImageData {
unsafe {
let cx = global.get_cx();
rooted!(in (*cx) let mut js_object = ptr::null_mut::<JSObject>());
let data = match data {
Some(ref mut d) => {
d.resize(len as usize, 0);
CreateWith::Slice(&d[..])
},
None => CreateWith::Length(len),
};
Uint8ClampedArray::create(*cx, data, js_object.handle_mut()).unwrap();
Self::new_with_jsobject(global, width, Some(height), Some(js_object.get()))
if let Some(ref mut d) = data {
d.resize(len as usize, 0);
let data = CreateWith::Slice(&d[..]);
Uint8ClampedArray::create(*cx, data, js_object.handle_mut()).unwrap();
Self::new_with_jsobject(global, width, Some(height), js_object.get())
} else {
Self::new_without_jsobject(global, width, height)
}
}
}
@ -58,43 +57,28 @@ impl ImageData {
unsafe fn new_with_jsobject(
global: &GlobalScope,
width: u32,
mut opt_height: Option<u32>,
opt_jsobject: Option<*mut JSObject>,
opt_height: Option<u32>,
jsobject: *mut JSObject,
) -> Fallible<DomRoot<ImageData>> {
assert!(opt_jsobject.is_some() || opt_height.is_some());
// checking jsobject type
let cx = global.get_cx();
typedarray!(in(*cx) let array_res: Uint8ClampedArray = jsobject);
let array = array_res.map_err(|_| {
Error::Type("Argument to Image data is not an Uint8ClampedArray".to_owned())
})?;
if width == 0 {
let byte_len = array.as_slice().len() as u32;
if byte_len == 0 || byte_len % 4 != 0 {
return Err(Error::InvalidState);
}
let len = byte_len / 4;
if width == 0 || len % width != 0 {
return Err(Error::IndexSize);
}
// checking jsobject type and verifying (height * width * 4 == jsobject.byte_len())
if let Some(jsobject) = opt_jsobject {
let cx = global.get_cx();
typedarray!(in(*cx) let array_res: Uint8ClampedArray = jsobject);
let array = array_res.map_err(|_| {
Error::Type("Argument to Image data is not an Uint8ClampedArray".to_owned())
})?;
let byte_len = array.as_slice().len() as u32;
if byte_len % 4 != 0 {
return Err(Error::InvalidState);
}
let len = byte_len / 4;
if width == 0 || len % width != 0 {
return Err(Error::IndexSize);
}
let height = len / width;
if opt_height.map_or(false, |x| height != x) {
return Err(Error::IndexSize);
} else {
opt_height = Some(height);
}
}
let height = opt_height.unwrap();
if height == 0 {
let height = len / width;
if opt_height.map_or(false, |x| height != x) {
return Err(Error::IndexSize);
}
@ -105,15 +89,7 @@ impl ImageData {
data: Heap::default(),
});
if let Some(jsobject) = opt_jsobject {
(*imagedata).data.set(jsobject);
} else {
let len = width * height * 4;
let cx = global.get_cx();
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
Uint8ClampedArray::create(*cx, CreateWith::Length(len), array.handle_mut()).unwrap();
(*imagedata).data.set(array.get());
}
(*imagedata).data.set(jsobject);
Ok(reflect_dom_object(
imagedata,
@ -122,10 +98,39 @@ impl ImageData {
))
}
#[allow(unsafe_code)]
unsafe fn new_without_jsobject(
global: &GlobalScope,
width: u32,
height: u32,
) -> Fallible<DomRoot<ImageData>> {
if width == 0 || height == 0 {
return Err(Error::IndexSize);
}
let imagedata = Box::new(ImageData {
reflector_: Reflector::new(),
width: width,
height: height,
data: Heap::default(),
});
let len = width * height * 4;
let cx = global.get_cx();
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
Uint8ClampedArray::create(*cx, CreateWith::Length(len), array.handle_mut()).unwrap();
(*imagedata).data.set(array.get());
Ok(reflect_dom_object(
imagedata,
global,
ImageDataBinding::Wrap,
))
}
// https://html.spec.whatwg.org/multipage/#pixel-manipulation:dom-imagedata-3
#[allow(unsafe_code)]
pub fn Constructor(global: &GlobalScope, width: u32, height: u32) -> Fallible<DomRoot<Self>> {
unsafe { Self::new_with_jsobject(global, width, Some(height), None) }
unsafe { Self::new_without_jsobject(global, width, height) }
}
// https://html.spec.whatwg.org/multipage/#pixel-manipulation:dom-imagedata-4
@ -138,7 +143,7 @@ impl ImageData {
width: u32,
opt_height: Option<u32>,
) -> Fallible<DomRoot<Self>> {
Self::new_with_jsobject(global, width, opt_height, Some(jsobject))
Self::new_with_jsobject(global, width, opt_height, jsobject)
}
/// Nothing must change the array on the JS side while the slice is live.