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

Side by Side 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: 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkColorSpace.h" 8 #include "SkColorSpace.h"
9 #include "SkColorSpace_Base.h" 9 #include "SkColorSpace_Base.h"
10 #include "SkEndian.h" 10 #include "SkEndian.h"
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 if (arg1 >= 0 && arg2 <= std::numeric_limits<T>::max() - arg1) { 312 if (arg1 >= 0 && arg2 <= std::numeric_limits<T>::max() - arg1) {
313 T sum = arg1 + arg2; 313 T sum = arg1 + arg2;
314 if (sum <= std::numeric_limits<size_t>::max()) { 314 if (sum <= std::numeric_limits<size_t>::max()) {
315 *result = static_cast<size_t>(sum); 315 *result = static_cast<size_t>(sum);
316 return true; 316 return true;
317 } 317 }
318 } 318 }
319 return false; 319 return false;
320 } 320 }
321 321
322 static bool safe_mul(uint32_t arg1, uint32_t arg2, uint32_t* result) {
323 uint64_t product64 = (uint64_t) arg1 * (uint64_t) arg2;
324 uint32_t product32 = (uint32_t) product64;
325 if (product32 != product64) {
326 return false;
327 }
328
329 *result = product32;
330 return true;
331 }
332
322 struct ICCTag { 333 struct ICCTag {
323 uint32_t fSignature; 334 uint32_t fSignature;
324 uint32_t fOffset; 335 uint32_t fOffset;
325 uint32_t fLength; 336 uint32_t fLength;
326 337
327 const uint8_t* init(const uint8_t* src) { 338 const uint8_t* init(const uint8_t* src) {
328 fSignature = read_big_endian_uint(src); 339 fSignature = read_big_endian_uint(src);
329 fOffset = read_big_endian_uint(src + 4); 340 fOffset = read_big_endian_uint(src + 4);
330 fLength = read_big_endian_uint(src + 8); 341 fLength = read_big_endian_uint(src + 8);
331 return src + 12; 342 return src + 12;
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 } 666 }
656 667
657 static constexpr uint32_t kTAG_AtoBType = SkSetFourByteTag('m', 'A', 'B', ' '); 668 static constexpr uint32_t kTAG_AtoBType = SkSetFourByteTag('m', 'A', 'B', ' ');
658 669
659 bool load_color_lut(SkColorLookUpTable* colorLUT, uint32_t inputChannels, uint32 _t outputChannels, 670 bool load_color_lut(SkColorLookUpTable* colorLUT, uint32_t inputChannels, uint32 _t outputChannels,
660 const uint8_t* src, size_t len) { 671 const uint8_t* src, size_t len) {
661 if (len < 20) { 672 if (len < 20) {
662 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); 673 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len);
663 return false; 674 return false;
664 } 675 }
676 size_t dataLen = len - 20;
kjlubick 2016/06/20 14:27:23 Where's the magic number 20 coming from?
msarett 2016/06/20 14:44:11 20 is the number of bytes preceding the actual col
665 677
666 SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels && 3 == outputCha nnels); 678 SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels && 3 == outputCha nnels);
667 colorLUT->fInputChannels = inputChannels; 679 colorLUT->fInputChannels = inputChannels;
668 colorLUT->fOutputChannels = outputChannels; 680 colorLUT->fOutputChannels = outputChannels;
669 uint32_t numEntries = 1; 681 uint32_t numEntries = 1;
670 for (uint32_t i = 0; i < inputChannels; i++) { 682 for (uint32_t i = 0; i < inputChannels; i++) {
671 colorLUT->fGridPoints[i] = src[i]; 683 colorLUT->fGridPoints[i] = src[i];
672 numEntries *= src[i]; 684 if (0 == src[i]) {
685 SkColorSpacePrintf("Each input channel must have at least one grid p oint.");
686 return false;
687 }
688
689 if (!safe_mul(numEntries, src[i], &numEntries)) {
690 SkColorSpacePrintf("Too many entries in Color LUT.");
691 return false;
692 }
673 } 693 }
674 numEntries *= outputChannels; 694
695 if (!safe_mul(numEntries, outputChannels, &numEntries)) {
696 SkColorSpacePrintf("Too many entries in Color LUT.");
697 return false;
698 }
675 699
676 // Space is provided for a maximum of the 16 input channels. Now we determi ne the precision 700 // Space is provided for a maximum of the 16 input channels. Now we determi ne the precision
677 // of the table values. 701 // of the table values.
678 uint8_t precision = src[16]; 702 uint8_t precision = src[16];
679 switch (precision) { 703 switch (precision) {
680 case 1: // 8-bit data 704 case 1: // 8-bit data
681 case 2: // 16-bit data 705 case 2: // 16-bit data
682 break; 706 break;
683 default: 707 default:
684 SkColorSpacePrintf("Color LUT precision must be 8-bit or 16-bit.\n", len); 708 SkColorSpacePrintf("Color LUT precision must be 8-bit or 16-bit.\n") ;
685 return false; 709 return false;
686 } 710 }
687 711
688 if (len < 20 + numEntries * precision) { 712 uint32_t clutBytes;
713 if (!safe_mul(numEntries, precision, &clutBytes)) {
714 SkColorSpacePrintf("Too many entries in Color LUT.");
715 return false;
716 }
717
718 if (dataLen < clutBytes) {
689 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); 719 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len);
690 return false; 720 return false;
691 } 721 }
692 722
693 // Movable struct colorLUT has ownership of fTable. 723 // Movable struct colorLUT has ownership of fTable.
694 colorLUT->fTable = std::unique_ptr<float[]>(new float[numEntries]); 724 colorLUT->fTable = std::unique_ptr<float[]>(new float[numEntries]);
695 const uint8_t* ptr = src + 20; 725 const uint8_t* ptr = src + 20;
696 for (uint32_t i = 0; i < numEntries; i++, ptr += precision) { 726 for (uint32_t i = 0; i < numEntries; i++, ptr += precision) {
697 if (1 == precision) { 727 if (1 == precision) {
698 colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f; 728 colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f;
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 ptr32[4] = SkEndian_SwapBE32(0x000116cc); 1198 ptr32[4] = SkEndian_SwapBE32(0x000116cc);
1169 ptr += kTAG_XYZ_Bytes; 1199 ptr += kTAG_XYZ_Bytes;
1170 1200
1171 // Write copyright tag 1201 // Write copyright tag
1172 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); 1202 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag));
1173 1203
1174 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if 1204 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if
1175 // the client calls again? 1205 // the client calls again?
1176 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); 1206 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize);
1177 } 1207 }
OLDNEW
« 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