bool WebGLBuffer::associateBufferSubDataImpl(GC3Dintptr offset, ArrayBuffer* array, GC3Dintptr arrayByteOffset, GC3Dsizeiptr byteLength) { if (!array || offset < 0 || arrayByteOffset < 0 || byteLength < 0) return false; if (byteLength) { CheckedInt<GC3Dintptr> checkedBufferOffset(offset); CheckedInt<GC3Dintptr> checkedArrayOffset(arrayByteOffset); CheckedInt<GC3Dsizeiptr> checkedLength(byteLength); CheckedInt<GC3Dintptr> checkedArrayMax = checkedArrayOffset + checkedLength; CheckedInt<GC3Dintptr> checkedBufferMax = checkedBufferOffset + checkedLength; if (!checkedArrayMax.valid() || checkedArrayMax.value() > static_cast<int32_t>(array->byteLength()) || !checkedBufferMax.valid() || checkedBufferMax.value() > m_byteLength) return false; } switch (m_target) { case GraphicsContext3D::ELEMENT_ARRAY_BUFFER: clearCachedMaxIndices(); if (byteLength) { if (!m_elementArrayBuffer) return false; memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()) + offset, static_cast<unsigned char*>(array->data()) + arrayByteOffset, byteLength); } return true; case GraphicsContext3D::ARRAY_BUFFER: return true; default: return false; } }
/* static */ bool gfxASurface::CheckSurfaceSize(const gfxIntSize& sz, PRInt32 limit) { if (sz.width < 0 || sz.height < 0) { NS_WARNING("Surface width or height < 0!"); return false; } // reject images with sides bigger than limit if (limit && (sz.width > limit || sz.height > limit)) { NS_WARNING("Surface size too large (exceeds caller's limit)!"); return false; } #if defined(XP_MACOSX) // CoreGraphics is limited to images < 32K in *height*, // so clamp all surfaces on the Mac to that height if (sz.height > SHRT_MAX) { NS_WARNING("Surface size too large (exceeds CoreGraphics limit)!"); return false; } #endif // make sure the surface area doesn't overflow a PRInt32 CheckedInt<PRInt32> tmp = sz.width; tmp *= sz.height; if (!tmp.valid()) { NS_WARNING("Surface size too large (would overflow)!"); return false; } // assuming 4-byte stride, make sure the allocation size // doesn't overflow a PRInt32 either tmp *= 4; if (!tmp.valid()) { NS_WARNING("Allocation too large (would overflow)!"); return false; } return true; }
bool WebGLBuffer::associateBufferDataImpl(ArrayBuffer* array, GC3Dintptr byteOffset, GC3Dsizeiptr byteLength) { if (byteLength < 0 || byteOffset < 0) return false; if (array && byteLength) { CheckedInt<GC3Dintptr> checkedOffset(byteOffset); CheckedInt<GC3Dsizeiptr> checkedLength(byteLength); CheckedInt<GC3Dintptr> checkedMax = checkedOffset + checkedLength; if (!checkedMax.valid() || checkedMax.value() > static_cast<int32_t>(array->byteLength())) return false; } switch (m_target) { case GraphicsContext3D::ELEMENT_ARRAY_BUFFER: m_byteLength = byteLength; clearCachedMaxIndices(); if (byteLength) { m_elementArrayBuffer = ArrayBuffer::create(byteLength, 1); if (!m_elementArrayBuffer) { m_byteLength = 0; return false; } if (array) { // We must always clone the incoming data because client-side // modifications without calling bufferData or bufferSubData // must never be able to change the validation results. memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()), static_cast<unsigned char*>(array->data()) + byteOffset, byteLength); } } else m_elementArrayBuffer = 0; return true; case GraphicsContext3D::ARRAY_BUFFER: m_byteLength = byteLength; return true; default: return false; } }