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

Side by Side Diff: src/core/SkColorSpace.cpp

Issue 2020303002: Fix integer overflow in SkColorSpace (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 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 return false; 359 return false;
360 } 360 }
361 361
362 dst[0] = SkFixedToFloat(read_big_endian_int(src + 8)); 362 dst[0] = SkFixedToFloat(read_big_endian_int(src + 8));
363 dst[1] = SkFixedToFloat(read_big_endian_int(src + 12)); 363 dst[1] = SkFixedToFloat(read_big_endian_int(src + 12));
364 dst[2] = SkFixedToFloat(read_big_endian_int(src + 16)); 364 dst[2] = SkFixedToFloat(read_big_endian_int(src + 16));
365 SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]); 365 SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]);
366 return true; 366 return true;
367 } 367 }
368 368
369 template <class T>
370 static bool safe_add(T arg1, T arg2, size_t* result) {
371 SkASSERT(arg1 >= 0);
372 SkASSERT(arg2 >= 0);
373 if (arg1 >= 0 && arg2 <= std::numeric_limits<T>::max() - arg1) {
374 T sum = arg1 + arg2;
375 if (sum <= std::numeric_limits<size_t>::max()) {
376 *result = static_cast<size_t>(sum);
377 return true;
378 }
379 }
380 return false;
381 }
382
369 static constexpr uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', ' v'); 383 static constexpr uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', ' v');
370 static constexpr uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', ' a'); 384 static constexpr uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', ' a');
371 385
372 bool load_gammas(SkGammaCurve* gammas, uint32_t numGammas, const uint8_t* src, s ize_t len) { 386 bool load_gammas(SkGammaCurve* gammas, uint32_t numGammas, const uint8_t* src, s ize_t len) {
373 for (uint32_t i = 0; i < numGammas; i++) { 387 for (uint32_t i = 0; i < numGammas; i++) {
374 if (len < 12) { 388 if (len < 12) {
375 // FIXME (msarett): 389 // FIXME (msarett):
376 // We could potentially return false here after correctly parsing *s ome* of the 390 // We could potentially return false here after correctly parsing *s ome* of the
377 // gammas correctly. Should we somehow try to indicate a partial su ccess? 391 // gammas correctly. Should we somehow try to indicate a partial su ccess?
378 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len); 392 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
379 return false; 393 return false;
380 } 394 }
381 395
382 // We need to count the number of bytes in the tag, so we are able to mo ve to the 396 // We need to count the number of bytes in the tag, so we are able to mo ve to the
383 // next tag on the next loop iteration. 397 // next tag on the next loop iteration.
384 size_t tagBytes; 398 size_t tagBytes;
385 399
386 uint32_t type = read_big_endian_uint(src); 400 uint32_t type = read_big_endian_uint(src);
387 switch (type) { 401 switch (type) {
388 case kTAG_CurveType: { 402 case kTAG_CurveType: {
389 uint32_t count = read_big_endian_uint(src + 8); 403 uint32_t count = read_big_endian_uint(src + 8);
390 tagBytes = 12 + count * 2; 404
405 // tagBytes = 12 + 2 * count
406 // We need to do safe addition here to avoid integer overflow.
407 if (!safe_add(count, count, &tagBytes) ||
408 !safe_add((size_t) 12, tagBytes, &tagBytes))
409 {
410 SkColorSpacePrintf("Invalid gamma count");
411 return false;
412 }
413
391 if (0 == count) { 414 if (0 == count) {
392 // Some tags require a gamma curve, but the author doesn't a ctually want 415 // Some tags require a gamma curve, but the author doesn't a ctually want
393 // to transform the data. In this case, it is common to see a curve with 416 // to transform the data. In this case, it is common to see a curve with
394 // a count of 0. 417 // a count of 0.
395 gammas[i].fValue = 1.0f; 418 gammas[i].fValue = 1.0f;
396 break; 419 break;
397 } else if (len < tagBytes) { 420 } else if (len < tagBytes) {
398 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ; 421 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ;
399 return false; 422 return false;
400 } 423 }
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 ptr32[4] = SkEndian_SwapBE32(0x000116cc); 1071 ptr32[4] = SkEndian_SwapBE32(0x000116cc);
1049 ptr += kTAG_XYZ_Bytes; 1072 ptr += kTAG_XYZ_Bytes;
1050 1073
1051 // Write copyright tag 1074 // Write copyright tag
1052 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); 1075 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag));
1053 1076
1054 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if 1077 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if
1055 // the client calls again? 1078 // the client calls again?
1056 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); 1079 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize);
1057 } 1080 }
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