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

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: 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 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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 } 662 }
652 } 663 }
653 664
654 return true; 665 return true;
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 // 16 bytes reserved for grid points, 2 for precision, 2 for padding.
673 // The color LUT data follows after this header.
674 static constexpr uint32_t kColorLUTHeaderSize = 20;
675 if (len < kColorLUTHeaderSize) {
662 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); 676 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len);
663 return false; 677 return false;
664 } 678 }
679 size_t dataLen = len - kColorLUTHeaderSize;
665 680
666 SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels && 3 == outputCha nnels); 681 SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels && 3 == outputCha nnels);
667 colorLUT->fInputChannels = inputChannels; 682 colorLUT->fInputChannels = inputChannels;
668 colorLUT->fOutputChannels = outputChannels; 683 colorLUT->fOutputChannels = outputChannels;
669 uint32_t numEntries = 1; 684 uint32_t numEntries = 1;
670 for (uint32_t i = 0; i < inputChannels; i++) { 685 for (uint32_t i = 0; i < inputChannels; i++) {
671 colorLUT->fGridPoints[i] = src[i]; 686 colorLUT->fGridPoints[i] = src[i];
672 numEntries *= src[i]; 687 if (0 == src[i]) {
688 SkColorSpacePrintf("Each input channel must have at least one grid p oint.");
689 return false;
690 }
691
692 if (!safe_mul(numEntries, src[i], &numEntries)) {
693 SkColorSpacePrintf("Too many entries in Color LUT.");
694 return false;
695 }
673 } 696 }
674 numEntries *= outputChannels; 697
698 if (!safe_mul(numEntries, outputChannels, &numEntries)) {
699 SkColorSpacePrintf("Too many entries in Color LUT.");
700 return false;
701 }
675 702
676 // Space is provided for a maximum of the 16 input channels. Now we determi ne the precision 703 // Space is provided for a maximum of the 16 input channels. Now we determi ne the precision
677 // of the table values. 704 // of the table values.
678 uint8_t precision = src[16]; 705 uint8_t precision = src[16];
679 switch (precision) { 706 switch (precision) {
680 case 1: // 8-bit data 707 case 1: // 8-bit data
681 case 2: // 16-bit data 708 case 2: // 16-bit data
682 break; 709 break;
683 default: 710 default:
684 SkColorSpacePrintf("Color LUT precision must be 8-bit or 16-bit.\n", len); 711 SkColorSpacePrintf("Color LUT precision must be 8-bit or 16-bit.\n") ;
685 return false; 712 return false;
686 } 713 }
687 714
688 if (len < 20 + numEntries * precision) { 715 uint32_t clutBytes;
716 if (!safe_mul(numEntries, precision, &clutBytes)) {
717 SkColorSpacePrintf("Too many entries in Color LUT.");
718 return false;
719 }
720
721 if (dataLen < clutBytes) {
689 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); 722 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len);
690 return false; 723 return false;
691 } 724 }
692 725
693 // Movable struct colorLUT has ownership of fTable. 726 // Movable struct colorLUT has ownership of fTable.
694 colorLUT->fTable = std::unique_ptr<float[]>(new float[numEntries]); 727 colorLUT->fTable = std::unique_ptr<float[]>(new float[numEntries]);
695 const uint8_t* ptr = src + 20; 728 const uint8_t* ptr = src + kColorLUTHeaderSize;
696 for (uint32_t i = 0; i < numEntries; i++, ptr += precision) { 729 for (uint32_t i = 0; i < numEntries; i++, ptr += precision) {
697 if (1 == precision) { 730 if (1 == precision) {
698 colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f; 731 colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f;
699 } else { 732 } else {
700 colorLUT->fTable[i] = ((float) read_big_endian_short(ptr)) / 65535.0 f; 733 colorLUT->fTable[i] = ((float) read_big_endian_short(ptr)) / 65535.0 f;
701 } 734 }
702 } 735 }
703 736
704 return true; 737 return true;
705 } 738 }
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 ptr32[4] = SkEndian_SwapBE32(0x000116cc); 1201 ptr32[4] = SkEndian_SwapBE32(0x000116cc);
1169 ptr += kTAG_XYZ_Bytes; 1202 ptr += kTAG_XYZ_Bytes;
1170 1203
1171 // Write copyright tag 1204 // Write copyright tag
1172 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); 1205 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag));
1173 1206
1174 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if 1207 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if
1175 // the client calls again? 1208 // the client calls again?
1176 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); 1209 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize);
1177 } 1210 }
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