Bug 1533525 - Don't freely convert WebGL(int|sizei)ptr to GL(int|sizei)ptr. r=lsalzman
☠☠ backed out by 36570e7c5eb7 ☠ ☠
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 06 Mar 2019 15:52:05 -0800
changeset 468715 bdc40c000b29ba024a7014d3ff5fc31d98e608df
parent 468714 d6bbb316b768e9cfeca7ed89ecd7b52875348063
child 468716 36570e7c5eb7191101d786823427ed70707e5606
push id35846
push userncsoregi@mozilla.com
push dateWed, 10 Apr 2019 10:00:20 +0000
treeherdermozilla-central@a1eb490ba448 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1533525
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1533525 - Don't freely convert WebGL(int|sizei)ptr to GL(int|sizei)ptr. r=lsalzman Differential Revision: https://phabricator.services.mozilla.com/D26631
dom/canvas/WebGL2Context.h
dom/canvas/WebGL2ContextBuffers.cpp
dom/canvas/WebGLBuffer.cpp
dom/canvas/WebGLBuffer.h
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextBuffers.cpp
--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -34,25 +34,26 @@ class WebGL2Context : public WebGLContex
 
   virtual JSObject* WrapObject(JSContext* cx,
                                JS::Handle<JSObject*> givenProto) override;
 
   // -------------------------------------------------------------------------
   // Buffer objects - WebGL2ContextBuffers.cpp
 
   void CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
-                         GLintptr readOffset, GLintptr writeOffset,
-                         GLsizeiptr size);
+                         WebGLintptr readOffset, WebGLintptr writeOffset,
+                         WebGLsizeiptr size);
 
  private:
   template <typename BufferT>
-  void GetBufferSubDataT(GLenum target, GLintptr offset, const BufferT& data);
+  void GetBufferSubDataT(GLenum target, WebGLintptr offset,
+                         const BufferT& data);
 
  public:
-  void GetBufferSubData(GLenum target, GLintptr srcByteOffset,
+  void GetBufferSubData(GLenum target, WebGLintptr srcByteOffset,
                         const dom::ArrayBufferView& dstData,
                         GLuint dstElemOffset, GLuint dstElemCountOverride);
 
   // -------------------------------------------------------------------------
   // Framebuffer objects - WebGL2ContextFramebuffers.cpp
 
   void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
@@ -298,17 +299,17 @@ class WebGL2Context : public WebGLContex
   // -------------------------------------------------------------------------
   // Writing to the drawing buffer
 
   /* Implemented in WebGLContext
   void VertexAttribDivisor(GLuint index, GLuint divisor);
   void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
                            GLsizei instanceCount);
   void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
-                             GLintptr offset, GLsizei instanceCount);
+                             WebGLintptr offset, GLsizei instanceCount);
   */
 
   void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
                          GLenum type, WebGLintptr byteOffset) {
     const FuncScope funcScope(*this, "drawRangeElements");
     if (IsContextLost()) return;
 
     if (end < start) {
@@ -400,17 +401,17 @@ class WebGL2Context : public WebGLContex
 
   // -------------------------------------------------------------------------
   // Uniform Buffer Objects and Transform Feedback Buffers -
   // WebGL2ContextUniforms.cpp
   // TODO(djg): Implemented in WebGLContext
   /*
       void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
       void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
-                           GLintptr offset, GLsizeiptr size);
+                           WebGLintptr offset, WebGLsizeiptr size);
   */
   virtual JS::Value GetParameter(JSContext* cx, GLenum pname,
                                  ErrorResult& rv) override;
   // Make the inline version from the superclass visible here.
   using WebGLContext::GetParameter;
   void GetIndexedParameter(JSContext* cx, GLenum target, GLuint index,
                            JS::MutableHandleValue retval, ErrorResult& rv);
   void GetUniformIndices(const WebGLProgram& program,
--- a/dom/canvas/WebGL2ContextBuffers.cpp
+++ b/dom/canvas/WebGL2ContextBuffers.cpp
@@ -10,52 +10,55 @@
 #include "WebGLTransformFeedback.h"
 
 namespace mozilla {
 
 // -------------------------------------------------------------------------
 // Buffer objects
 
 void WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
-                                      GLintptr readOffset, GLintptr writeOffset,
-                                      GLsizeiptr size) {
+                                      WebGLintptr readOffset,
+                                      WebGLintptr writeOffset,
+                                      WebGLsizeiptr size) {
   const FuncScope funcScope(*this, "copyBufferSubData");
   if (IsContextLost()) return;
 
   const auto& readBuffer = ValidateBufferSelection(readTarget);
   if (!readBuffer) return;
 
   const auto& writeBuffer = ValidateBufferSelection(writeTarget);
   if (!writeBuffer) return;
 
   if (!ValidateNonNegative("readOffset", readOffset) ||
       !ValidateNonNegative("writeOffset", writeOffset) ||
       !ValidateNonNegative("size", size)) {
     return;
   }
 
-  const auto fnValidateOffsetSize = [&](const char* info, GLintptr offset,
+  if (!CheckedInt<GLintptr>(readOffset).isValid() ||
+      !CheckedInt<GLintptr>(writeOffset).isValid() ||
+      !CheckedInt<GLsizeiptr>(size).isValid())
+    return ErrorOutOfMemory("offset or size too large for platform.");
+
+  const auto fnValidateOffsetSize = [&](const char* info, WebGLintptr offset,
                                         const WebGLBuffer* buffer) {
-    const auto neededBytes = CheckedInt<size_t>(offset) + size;
+    const auto neededBytes = CheckedInt<uint64_t>(offset) + size;
     if (!neededBytes.isValid() || neededBytes.value() > buffer->ByteLength()) {
       ErrorInvalidValue("Invalid %s range.", info);
       return false;
     }
     return true;
   };
 
   if (!fnValidateOffsetSize("read", readOffset, readBuffer) ||
       !fnValidateOffsetSize("write", writeOffset, writeBuffer)) {
     return;
   }
 
   if (readBuffer == writeBuffer) {
-    MOZ_ASSERT((CheckedInt<WebGLsizeiptr>(readOffset) + size).isValid());
-    MOZ_ASSERT((CheckedInt<WebGLsizeiptr>(writeOffset) + size).isValid());
-
     const bool separate =
         (readOffset + size <= writeOffset || writeOffset + size <= readOffset);
     if (!separate) {
       ErrorInvalidValue(
           "Ranges [readOffset, readOffset + size) and"
           " [writeOffset, writeOffset + size) overlap.");
       return;
     }
@@ -76,17 +79,17 @@ void WebGL2Context::CopyBufferSubData(GL
   const ScopedLazyBind readBind(gl, readTarget, readBuffer);
   const ScopedLazyBind writeBind(gl, writeTarget, writeBuffer);
   gl->fCopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset,
                          size);
 
   writeBuffer->ResetLastUpdateFenceId();
 }
 
-void WebGL2Context::GetBufferSubData(GLenum target, GLintptr srcByteOffset,
+void WebGL2Context::GetBufferSubData(GLenum target, WebGLintptr srcByteOffset,
                                      const dom::ArrayBufferView& dstData,
                                      GLuint dstElemOffset,
                                      GLuint dstElemCountOverride) {
   const FuncScope funcScope(*this, "getBufferSubData");
   if (IsContextLost()) return;
 
   if (!ValidateNonNegative("srcByteOffset", srcByteOffset)) return;
 
@@ -101,18 +104,19 @@ void WebGL2Context::GetBufferSubData(GLe
 
   const auto& buffer = ValidateBufferSelection(target);
   if (!buffer) return;
 
   if (!buffer->ValidateRange(srcByteOffset, byteLen)) return;
 
   ////
 
-  if (!CheckedInt<GLsizeiptr>(byteLen).isValid()) {
-    ErrorOutOfMemory("Size too large.");
+  if (!CheckedInt<GLintptr>(srcByteOffset).isValid() ||
+      !CheckedInt<GLsizeiptr>(byteLen).isValid()) {
+    ErrorOutOfMemory("offset or size too large for platform.");
     return;
   }
   const GLsizeiptr glByteLen(byteLen);
 
   ////
 
   switch (buffer->mUsage) {
     case LOCAL_GL_STATIC_READ:
--- a/dom/canvas/WebGLBuffer.cpp
+++ b/dom/canvas/WebGLBuffer.cpp
@@ -79,17 +79,17 @@ static bool ValidateBufferUsageEnum(WebG
     default:
       break;
   }
 
   webgl->ErrorInvalidEnumInfo("usage", usage);
   return false;
 }
 
-void WebGLBuffer::BufferData(GLenum target, size_t size, const void* data,
+void WebGLBuffer::BufferData(GLenum target, uint64_t size, const void* data,
                              GLenum usage) {
   // Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
   // is like intptr_t.
   if (!CheckedInt<GLsizeiptr>(size).isValid())
     return mContext->ErrorOutOfMemory("bad size");
 
   if (!ValidateBufferUsageEnum(mContext, usage)) return;
 
@@ -146,22 +146,23 @@ void WebGLBuffer::BufferData(GLenum targ
                                     uint32_t(mIndexRanges.size()));
       mIndexRanges.clear();
     }
   }
 
   ResetLastUpdateFenceId();
 }
 
-void WebGLBuffer::BufferSubData(GLenum target, size_t dstByteOffset,
-                                size_t dataLen, const void* data) const {
+void WebGLBuffer::BufferSubData(GLenum target, uint64_t dstByteOffset,
+                                uint64_t dataLen, const void* data) const {
   if (!ValidateRange(dstByteOffset, dataLen)) return;
 
-  if (!CheckedInt<GLintptr>(dataLen).isValid())
-    return mContext->ErrorOutOfMemory("Size too large.");
+  if (!CheckedInt<GLintptr>(dstByteOffset).isValid() ||
+      !CheckedInt<GLsizeiptr>(dataLen).isValid())
+    return mContext->ErrorOutOfMemory("offset or size too large for platform.");
 
   ////
 
   const void* uploadData = data;
   if (mIndexCache) {
     const auto cachedDataBegin = (uint8_t*)mIndexCache.get() + dstByteOffset;
     memcpy(cachedDataBegin, data, dataLen);
     uploadData = cachedDataBegin;
--- a/dom/canvas/WebGLBuffer.h
+++ b/dom/canvas/WebGLBuffer.h
@@ -44,18 +44,18 @@ class WebGLBuffer final : public nsWrapp
   bool ValidateRange(size_t byteOffset, size_t byteLen) const;
 
   WebGLContext* GetParentObject() const { return mContext; }
 
   virtual JSObject* WrapObject(JSContext* cx,
                                JS::Handle<JSObject*> givenProto) override;
 
   bool ValidateCanBindToTarget(GLenum target);
-  void BufferData(GLenum target, size_t size, const void* data, GLenum usage);
-  void BufferSubData(GLenum target, size_t dstByteOffset, size_t dataLen,
+  void BufferData(GLenum target, uint64_t size, const void* data, GLenum usage);
+  void BufferSubData(GLenum target, uint64_t dstByteOffset, uint64_t dataLen,
                      const void* data) const;
 
   ////
 
   static void AddBindCount(GLenum target, WebGLBuffer* buffer, int8_t addVal) {
     if (!buffer) return;
 
     if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER) {
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -953,31 +953,31 @@ class WebGLContext : public nsICanvasRen
   // -----------------------------------------------------------------------------
   // Buffer Objects (WebGLContextBuffers.cpp)
   void BindBuffer(GLenum target, WebGLBuffer* buffer);
   void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buf);
   void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buf,
                        WebGLintptr offset, WebGLsizeiptr size);
 
  private:
-  void BufferDataImpl(GLenum target, size_t dataLen, const uint8_t* data,
+  void BufferDataImpl(GLenum target, uint64_t dataLen, const uint8_t* data,
                       GLenum usage);
 
  public:
   void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage);
   void BufferData(GLenum target,
                   const dom::Nullable<dom::ArrayBuffer>& maybeSrc,
                   GLenum usage);
   void BufferData(GLenum target, const dom::ArrayBufferView& srcData,
                   GLenum usage, GLuint srcElemOffset = 0,
                   GLuint srcElemCountOverride = 0);
 
  private:
   void BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset,
-                         size_t srcDataLen, const uint8_t* srcData);
+                         uint64_t srcDataLen, const uint8_t* srcData);
 
  public:
   void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
                      const dom::ArrayBufferView& src, GLuint srcElemOffset = 0,
                      GLuint srcElemCountOverride = 0);
   void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
                      const dom::ArrayBuffer& src);
   void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
--- a/dom/canvas/WebGLContextBuffers.cpp
+++ b/dom/canvas/WebGLContextBuffers.cpp
@@ -280,17 +280,17 @@ void WebGLContext::BindBufferRange(GLenu
 
   if (buffer) {
     buffer->SetContentAfterBind(target);
   }
 }
 
 ////////////////////////////////////////
 
-void WebGLContext::BufferDataImpl(GLenum target, size_t dataLen,
+void WebGLContext::BufferDataImpl(GLenum target, uint64_t dataLen,
                                   const uint8_t* data, GLenum usage) {
   const auto& buffer = ValidateBufferSelection(target);
   if (!buffer) return;
 
   buffer->BufferData(target, dataLen, data, usage);
 }
 
 ////
@@ -305,18 +305,18 @@ void WebGLContext::BufferData(GLenum tar
 
   const auto checkedSize = CheckedInt<size_t>(size);
   if (!checkedSize.isValid())
     return ErrorOutOfMemory("size too large for platform.");
 
   const UniqueBuffer zeroBuffer(calloc(checkedSize.value(), 1u));
   if (!zeroBuffer) return ErrorOutOfMemory("Failed to allocate zeros.");
 
-  BufferDataImpl(target, checkedSize.value(), (const uint8_t*)zeroBuffer.get(),
-                 usage);
+  BufferDataImpl(target, uint64_t{checkedSize.value()},
+                 (const uint8_t*)zeroBuffer.get(), usage);
 }
 
 void WebGLContext::BufferData(GLenum target,
                               const dom::Nullable<dom::ArrayBuffer>& maybeSrc,
                               GLenum usage) {
   const FuncScope funcScope(*this, "bufferData");
   if (IsContextLost()) return;
 
@@ -341,25 +341,25 @@ void WebGLContext::BufferData(GLenum tar
   }
 
   BufferDataImpl(target, byteLen, bytes, usage);
 }
 
 ////////////////////////////////////////
 
 void WebGLContext::BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset,
-                                     size_t dataLen, const uint8_t* data) {
+                                     uint64_t dataLen, const uint8_t* data) {
   const FuncScope funcScope(*this, "bufferSubData");
 
   if (!ValidateNonNegative("byteOffset", dstByteOffset)) return;
 
   const auto& buffer = ValidateBufferSelection(target);
   if (!buffer) return;
 
-  buffer->BufferSubData(target, size_t(dstByteOffset), dataLen, data);
+  buffer->BufferSubData(target, uint64_t(dstByteOffset), dataLen, data);
 }
 
 ////
 
 void WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
                                  const dom::ArrayBuffer& src) {
   const FuncScope funcScope(*this, "bufferSubData");
   if (IsContextLost()) return;