blob: 9c19906b2116e47231881c8a38f508bc791f02cb [file] [edit]
diff --git a/third_party/lcms/src/cmscgats.c b/third_party/lcms/src/cmscgats.c
index 71692641a..0fe896122 100644
--- a/third_party/lcms/src/cmscgats.c
+++ b/third_party/lcms/src/cmscgats.c
@@ -2456,6 +2456,9 @@ cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cm
_cmsAssert(Ptr != NULL);
_cmsAssert(len != 0);
+ // Check for later overflow
+ if (len + 1 == 0) return NULL;
+
type = IsMyBlock((const cmsUInt8Number*)Ptr, len);
if (type == 0) return NULL;
@@ -2463,6 +2466,7 @@ cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cm
if (!hIT8) return NULL;
it8 = (cmsIT8*) hIT8;
+
it8 ->MemoryBlock = (char*) _cmsMalloc(ContextID, len + 1);
if (it8->MemoryBlock == NULL)
{
diff --git a/third_party/lcms/src/cmslut.c b/third_party/lcms/src/cmslut.c
index 11361de45..03bb01cb9 100644
--- a/third_party/lcms/src/cmslut.c
+++ b/third_party/lcms/src/cmslut.c
@@ -547,7 +547,7 @@ cmsStage* CMSEXPORT cmsStageAllocCLut16bitGranular(cmsContext ContextID,
cmsUInt32Number outputChan,
const cmsUInt16Number* Table)
{
- cmsUInt32Number i, n;
+ cmsUInt32Number i, n, cs;
_cmsStageCLutData* NewElem;
cmsStage* NewMPE;
@@ -571,14 +571,17 @@ cmsStage* CMSEXPORT cmsStageAllocCLut16bitGranular(cmsContext ContextID,
NewMPE ->Data = (void*) NewElem;
- NewElem -> nEntries = n = outputChan * CubeSize(clutPoints, inputChan);
- NewElem -> HasFloatValues = FALSE;
+ cs = CubeSize(clutPoints, inputChan);
+ n = outputChan * cs;
- if (n == 0) {
+ if (n == 0 || n / outputChan != cs) // Check for overflow.
+ {
cmsStageFree(NewMPE);
return NULL;
}
+ NewElem -> nEntries = n;
+ NewElem -> HasFloatValues = FALSE;
NewElem ->Tab.T = (cmsUInt16Number*) _cmsCalloc(ContextID, n, sizeof(cmsUInt16Number));
if (NewElem ->Tab.T == NULL) {
@@ -638,7 +641,7 @@ cmsStage* CMSEXPORT cmsStageAllocCLutFloat(cmsContext ContextID,
cmsStage* CMSEXPORT cmsStageAllocCLutFloatGranular(cmsContext ContextID, const cmsUInt32Number clutPoints[], cmsUInt32Number inputChan, cmsUInt32Number outputChan, const cmsFloat32Number* Table)
{
- cmsUInt32Number i, n;
+ cmsUInt32Number i, n, cs;
_cmsStageCLutData* NewElem;
cmsStage* NewMPE;
@@ -662,15 +665,18 @@ cmsStage* CMSEXPORT cmsStageAllocCLutFloatGranular(cmsContext ContextID, const c
NewMPE ->Data = (void*) NewElem;
- // There is a potential integer overflow on conputing n and nEntries.
- NewElem -> nEntries = n = outputChan * CubeSize(clutPoints, inputChan);
- NewElem -> HasFloatValues = TRUE;
+ cs = CubeSize(clutPoints, inputChan);
+ n = outputChan * cs;
- if (n == 0) {
+ if (n == 0 || n / outputChan != cs) // Check for overflow.
+ {
cmsStageFree(NewMPE);
return NULL;
}
+ NewElem -> nEntries = n;
+ NewElem -> HasFloatValues = TRUE;
+
NewElem ->Tab.TFloat = (cmsFloat32Number*) _cmsCalloc(ContextID, n, sizeof(cmsFloat32Number));
if (NewElem ->Tab.TFloat == NULL) {
cmsStageFree(NewMPE);
diff --git a/third_party/lcms/src/cmsnamed.c b/third_party/lcms/src/cmsnamed.c
index 54d1abf91..50cc6b349 100644
--- a/third_party/lcms/src/cmsnamed.c
+++ b/third_party/lcms/src/cmsnamed.c
@@ -92,7 +92,7 @@ cmsBool GrowMLUpool(cmsMLU* mlu)
static
cmsBool GrowMLUtable(cmsMLU* mlu)
{
- cmsUInt32Number AllocatedEntries;
+ cmsUInt32Number AllocatedEntries, AllocatedBytes;
_cmsMLUentry *NewPtr;
// Sanity check
@@ -103,8 +103,13 @@ cmsBool GrowMLUtable(cmsMLU* mlu)
// Check for overflow
if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE;
+ AllocatedBytes = AllocatedEntries * sizeof(_cmsMLUentry);
+
+ // Check for overflow
+ if (AllocatedBytes / sizeof(_cmsMLUentry) != AllocatedEntries) return FALSE;
+
// Reallocate the memory
- NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry));
+ NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedBytes);
if (NewPtr == NULL) return FALSE;
mlu ->Entries = NewPtr;
diff --git a/third_party/lcms/src/cmstypes.c b/third_party/lcms/src/cmstypes.c
index ec1909f8d..074511296 100644
--- a/third_party/lcms/src/cmstypes.c
+++ b/third_party/lcms/src/cmstypes.c
@@ -1488,10 +1488,10 @@ void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
cmsMLU* mlu;
cmsUInt32Number Count, RecLen, NumOfWchar;
cmsUInt32Number SizeOfHeader;
- cmsUInt32Number Len, Offset;
+ cmsUInt32Number Len, Offset, WideLen, WideSizeOfTag;
cmsUInt32Number i;
wchar_t* Block;
- cmsUInt32Number BeginOfThisString, EndOfThisString, LargestPosition;
+ cmsUInt32Number BeginOfThisString, EndOfThisString, LargestPosition, WideBeginOfThisString;
*nItems = 0;
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
@@ -1533,9 +1533,16 @@ void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
// True begin of the string
BeginOfThisString = Offset - SizeOfHeader - 8;
- // Adjust to wchar_t elements
- mlu ->Entries[i].Len = (Len * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
- mlu ->Entries[i].StrW = (BeginOfThisString * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
+ // Adjust to wchar_t elements and check for overflow
+ WideBeginOfThisString = BeginOfThisString * sizeof(wchar_t);
+ if (WideBeginOfThisString / sizeof(wchar_t) != BeginOfThisString) goto Error;
+
+ // Adjust to wchar_t elements and check for overflow
+ WideLen = Len * sizeof(wchar_t);
+ if (WideLen / sizeof(wchar_t) != Len) goto Error;
+
+ mlu ->Entries[i].Len = WideLen / sizeof(cmsUInt16Number);
+ mlu ->Entries[i].StrW = WideBeginOfThisString / sizeof(cmsUInt16Number);
// To guess maximum size, add offset + len
EndOfThisString = BeginOfThisString + Len;
@@ -1544,7 +1551,12 @@ void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
}
// Now read the remaining of tag and fill all strings. Subtract the directory
- SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
+ WideSizeOfTag = LargestPosition * sizeof(wchar_t);
+
+ // Check for overflow
+ if (WideSizeOfTag / sizeof(wchar_t) != LargestPosition) goto Error;
+
+ SizeOfTag = WideSizeOfTag / sizeof(cmsUInt16Number);
if (SizeOfTag == 0)
{
Block = NULL;
@@ -5128,7 +5140,7 @@ static
cmsBool ReadOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, wchar_t ** wcstr)
{
- cmsUInt32Number nChars;
+ cmsUInt32Number nChars, nBytes;
// Special case for undefined strings (see ICC Votable
// Proposal Submission, Dictionary Type and Metadata TAG Definition)
@@ -5141,9 +5153,12 @@ cmsBool ReadOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, wchar
if (!io -> Seek(io, e -> Offsets[i])) return FALSE;
nChars = e ->Sizes[i] / sizeof(cmsUInt16Number);
+ nBytes = (nChars + 1) * sizeof(wchar_t);
+ // Check for overflow
+ if (nBytes / sizeof(wchar_t) != nChars + 1) return FALSE;
- *wcstr = (wchar_t*) _cmsMallocZero(e ->ContextID, (nChars + 1) * sizeof(wchar_t));
+ *wcstr = (wchar_t*) _cmsMallocZero(e ->ContextID, nBytes);
if (*wcstr == NULL) return FALSE;
if (!_cmsReadWCharArray(io, nChars, *wcstr)) {