Bug 1313541 - Add ValidateArrayBufferView. - r=ethlin
MozReview-Commit-ID: JuiA7dD4vwR
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -2504,16 +2504,51 @@ WebGLContext::StartVRPresentation()
vrmc->GetBackendType(),
TextureFlags::ORIGIN_BOTTOM_LEFT);
screen->Morph(Move(factory));
return true;
}
////////////////////////////////////////////////////////////////////////////////
+
+bool
+WebGLContext::ValidateArrayBufferView(const char* funcName,
+ const dom::ArrayBufferView& view, GLuint elemOffset,
+ GLuint elemCountOverride, uint8_t** const out_bytes,
+ size_t* const out_byteLen)
+{
+ view.ComputeLengthAndData();
+ uint8_t* const bytes = view.DataAllowShared();
+ const size_t byteLen = view.LengthAllowShared();
+
+ const auto& elemType = view.Type();
+ const auto& elemSize = js::Scalar::byteSize(elemType);
+
+ size_t elemCount = byteLen / elemSize;
+ if (elemOffset > elemCount) {
+ ErrorInvalidValue("%s: Invalid offset into ArrayBufferView.", funcName);
+ return false;
+ }
+ elemCount -= elemOffset;
+
+ if (elemCountOverride) {
+ if (elemCountOverride > elemCount) {
+ ErrorInvalidValue("%s: Invalid sub-length for ArrayBufferView.", funcName);
+ return false;
+ }
+ elemCount = elemCountOverride;
+ }
+
+ *out_bytes = bytes + (elemOffset * elemSize);
+ *out_byteLen = elemCount * elemSize;
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// XPCOM goop
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback,
const std::vector<IndexedBufferBinding>& field,
const char* name, uint32_t flags)
{
for (const auto& cur : field) {
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1346,16 +1346,22 @@ protected:
bool ValidateNonNegative(const char* funcName, const char* argName, int64_t val) {
if (MOZ_UNLIKELY(val < 0)) {
ErrorInvalidValue("%s: `%s` must be non-negative.", funcName, argName);
return false;
}
return true;
}
+ bool ValidateArrayBufferView(const char* funcName, const dom::ArrayBufferView& view,
+ GLuint elemOffset, GLuint elemCountOverride,
+ uint8_t** const out_bytes, size_t* const out_byteLen);
+
+ ////
+
void Invalidate();
void DestroyResourcesAndContext();
void MakeContextCurrent() const;
// helpers
bool ConvertImage(size_t width, size_t height, size_t srcStride,
@@ -1844,20 +1850,17 @@ class ScopedLazyBind final
public:
ScopedLazyBind(gl::GLContext* gl, GLenum target, const WebGLBuffer* buf);
private:
void UnwrapImpl();
};
-void
-ComputeLengthAndData(const dom::ArrayBufferViewOrSharedArrayBufferView& view,
- void** const out_data, size_t* const out_length,
- js::Scalar::Type* const out_type);
+////
void
Intersect(uint32_t srcSize, int32_t dstStartInSrc, uint32_t dstSize,
uint32_t* const out_intStartInSrc, uint32_t* const out_intStartInDst,
uint32_t* const out_intSize);
bool
ZeroTextureData(WebGLContext* webgl, const char* funcName, GLuint tex,