Add validation for the pack buffer in ReadPixels
BUG=angleproject:1512
Change-Id: Ia6bac628c35f04bc5d3adfde1569902475519698
Reviewed-on: https://chromium-review.googlesource.com/387668
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/formatutils.cpp b/src/libANGLE/formatutils.cpp
index 780f2f7..4222d72 100644
--- a/src/libANGLE/formatutils.cpp
+++ b/src/libANGLE/formatutils.cpp
@@ -939,6 +939,32 @@
return skipBytes.ValueOrDie();
}
+gl::ErrorOrResult<GLuint> InternalFormat::computePackSize(GLenum formatType,
+ const gl::Extents &size,
+ const gl::PixelPackState &pack) const
+{
+ ASSERT(!compressed);
+
+ if (size.height == 0)
+ {
+ return 0;
+ }
+
+ CheckedNumeric<GLuint> rowPitch;
+ ANGLE_TRY_RESULT(computeRowPitch(formatType, size.width, pack.alignment, pack.rowLength),
+ rowPitch);
+
+ CheckedNumeric<GLuint> heightMinusOne = size.height - 1;
+ CheckedNumeric<GLuint> bytes = computePixelBytes(formatType);
+
+ CheckedNumeric<GLuint> totalSize = heightMinusOne * rowPitch;
+ totalSize += size.width * bytes;
+
+ ANGLE_TRY_CHECKED_MATH(totalSize);
+
+ return totalSize.ValueOrDie();
+}
+
gl::ErrorOrResult<GLuint> InternalFormat::computeUnpackSize(
GLenum formatType,
const gl::Extents &size,
@@ -950,6 +976,11 @@
return computeCompressedImageSize(formatType, size);
}
+ if (size.height == 0 || size.depth == 0)
+ {
+ return 0;
+ }
+
CheckedNumeric<GLuint> rowPitch;
CheckedNumeric<GLuint> depthPitch;
ANGLE_TRY_RESULT(computeRowPitch(formatType, size.width, unpack.alignment, unpack.rowLength),
@@ -971,6 +1002,26 @@
return totalSize.ValueOrDie();
}
+gl::ErrorOrResult<GLuint> InternalFormat::computePackEndByte(GLenum formatType,
+ const gl::Extents &size,
+ const gl::PixelPackState &pack) const
+{
+ GLuint rowPitch;
+ CheckedNumeric<GLuint> checkedSkipBytes;
+ CheckedNumeric<GLuint> checkedCopyBytes;
+
+ ANGLE_TRY_RESULT(computeRowPitch(formatType, size.width, pack.alignment, pack.rowLength),
+ rowPitch);
+ ANGLE_TRY_RESULT(computeSkipBytes(rowPitch, 0, 0, pack.skipRows, pack.skipPixels, false),
+ checkedSkipBytes);
+ ANGLE_TRY_RESULT(computePackSize(formatType, size, pack), checkedCopyBytes);
+
+ CheckedNumeric<GLuint> endByte = checkedCopyBytes + checkedSkipBytes;
+
+ ANGLE_TRY_CHECKED_MATH(endByte);
+ return endByte.ValueOrDie();
+}
+
gl::ErrorOrResult<GLuint> InternalFormat::computeUnpackEndByte(GLenum formatType,
const gl::Extents &size,
const gl::PixelUnpackState &unpack,