diff options
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/bindings/conversions.rs | 2 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 148 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGLRenderingContext.webidl | 29 |
3 files changed, 102 insertions, 77 deletions
diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index 55c3c41f460..0b050a4fc64 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -535,6 +535,8 @@ unsafe impl ArrayBufferViewContents for f64 { /// Returns a mutable slice of the Array Buffer View data, viewed as T, without checking the real /// type of it. pub unsafe fn array_buffer_view_data<'a, T: ArrayBufferViewContents>(abv: *mut JSObject) -> Option<&'a mut [T]> { + assert!(!abv.is_null()); + let mut byte_length = 0; let mut ptr = ptr::null_mut(); let mut is_shared = false; diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 312357fd3d2..0b285ba21be 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -390,12 +390,12 @@ impl WebGLRenderingContext { // TODO(emilio): Move this logic to a validator. #[allow(unsafe_code)] - fn validate_tex_image_2d_data(&self, + unsafe fn validate_tex_image_2d_data(&self, width: u32, height: u32, format: TexFormat, data_type: TexDataType, - data: Option<*mut JSObject>) + data: *mut JSObject) -> Result<u32, ()> { let element_size = data_type.element_size(); let components_per_element = data_type.components_per_element(); @@ -407,17 +407,17 @@ impl WebGLRenderingContext { // if it is UNSIGNED_SHORT_5_6_5, UNSIGNED_SHORT_4_4_4_4, // or UNSIGNED_SHORT_5_5_5_1, a Uint16Array must be supplied. // If the types do not match, an INVALID_OPERATION error is generated. - let received_size = if let Some(data) = data { - if unsafe { array_buffer_view_data_checked::<u16>(data).is_some() } { + let received_size = if data.is_null() { + element_size + } else { + if array_buffer_view_data_checked::<u16>(data).is_some() { 2 - } else if unsafe { array_buffer_view_data_checked::<u8>(data).is_some() } { + } else if array_buffer_view_data_checked::<u8>(data).is_some() { 1 } else { self.webgl_error(InvalidOperation); return Err(()); } - } else { - element_size }; if received_size != element_size { @@ -571,7 +571,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { receiver.recv().unwrap() } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 fn GetBufferParameter(&self, _cx: *mut JSContext, target: u32, parameter: u32) -> JSVal { let (sender, receiver) = ipc::channel().unwrap(); @@ -845,7 +844,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn BufferData(&self, _cx: *mut JSContext, target: u32, data: Option<*mut JSObject>, usage: u32) { + fn BufferData(&self, _cx: *mut JSContext, target: u32, data: *mut JSObject, usage: u32) { let bound_buffer = match target { constants::ARRAY_BUFFER => self.bound_buffer_array.get(), constants::ELEMENT_ARRAY_BUFFER => self.bound_buffer_element_array.get(), @@ -864,40 +863,37 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { _ => return self.webgl_error(InvalidEnum), } - let data = match data { - Some(data) => data, - None => return self.webgl_error(InvalidValue), - }; - if let Some(data_vec) = array_buffer_view_to_vec::<u8>(data) { handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, &data_vec, usage)); } else { - // NB: array_buffer_view_to_vec should never fail when - // we have WebIDL support for Float32Array etc. + // NB: array_buffer_view_to_vec should never fail when we have + // WebIDL support for Float32Array etc. self.webgl_error(InvalidValue); } } #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn BufferSubData(&self, _cx: *mut JSContext, target: u32, offset: i64, data: Option<*mut JSObject>) { + fn BufferSubData(&self, _cx: *mut JSContext, target: u32, offset: i64, data: *mut JSObject) { let bound_buffer = match target { constants::ARRAY_BUFFER => self.bound_buffer_array.get(), constants::ELEMENT_ARRAY_BUFFER => self.bound_buffer_element_array.get(), _ => return self.webgl_error(InvalidEnum), }; + let bound_buffer = match bound_buffer { Some(bound_buffer) => bound_buffer, None => return self.webgl_error(InvalidOperation), }; - let data = match data { - Some(data) => data, - None => return self.webgl_error(InvalidValue), - }; + + if data.is_null() { + return self.webgl_error(InvalidValue); + } if offset < 0 { return self.webgl_error(InvalidValue); } + if let Some(data_vec) = array_buffer_view_to_vec::<u8>(data) { if (offset as usize) + data_vec.len() > bound_buffer.capacity() { return self.webgl_error(InvalidValue); @@ -906,6 +902,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { .send(CanvasMsg::WebGL(WebGLCommand::BufferSubData(target, offset as isize, data_vec))) .unwrap() } else { + // NB: array_buffer_view_to_vec should never fail when we have + // WebIDL support for Float32Array etc. self.webgl_error(InvalidValue); } } @@ -1653,6 +1651,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 fn ReadPixels(&self, _cx: *mut JSContext, x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32, pixels: *mut JSObject) { + if pixels.is_null() { + return self.webgl_error(InvalidValue); + } + let mut data = match unsafe { array_buffer_view_data::<u8>(pixels) } { Some(data) => data, None => return self.webgl_error(InvalidValue), @@ -1819,11 +1821,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 + #[allow(unsafe_code)] fn Uniform1iv(&self, _cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, - data: Option<*mut JSObject>) { - let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d)); + data: *mut JSObject) { + assert!(!data.is_null()); + let data_vec = unsafe { array_buffer_view_to_vec::<i32>(data) }; + if self.validate_uniform_parameters(uniform, UniformSetterType::Int, data_vec.as_ref().map(Vec::as_slice)) { self.ipc_renderer .send(CanvasMsg::WebGL(WebGLCommand::Uniform1iv(uniform.unwrap().id(), data_vec.unwrap()))) @@ -1832,11 +1837,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 + #[allow(unsafe_code)] fn Uniform1fv(&self, _cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, - data: Option<*mut JSObject>) { - let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d)); + data: *mut JSObject) { + assert!(!data.is_null()); + let data_vec = unsafe { array_buffer_view_to_vec::<f32>(data) }; + if self.validate_uniform_parameters(uniform, UniformSetterType::Float, data_vec.as_ref().map(Vec::as_slice)) { self.ipc_renderer .send(CanvasMsg::WebGL(WebGLCommand::Uniform1fv(uniform.unwrap().id(), data_vec.unwrap()))) @@ -1856,11 +1864,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 + #[allow(unsafe_code)] fn Uniform2fv(&self, _cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, - data: Option<*mut JSObject>) { - let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d)); + data: *mut JSObject) { + assert!(!data.is_null()); + let data_vec = unsafe { array_buffer_view_to_vec::<f32>(data) }; if self.validate_uniform_parameters(uniform, UniformSetterType::FloatVec2, data_vec.as_ref().map(Vec::as_slice)) { @@ -1884,11 +1894,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 + #[allow(unsafe_code)] fn Uniform2iv(&self, _cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, - data: Option<*mut JSObject>) { - let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d)); + data: *mut JSObject) { + assert!(!data.is_null()); + let data_vec = unsafe { array_buffer_view_to_vec::<i32>(data) }; + if self.validate_uniform_parameters(uniform, UniformSetterType::IntVec2, data_vec.as_ref().map(Vec::as_slice)) { @@ -1912,11 +1925,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 + #[allow(unsafe_code)] fn Uniform3fv(&self, _cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, - data: Option<*mut JSObject>) { - let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d)); + data: *mut JSObject) { + assert!(!data.is_null()); + let data_vec = unsafe { array_buffer_view_to_vec::<f32>(data) }; + if self.validate_uniform_parameters(uniform, UniformSetterType::FloatVec3, data_vec.as_ref().map(Vec::as_slice)) { @@ -1940,11 +1956,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 + #[allow(unsafe_code)] fn Uniform3iv(&self, _cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, - data: Option<*mut JSObject>) { - let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d)); + data: *mut JSObject) { + assert!(!data.is_null()); + let data_vec = unsafe { array_buffer_view_to_vec::<i32>(data) }; + if self.validate_uniform_parameters(uniform, UniformSetterType::IntVec3, data_vec.as_ref().map(Vec::as_slice)) { @@ -1969,11 +1988,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 + #[allow(unsafe_code)] fn Uniform4iv(&self, _cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, - data: Option<*mut JSObject>) { - let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d)); + data: *mut JSObject) { + assert!(!data.is_null()); + let data_vec = unsafe { array_buffer_view_to_vec::<i32>(data) }; + if self.validate_uniform_parameters(uniform, UniformSetterType::IntVec4, data_vec.as_ref().map(Vec::as_slice)) { @@ -1997,11 +2019,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 + #[allow(unsafe_code)] fn Uniform4fv(&self, _cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, - data: Option<*mut JSObject>) { - let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d)); + data: *mut JSObject) { + assert!(!data.is_null()); + let data_vec = unsafe { array_buffer_view_to_vec::<f32>(data) }; + if self.validate_uniform_parameters(uniform, UniformSetterType::FloatVec4, data_vec.as_ref().map(Vec::as_slice)) { @@ -2069,7 +2094,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self.vertex_attrib(indx, x, y, z, 1f32) } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib3fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) { @@ -2152,6 +2176,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + #[allow(unsafe_code)] fn TexImage2D(&self, _cx: *mut JSContext, target: u32, @@ -2162,7 +2187,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { border: i32, format: u32, data_type: u32, - data: Option<*mut JSObject>) { + data: *mut JSObject) { let validator = TexImage2DValidator::new(self, target, level, internal_format, width, height, border, format, data_type); @@ -2181,22 +2206,21 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { Err(_) => return, // NB: The validator sets the correct error for us. }; - let expected_byte_length = match self.validate_tex_image_2d_data(width, - height, - format, - data_type, - data) { - Ok(byte_length) => byte_length, - Err(_) => return, - }; + let expected_byte_length = + match unsafe { self.validate_tex_image_2d_data(width, height, + format, data_type, + data) } { + Ok(byte_length) => byte_length, + Err(_) => return, + }; // If data is null, a buffer of sufficient size // initialized to 0 is passed. - let buff = if let Some(data) = data { + let buff = if data.is_null() { + vec![0u8; expected_byte_length as usize] + } else { array_buffer_view_to_vec::<u8>(data) .expect("Can't reach here without being an ArrayBufferView!") - } else { - vec![0u8; expected_byte_length as usize] }; if buff.len() != expected_byte_length as usize { @@ -2246,6 +2270,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + #[allow(unsafe_code)] fn TexSubImage2D(&self, _cx: *mut JSContext, target: u32, @@ -2256,7 +2281,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { height: i32, format: u32, data_type: u32, - data: Option<*mut JSObject>) { + data: *mut JSObject) { let validator = TexImage2DValidator::new(self, target, level, format, width, height, 0, format, data_type); @@ -2274,22 +2299,21 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { Err(_) => return, // NB: The validator sets the correct error for us. }; - let expected_byte_length = match self.validate_tex_image_2d_data(width, - height, - format, - data_type, - data) { - Ok(byte_length) => byte_length, - Err(()) => return, - }; + let expected_byte_length = + match unsafe { self.validate_tex_image_2d_data(width, height, + format, data_type, + data) } { + Ok(byte_length) => byte_length, + Err(()) => return, + }; // If data is null, a buffer of sufficient size // initialized to 0 is passed. - let buff = if let Some(data) = data { + let buff = if data.is_null() { + vec![0u8; expected_byte_length as usize] + } else { array_buffer_view_to_vec::<u8>(data) .expect("Can't reach here without being an ArrayBufferView!") - } else { - vec![0u8; expected_byte_length as usize] }; if expected_byte_length != 0 && diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl index 19e5f029168..dcc7a1a8bea 100644 --- a/components/script/dom/webidls/WebGLRenderingContext.webidl +++ b/components/script/dom/webidls/WebGLRenderingContext.webidl @@ -492,11 +492,11 @@ interface WebGLRenderingContextBase //void bufferData(GLenum target, GLsizeiptr size, GLenum usage); // FIXME(dmarcos) The function below is the original function in the webIdl: // void bufferData(GLenum target, BufferDataSource? data, GLenum usage); - // The Code generator doesn't handle BufferDataSource so we're using 'optional object' + // The Code generator doesn't handle BufferDataSource so we're using 'object?' // in the meantime - void bufferData(GLenum target, optional object data, GLenum usage); + void bufferData(GLenum target, object? data, GLenum usage); //void bufferSubData(GLenum target, GLintptr offset, BufferDataSource? data); - void bufferSubData(GLenum target, GLintptr offset, optional object data); + void bufferSubData(GLenum target, GLintptr offset, object? data); //[WebGLHandlesContextLoss] GLenum checkFramebufferStatus(GLenum target); void clear(GLbitfield mask); @@ -639,7 +639,7 @@ interface WebGLRenderingContextBase // FIXME: SM interface arguments void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, - GLenum type, optional object data); + GLenum type, object? data); void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, TexImageSource? source); // May throw DOMException @@ -648,47 +648,46 @@ interface WebGLRenderingContextBase void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLenum type, optional object data); + GLenum format, GLenum type, object? data); void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, TexImageSource? source); // May throw DOMException void uniform1f(WebGLUniformLocation? location, GLfloat x); //void uniform1fv(WebGLUniformLocation? location, Float32Array v); //void uniform1fv(WebGLUniformLocation? location, sequence<GLfloat> v); - void uniform1fv(WebGLUniformLocation? location, optional object v); + void uniform1fv(WebGLUniformLocation? location, object v); void uniform1i(WebGLUniformLocation? location, GLint x); //void uniform1iv(WebGLUniformLocation? location, Int32Array v); //void uniform1iv(WebGLUniformLocation? location, sequence<long> v); - void uniform1iv(WebGLUniformLocation? location, optional object v); + void uniform1iv(WebGLUniformLocation? location, object v); void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y); //void uniform2fv(WebGLUniformLocation? location, Float32Array v); //void uniform2fv(WebGLUniformLocation? location, sequence<GLfloat> v); - void uniform2fv(WebGLUniformLocation? location, optional object v); + void uniform2fv(WebGLUniformLocation? location, object v); //void uniform2i(WebGLUniformLocation? location, GLint x, GLint y); void uniform2i(WebGLUniformLocation? location, GLint x, GLint y); //void uniform2iv(WebGLUniformLocation? location, Int32Array v); //void uniform2iv(WebGLUniformLocation? location, sequence<long> v); - void uniform2iv(WebGLUniformLocation? location, optional object v); + void uniform2iv(WebGLUniformLocation? location, object v); void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z); - void uniform3fv(WebGLUniformLocation? location, optional object v); + void uniform3fv(WebGLUniformLocation? location, object v); //void uniform3fv(WebGLUniformLocation? location, Float32Array v); //void uniform3fv(WebGLUniformLocation? location, sequence<GLfloat> v); void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z); //void uniform3iv(WebGLUniformLocation? location, Int32Array v); //void uniform3iv(WebGLUniformLocation? location, sequence<long> v); - void uniform3iv(WebGLUniformLocation? location, optional object v); + void uniform3iv(WebGLUniformLocation? location, object v); void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); // FIXME(dmarcos) The function below is the original function in the webIdl: //void uniform4fv(WebGLUniformLocation? location, Float32Array v); - // The Code genearator doesn't handle BufferDataSource so we're using 'optional object' - // in the meantime - void uniform4fv(WebGLUniformLocation? location, optional object v); + // The Code genearator doesn't handle typed arrays, so we use object instead. + void uniform4fv(WebGLUniformLocation? location, object v); //void uniform4fv(WebGLUniformLocation? location, sequence<GLfloat> v); void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w); //void uniform4iv(WebGLUniformLocation? location, Int32Array v); //void uniform4iv(WebGLUniformLocation? location, sequence<long> v); // See FIXME above - void uniform4iv(WebGLUniformLocation? location, optional object v); + void uniform4iv(WebGLUniformLocation? location, object v); //void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, // Float32Array value); |