Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(807)

Unified Diff: third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp

Issue 1566283003: Upgrade blink side ReadPixels size validation to consider ES3 pack parameters. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp b/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp
index 94ed96346338b246a361d940987693eda8a377da..38849d9937831680cd1affa8a12408eaea61b1cb 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp
@@ -1923,8 +1923,26 @@ void FormatConverter::convert()
return;
}
+bool frameIsValid(const SkBitmap& frameBitmap)
+{
+ return !frameBitmap.isNull()
+ && !frameBitmap.empty()
+ && frameBitmap.isImmutable()
+ && frameBitmap.colorType() == kN32_SkColorType;
+}
+
} // anonymous namespace
+WebGLImageConversion::PixelStoreParams::PixelStoreParams()
+ : alignment(4)
+ , rowLength(0)
+ , imageHeight(0)
+ , skipPixels(0)
+ , skipRows(0)
+ , skipImages(0)
+{
+}
+
bool WebGLImageConversion::computeFormatAndTypeParameters(GLenum format, GLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent)
{
switch (format) {
@@ -2000,40 +2018,102 @@ bool WebGLImageConversion::computeFormatAndTypeParameters(GLenum format, GLenum
return true;
}
-GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, GLint alignment, unsigned* imageSizeInBytes, unsigned* paddingInBytes)
+GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, const PixelStoreParams& params, unsigned* imageSizeInBytes, unsigned* paddingInBytes, unsigned* skipSizeInBytes)
{
ASSERT(imageSizeInBytes);
- ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8);
+ ASSERT(params.alignment == 1 || params.alignment == 2 || params.alignment == 4 || params.alignment == 8);
+ ASSERT(params.rowLength >= 0 && params.imageHeight >= 0);
+ ASSERT(params.skipPixels >= 0 && params.skipRows >= 0 && params.skipImages >= 0);
if (width < 0 || height < 0 || depth < 0)
return GL_INVALID_VALUE;
- unsigned bytesPerComponent, componentsPerPixel;
- if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &componentsPerPixel))
- return GL_INVALID_ENUM;
if (!width || !height || !depth) {
*imageSizeInBytes = 0;
if (paddingInBytes)
*paddingInBytes = 0;
+ if (skipSizeInBytes)
+ *skipSizeInBytes = 0;
return GL_NO_ERROR;
}
- CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel);
- checkedValue *= width;
+
+ int rowLength = params.rowLength > 0 ? params.rowLength : width;
+ int imageHeight = params.imageHeight > 0 ? params.imageHeight : height;
+
+ unsigned bytesPerComponent, componentsPerPixel;
+ if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &componentsPerPixel))
+ return GL_INVALID_ENUM;
+ unsigned bytesPerGroup = bytesPerComponent * componentsPerPixel;
+ CheckedInt<uint32_t> checkedValue = static_cast<uint32_t>(rowLength);
+ checkedValue *= bytesPerGroup;
if (!checkedValue.isValid())
return GL_INVALID_VALUE;
- unsigned validRowSize = checkedValue.value();
+
+ unsigned lastRowSize;
+ if (params.rowLength > 0 && params.rowLength != width) {
+ CheckedInt<uint32_t> tmp = width;
+ tmp *= bytesPerGroup;
+ if (!tmp.isValid())
+ return GL_INVALID_VALUE;
+ lastRowSize = tmp.value();
+ } else {
+ lastRowSize = checkedValue.value();
+ }
+
unsigned padding = 0;
- unsigned residual = validRowSize % alignment;
+ unsigned residual = checkedValue.value() % params.alignment;
if (residual) {
- padding = alignment - residual;
+ padding = params.alignment - residual;
checkedValue += padding;
}
- // Last row needs no padding.
- checkedValue *= (height * depth - 1);
- checkedValue += validRowSize;
+ if (!checkedValue.isValid())
+ return GL_INVALID_VALUE;
+ unsigned paddedRowSize = checkedValue.value();
+
+ CheckedInt<uint32_t> rows = imageHeight;
+ rows *= (depth - 1);
+ // Last image is not affected by IMAGE_HEIGHT parameter.
+ rows += height;
+ if (!rows.isValid())
+ return GL_INVALID_VALUE;
+ checkedValue *= (rows.value() - 1);
+ // Last row is not affected by ROW_LENGTH parameter.
+ checkedValue += lastRowSize;
if (!checkedValue.isValid())
return GL_INVALID_VALUE;
*imageSizeInBytes = checkedValue.value();
if (paddingInBytes)
*paddingInBytes = padding;
+
+ CheckedInt<uint32_t> skipSize = 0;
+ if (params.skipImages > 0) {
+ CheckedInt<uint32_t> tmp = paddedRowSize;
+ tmp *= imageHeight;
+ tmp *= params.skipImages;
+ if (!tmp.isValid())
+ return GL_INVALID_VALUE;
+ skipSize += tmp.value();
+ }
+ if (params.skipRows > 0) {
+ CheckedInt<uint32_t> tmp = paddedRowSize;
+ tmp *= params.skipRows;
+ if (!tmp.isValid())
+ return GL_INVALID_VALUE;
+ skipSize += tmp.value();
+ }
+ if (params.skipPixels > 0) {
+ CheckedInt<uint32_t> tmp = bytesPerGroup;
+ tmp *= params.skipPixels;
+ if (!tmp.isValid())
+ return GL_INVALID_VALUE;
+ skipSize += tmp.value();
+ }
+ if (!skipSize.isValid())
+ return GL_INVALID_VALUE;
+ if (skipSizeInBytes)
+ *skipSizeInBytes = skipSize.value();
+
+ checkedValue += skipSize.value();
+ if (!checkedValue.isValid())
+ return GL_INVALID_VALUE;
return GL_NO_ERROR;
}
@@ -2044,18 +2124,6 @@ WebGLImageConversion::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomS
extractImage(premultiplyAlpha, ignoreGammaAndColorProfile);
}
-namespace {
-
-bool frameIsValid(const SkBitmap& frameBitmap)
-{
- return !frameBitmap.isNull()
- && !frameBitmap.empty()
- && frameBitmap.isImmutable()
- && frameBitmap.colorType() == kN32_SkColorType;
-}
-
-} // anonymous namespace
-
void WebGLImageConversion::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
{
ASSERT(!m_imagePixelLocker);
@@ -2230,7 +2298,9 @@ bool WebGLImageConversion::packImageData(
unsigned packedSize;
// Output data is tightly packed (alignment == 1).
- if (computeImageSizeInBytes(format, type, width, height, 1, 1, &packedSize, 0) != GL_NO_ERROR)
+ PixelStoreParams params;
+ params.alignment = 1;
+ if (computeImageSizeInBytes(format, type, width, height, 1, params, &packedSize, 0, 0) != GL_NO_ERROR)
return false;
data.resize(packedSize);
@@ -2257,7 +2327,9 @@ bool WebGLImageConversion::extractImageData(
unsigned packedSize;
// Output data is tightly packed (alignment == 1).
- if (computeImageSizeInBytes(format, type, width, height, 1, 1, &packedSize, 0) != GL_NO_ERROR)
+ PixelStoreParams params;
+ params.alignment = 1;
+ if (computeImageSizeInBytes(format, type, width, height, 1, params, &packedSize, 0, 0) != GL_NO_ERROR)
return false;
data.resize(packedSize);
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698