servo: Merge #13898 - webgl: texture size validation fixes (from anholt:webgl-texture-fixes); r=emilio
authorEric Anholt <eric@anholt.net>
Mon, 24 Oct 2016 00:52:57 -0500
changeset 339979 a78d9ea96166158cd703812ea9295cd4c955eea9
parent 339978 6bc685a3f0340c866f34d943f5696e24c6612b6e
child 339980 91e8edaae3c53ec53ae5b9553fc9a56ec523b208
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
servo: Merge #13898 - webgl: texture size validation fixes (from anholt:webgl-texture-fixes); r=emilio <!-- Please describe your changes on the following line: --> This pull request fixes the errors in texture-size-limit.html. --- <!-- 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 - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [X] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: f3973a0d3b2d12c96d0f21624fd0d6d925f34abb
servo/components/script/dom/webgl_validations/tex_image_2d.rs
servo/components/script/dom/webglrenderingcontext.rs
--- a/servo/components/script/dom/webgl_validations/tex_image_2d.rs
+++ b/servo/components/script/dom/webgl_validations/tex_image_2d.rs
@@ -158,28 +158,28 @@ impl<'a> WebGLValidator for CommonTexIma
         }
 
         // GL_INVALID_VALUE is generated if width or height is less than 0
         if self.width < 0 || self.height < 0 {
             self.context.webgl_error(InvalidValue);
             return Err(TexImageValidationError::NegativeDimension);
         }
 
+        let width = self.width as u32;
+        let height = self.height as u32;
+        let level = self.level as u32;
+
         // GL_INVALID_VALUE is generated if width or height is greater than
         // GL_MAX_TEXTURE_SIZE when target is GL_TEXTURE_2D or
         // GL_MAX_CUBE_MAP_TEXTURE_SIZE when target is not GL_TEXTURE_2D.
-        if self.width as u32 > max_size || self.height as u32 > max_size {
+        if width > max_size >> level || height > max_size >> level {
             self.context.webgl_error(InvalidValue);
             return Err(TexImageValidationError::TextureTooBig);
         }
 
-        let width = self.width as u32;
-        let height = self.height as u32;
-        let level = self.level as u32;
-
         // GL_INVALID_VALUE is generated if level is greater than zero and the
         // texture is not power of two.
         if level > 0 && (!width.is_power_of_two() || !height.is_power_of_two()) {
             self.context.webgl_error(InvalidValue);
             return Err(TexImageValidationError::NonPotTexture);
         }
 
         // GL_INVALID_VALUE may be generated if level is greater than
--- a/servo/components/script/dom/webglrenderingcontext.rs
+++ b/servo/components/script/dom/webglrenderingcontext.rs
@@ -2354,17 +2354,23 @@ impl WebGLRenderingContextMethods for We
 
         // If data is null, a buffer of sufficient size
         // initialized to 0 is passed.
         let buff = match data {
             None => vec![0u8; expected_byte_length as usize],
             Some(data) => data,
         };
 
-        if buff.len() != expected_byte_length as usize {
+        // From the WebGL spec:
+        //
+        //     "If pixels is non-null but its size is less than what
+        //      is required by the specified width, height, format,
+        //      type, and pixel storage parameters, generates an
+        //      INVALID_OPERATION error."
+        if buff.len() < expected_byte_length as usize {
             return Ok(self.webgl_error(InvalidOperation));
         }
 
         self.tex_image_2d(texture, target, data_type, format,
                           level, width, height, border, buff);
 
         Ok(())
     }
@@ -2454,18 +2460,23 @@ impl WebGLRenderingContextMethods for We
 
         // If data is null, a buffer of sufficient size
         // initialized to 0 is passed.
         let buff = match data {
             None => vec![0u8; expected_byte_length as usize],
             Some(data) => data,
         };
 
-        if expected_byte_length != 0 &&
-            buff.len() != expected_byte_length as usize {
+        // From the WebGL spec:
+        //
+        //     "If pixels is non-null but its size is less than what
+        //      is required by the specified width, height, format,
+        //      type, and pixel storage parameters, generates an
+        //      INVALID_OPERATION error."
+        if buff.len() < expected_byte_length as usize {
             return Ok(self.webgl_error(InvalidOperation));
         }
 
         self.tex_sub_image_2d(texture, target, level, xoffset, yoffset,
                               width, height, format, data_type, buff);
         Ok(())
     }