Bug 1313541 - Fix compressedTexImage size validation. - r=ethlin draft
authorJeff Gilbert (:jgilbert) <jgilbert@mozilla.com>
Thu, 27 Oct 2016 19:03:20 -0700
changeset 431873 43c067c77e6190e141c0bf3a040c600ce51270f3
parent 431872 456ce2ae8b85a88c6972000caed6cda5ed387419
child 535492 8a70862c52d3d4051c8c68944eb8f80e35e344d8
push id34137
push userbmo:jgilbert@mozilla.com
push dateMon, 31 Oct 2016 21:58:43 +0000
reviewersethlin
bugs1313541
milestone52.0a1
Bug 1313541 - Fix compressedTexImage size validation. - r=ethlin MozReview-Commit-ID: 4o83xIMyYMD
dom/canvas/WebGL2Context.h
dom/canvas/WebGLContext.h
dom/canvas/WebGLTextureUpload.cpp
--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -111,34 +111,36 @@ protected:
                     GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
 
     ////////////////////////////////////
 
 public:
     template<typename T>
     void CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat,
                               GLsizei width, GLsizei height, GLsizei depth, GLint border,
-                              const T& anySrc, GLuint viewElemOffset = 0)
+                              const T& anySrc, GLuint viewElemOffset = 0,
+                              GLuint viewElemLengthOverride = 0)
     {
         const char funcName[] = "compressedTexImage3D";
         const uint8_t funcDims = 3;
-        const TexImageSourceAdapter src(anySrc, viewElemOffset);
+        const TexImageSourceAdapter src(anySrc, viewElemOffset, viewElemLengthOverride);
         CompressedTexImage(funcName, funcDims, target, level, internalFormat, width,
                            height, depth, border, src);
     }
 
     template<typename T>
     void CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
                                  GLint zOffset, GLsizei width, GLsizei height,
                                  GLsizei depth, GLenum unpackFormat, const T& anySrc,
-                                 GLuint viewElemOffset = 0)
+                                 GLuint viewElemOffset = 0,
+                                 GLuint viewElemLengthOverride = 0)
     {
         const char funcName[] = "compressedTexSubImage3D";
         const uint8_t funcDims = 3;
-        const TexImageSourceAdapter src(anySrc, viewElemOffset);
+        const TexImageSourceAdapter src(anySrc, viewElemOffset, viewElemLengthOverride);
         CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset,
                               zOffset, width, height, depth, unpackFormat, src);
     }
 
     ////////////////////////////////////
 
     void CopyTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
                            GLint zOffset, GLint x, GLint y, GLsizei width,
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -196,16 +196,17 @@ struct IndexedBufferBinding
 };
 
 ////////////////////////////////////
 
 struct TexImageSource
 {
     const dom::ArrayBufferView* mView;
     GLuint mViewElemOffset;
+    GLuint mViewElemLengthOverride;
 
     const WebGLsizeiptr* mPboOffset;
 
     const dom::ImageData* mImageData;
 
     const dom::Element* mDomElem;
     ErrorResult* mOut_error;
 
@@ -226,23 +227,29 @@ struct TexImageSourceAdapter final : pub
             mView = &(maybeView.Value());
         }
     }
 
     TexImageSourceAdapter(const dom::ArrayBufferView& view, ErrorResult*) {
         mView = &view;
     }
 
-    TexImageSourceAdapter(const dom::ArrayBufferView& view, GLuint viewElemOffset) {
+    TexImageSourceAdapter(const dom::ArrayBufferView& view, GLuint viewElemOffset,
+                          GLuint viewElemLengthOverride = 0)
+    {
         mView = &view;
         mViewElemOffset = viewElemOffset;
+        mViewElemLengthOverride = viewElemLengthOverride;
     }
 
-    template<typename ignoredT>
-    TexImageSourceAdapter(WebGLsizeiptr pboOffset, ignoredT) {
+    TexImageSourceAdapter(WebGLsizeiptr pboOffset, GLuint ignored1, GLuint ignored2 = 0) {
+        mPboOffset = &pboOffset;
+    }
+
+    TexImageSourceAdapter(WebGLsizeiptr pboOffset, ErrorResult* ignored) {
         mPboOffset = &pboOffset;
     }
 
     TexImageSourceAdapter(const dom::ImageData& imageData, ErrorResult*) {
         mImageData = &imageData;
     }
 
     TexImageSourceAdapter(const dom::Element& domElem, ErrorResult* const out_error) {
@@ -995,36 +1002,38 @@ protected:
     virtual bool IsTexParamValid(GLenum pname) const;
 
     ////////////////////////////////////
 
 public:
     template<typename T>
     void CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat,
                               GLsizei width, GLsizei height, GLint border,
-                              const T& anySrc, GLuint viewElemOffset = 0)
+                              const T& anySrc, GLuint viewElemOffset = 0,
+                              GLuint viewElemLengthOverride = 0)
     {
         const char funcName[] = "compressedTexImage2D";
         const uint8_t funcDims = 2;
         const GLsizei depth = 1;
-        const TexImageSourceAdapter src(anySrc, viewElemOffset);
+        const TexImageSourceAdapter src(anySrc, viewElemOffset, viewElemLengthOverride);
         CompressedTexImage(funcName, funcDims, target, level, internalFormat, width,
                            height, depth, border, src);
     }
 
     template<typename T>
     void CompressedTexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
                                  GLsizei width, GLsizei height, GLenum unpackFormat,
-                                 const T& anySrc, GLuint viewElemOffset = 0)
+                                 const T& anySrc, GLuint viewElemOffset = 0,
+                                 GLuint viewElemLengthOverride = 0)
     {
         const char funcName[] = "compressedTexSubImage2D";
         const uint8_t funcDims = 2;
         const GLint zOffset = 0;
         const GLsizei depth = 1;
-        const TexImageSourceAdapter src(anySrc, viewElemOffset);
+        const TexImageSourceAdapter src(anySrc, viewElemOffset, viewElemLengthOverride);
         CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset,
                               zOffset, width, height, depth, unpackFormat, src);
     }
 
 protected:
     void CompressedTexImage(const char* funcName, uint8_t funcDims, GLenum target,
                             GLint level, GLenum internalFormat, GLsizei width,
                             GLsizei height, GLsizei depth, GLint border,
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -159,23 +159,25 @@ ValidateUnpackInfo(WebGLContext* webgl, 
     return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 static UniquePtr<webgl::TexUnpackBytes>
 FromView(WebGLContext* webgl, const char* funcName, TexImageTarget target,
          uint32_t width, uint32_t height, uint32_t depth,
-         const dom::ArrayBufferView* view, GLuint viewElemOffset)
+         const dom::ArrayBufferView* view, GLuint viewElemOffset,
+         GLuint viewElemLengthOverride)
 {
     const bool isClientData = true;
     const uint8_t* bytes = nullptr;
     size_t availByteCount = 0;
     if (view) {
-        if (!webgl->ValidateArrayBufferView(funcName, *view, viewElemOffset, 0,
+        if (!webgl->ValidateArrayBufferView(funcName, *view, viewElemOffset,
+                                            viewElemLengthOverride,
                                             const_cast<uint8_t**>(&bytes),
                                             &availByteCount))
         {
             return nullptr;
         }
     }
     return MakeUnique<webgl::TexUnpackBytes>(webgl, target, width, height, depth,
                                              isClientData, bytes, availByteCount);
@@ -392,17 +394,17 @@ WebGLContext::From(const char* funcName,
     }
 
     if (src.mDomElem) {
         return FromDomElem(funcName, target, width, height, depth, *(src.mDomElem),
                            src.mOut_error);
     }
 
     return FromView(this, funcName, target, width, height, depth, src.mView,
-                    src.mViewElemOffset);
+                    src.mViewElemOffset, src.mViewElemLengthOverride);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 static UniquePtr<webgl::TexUnpackBlob>
 ValidateTexOrSubImage(WebGLContext* webgl, const char* funcName, TexImageTarget target,
                       GLsizei rawWidth, GLsizei rawHeight, GLsizei rawDepth,
                       GLint border, const webgl::PackingInfo& pi,
@@ -1380,17 +1382,17 @@ WebGLContext::FromCompressed(const char*
     }
 
     if (mBoundPixelUnpackBuffer) {
         ErrorInvalidOperation("%s: PACK_BUFFER must be null.", funcName);
         return nullptr;
     }
 
     return FromView(this, funcName, target, width, height, depth, src.mView,
-                    src.mViewElemOffset);
+                    src.mViewElemOffset, src.mViewElemLengthOverride);
 }
 
 void
 WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GLint level,
                                  GLenum internalFormat, GLsizei rawWidth,
                                  GLsizei rawHeight, GLsizei rawDepth, GLint border,
                                  const TexImageSource& src)
 {