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

Unified Diff: src/core/SkColorSpace.cpp

Issue 2079243003: Sanitize parsing of color look-up table (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix use of magic number Created 4 years, 6 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkColorSpace.cpp
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
index ec8de725c129fdf79c400a1784771a2ab45eed81..5df45fff4126d7e9a08a1251e9b9cde029ae7de8 100644
--- a/src/core/SkColorSpace.cpp
+++ b/src/core/SkColorSpace.cpp
@@ -319,6 +319,17 @@ static bool safe_add(T arg1, T arg2, size_t* result) {
return false;
}
+static bool safe_mul(uint32_t arg1, uint32_t arg2, uint32_t* result) {
+ uint64_t product64 = (uint64_t) arg1 * (uint64_t) arg2;
+ uint32_t product32 = (uint32_t) product64;
+ if (product32 != product64) {
+ return false;
+ }
+
+ *result = product32;
+ return true;
+}
+
struct ICCTag {
uint32_t fSignature;
uint32_t fOffset;
@@ -658,10 +669,14 @@ static constexpr uint32_t kTAG_AtoBType = SkSetFourByteTag('m', 'A', 'B', ' ');
bool load_color_lut(SkColorLookUpTable* colorLUT, uint32_t inputChannels, uint32_t outputChannels,
const uint8_t* src, size_t len) {
- if (len < 20) {
+ // 16 bytes reserved for grid points, 2 for precision, 2 for padding.
+ // The color LUT data follows after this header.
+ static constexpr uint32_t kColorLUTHeaderSize = 20;
+ if (len < kColorLUTHeaderSize) {
SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len);
return false;
}
+ size_t dataLen = len - kColorLUTHeaderSize;
SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels && 3 == outputChannels);
colorLUT->fInputChannels = inputChannels;
@@ -669,9 +684,21 @@ bool load_color_lut(SkColorLookUpTable* colorLUT, uint32_t inputChannels, uint32
uint32_t numEntries = 1;
for (uint32_t i = 0; i < inputChannels; i++) {
colorLUT->fGridPoints[i] = src[i];
- numEntries *= src[i];
+ if (0 == src[i]) {
+ SkColorSpacePrintf("Each input channel must have at least one grid point.");
+ return false;
+ }
+
+ if (!safe_mul(numEntries, src[i], &numEntries)) {
+ SkColorSpacePrintf("Too many entries in Color LUT.");
+ return false;
+ }
+ }
+
+ if (!safe_mul(numEntries, outputChannels, &numEntries)) {
+ SkColorSpacePrintf("Too many entries in Color LUT.");
+ return false;
}
- numEntries *= outputChannels;
// Space is provided for a maximum of the 16 input channels. Now we determine the precision
// of the table values.
@@ -681,18 +708,24 @@ bool load_color_lut(SkColorLookUpTable* colorLUT, uint32_t inputChannels, uint32
case 2: // 16-bit data
break;
default:
- SkColorSpacePrintf("Color LUT precision must be 8-bit or 16-bit.\n", len);
+ SkColorSpacePrintf("Color LUT precision must be 8-bit or 16-bit.\n");
return false;
}
- if (len < 20 + numEntries * precision) {
+ uint32_t clutBytes;
+ if (!safe_mul(numEntries, precision, &clutBytes)) {
+ SkColorSpacePrintf("Too many entries in Color LUT.");
+ return false;
+ }
+
+ if (dataLen < clutBytes) {
SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len);
return false;
}
// Movable struct colorLUT has ownership of fTable.
colorLUT->fTable = std::unique_ptr<float[]>(new float[numEntries]);
- const uint8_t* ptr = src + 20;
+ const uint8_t* ptr = src + kColorLUTHeaderSize;
for (uint32_t i = 0; i < numEntries; i++, ptr += precision) {
if (1 == precision) {
colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698