summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Maria <info@littlecms.com>2010-10-25 17:44:14 +0200
committerMarti Maria <info@littlecms.com>2010-10-25 17:44:14 +0200
commit49219c0843d308922089283085ffc59e8d051595 (patch)
tree7bbd73fdfdf409eb7a763407f5f4724e60d69c06
parent4bd08b41fa98610816e73999297ed1648fe8b999 (diff)
downloadlcms2-49219c0843d308922089283085ffc59e8d051595.tar.gz
beta2 code review
-rw-r--r--include/lcms2.h2
-rw-r--r--include/lcms2_plugin.h1
-rw-r--r--src/cmserr.c3
-rw-r--r--src/cmsio0.c10
-rw-r--r--src/cmslut.c41
-rw-r--r--src/cmsnamed.c2
-rw-r--r--src/cmstypes.c96
7 files changed, 119 insertions, 36 deletions
diff --git a/include/lcms2.h b/include/lcms2.h
index fd7172f..bab1ec5 100644
--- a/include/lcms2.h
+++ b/include/lcms2.h
@@ -23,7 +23,7 @@
//
//---------------------------------------------------------------------------------
//
-// Version 2.1(alpha1)
+// Version 2.1(beta1)
//
#ifndef _lcms2_H
diff --git a/include/lcms2_plugin.h b/include/lcms2_plugin.h
index 359bf0f..896fa49 100644
--- a/include/lcms2_plugin.h
+++ b/include/lcms2_plugin.h
@@ -115,6 +115,7 @@ struct _cms_io_handler {
cmsContext ContextID;
cmsUInt32Number UsedSpace;
+ cmsUInt32Number ReportedSize;
char PhysicalFile[cmsMAX_PATH];
cmsUInt32Number (* Read)(struct _cms_io_handler* iohandler, void *Buffer,
diff --git a/src/cmserr.c b/src/cmserr.c
index b8fda2d..5f79328 100644
--- a/src/cmserr.c
+++ b/src/cmserr.c
@@ -134,7 +134,8 @@ void* _cmsCallocDefaultFn(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Nu
// Preserve calloc behaviour
if (Total == 0) return NULL;
- if (num >= UINT_MAX / size) return NULL; // Safe check for overflow.
+ // Safe check for overflow.
+ if (num >= UINT_MAX / size) return NULL;
// Check for overflow
if (Total < num || Total < size) {
diff --git a/src/cmsio0.c b/src/cmsio0.c
index 5cb36a9..589ea6a 100644
--- a/src/cmsio0.c
+++ b/src/cmsio0.c
@@ -113,6 +113,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromNULL(cmsContext ContextID)
iohandler ->ContextID = ContextID;
iohandler ->stream = (void*) fm;
iohandler ->UsedSpace = 0;
+ iohandler ->ReportedSize = 0;
iohandler ->PhysicalFile[0] = 0;
iohandler ->Read = NULLRead;
@@ -268,6 +269,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromMem(cmsContext ContextID, void *Buff
fm ->FreeBlockOnClose = TRUE;
fm ->Size = size;
fm ->Pointer = 0;
+ iohandler -> ReportedSize = size;
break;
case 'w':
@@ -278,6 +280,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromMem(cmsContext ContextID, void *Buff
fm ->FreeBlockOnClose = FALSE;
fm ->Size = size;
fm ->Pointer = 0;
+ iohandler -> ReportedSize = 0;
break;
default:
@@ -378,6 +381,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
return NULL;
}
+ iohandler -> ReportedSize = cmsfilelength(fm);
break;
case 'w':
@@ -387,6 +391,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
cmsSignalError(ContextID, cmsERROR_FILE, "Couldn't create '%s'", FileName);
return NULL;
}
+ iohandler -> ReportedSize = 0;
break;
default:
@@ -426,6 +431,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* S
iohandler -> ContextID = ContextID;
iohandler -> stream = (void*) Stream;
iohandler -> UsedSpace = 0;
+ iohandler -> ReportedSize = cmsfilelength(Stream);
iohandler -> PhysicalFile[0] = 0;
iohandler ->Read = FileRead;
@@ -621,8 +627,8 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
HeaderSize = _cmsAdjustEndianess32(Header.size);
// Make sure HeaderSize is lower than profile size
- // if (HeaderSize >= ???)
- // HeaderSize = ???;
+ if (HeaderSize >= Icc ->IOhandler ->ReportedSize)
+ HeaderSize = Icc ->IOhandler ->ReportedSize;
// Get creation date/time
diff --git a/src/cmslut.c b/src/cmslut.c
index 11aafb7..d0fe9c8 100644
--- a/src/cmslut.c
+++ b/src/cmslut.c
@@ -463,10 +463,20 @@ void EvaluateCLUTfloatIn16(const cmsFloat32Number In[], cmsFloat32Number Out[],
static
cmsUInt32Number CubeSize(const cmsUInt32Number Dims[], cmsUInt32Number b)
{
- cmsUInt32Number rv;
+ cmsUInt32Number rv, dim;
- for (rv = 1; b > 0; b--)
- rv *= Dims[b-1];
+ _cmsAssert(Dims != NULL);
+
+ for (rv = 1; b > 0; b--) {
+
+ dim = Dims[b-1];
+ if (dim == 0) return 0; // Error
+
+ rv *= dim;
+
+ // Check for overflow
+ if (rv > UINT_MAX / dim) return 0;
+ }
return rv;
}
@@ -549,6 +559,12 @@ cmsStage* CMSEXPORT cmsStageAllocCLut16bitGranular(cmsContext ContextID,
NewElem -> nEntries = n = outputChan * CubeSize(clutPoints, inputChan);
NewElem -> HasFloatValues = FALSE;
+ if (n == 0) {
+ cmsStageFree(NewMPE);
+ return NULL;
+ }
+
+
NewElem ->Tab.T = (cmsUInt16Number*) _cmsCalloc(ContextID, n, sizeof(cmsUInt16Number));
if (NewElem ->Tab.T == NULL) {
cmsStageFree(NewMPE);
@@ -610,9 +626,12 @@ cmsStage* CMSEXPORT cmsStageAllocCLutFloatGranular(cmsContext ContextID, const c
{
cmsUInt32Number i, n;
_cmsStageCLutData* NewElem;
- cmsStage* NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigCLutElemType, inputChan, outputChan,
- EvaluateCLUTfloat, CLUTElemDup, CLutElemTypeFree, NULL);
+ cmsStage* NewMPE;
+
+ _cmsAssert(clutPoints != NULL);
+ NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigCLutElemType, inputChan, outputChan,
+ EvaluateCLUTfloat, CLUTElemDup, CLutElemTypeFree, NULL);
if (NewMPE == NULL) return NULL;
@@ -628,6 +647,11 @@ cmsStage* CMSEXPORT cmsStageAllocCLutFloatGranular(cmsContext ContextID, const c
NewElem -> nEntries = n = outputChan * CubeSize( clutPoints, inputChan);
NewElem -> HasFloatValues = TRUE;
+ if (n == 0) {
+ cmsStageFree(NewMPE);
+ return NULL;
+ }
+
NewElem ->Tab.TFloat = (cmsFloat32Number*) _cmsCalloc(ContextID, n, sizeof(cmsFloat32Number));
if (NewElem ->Tab.TFloat == NULL) {
cmsStageFree(NewMPE);
@@ -719,6 +743,7 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v
if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE;
nTotalPoints = CubeSize(nSamples, nInputs);
+ if (nTotalPoints == 0) return FALSE;
index = 0;
for (i = 0; i < nTotalPoints; i++) {
@@ -772,6 +797,7 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE;
nTotalPoints = CubeSize(nSamples, nInputs);
+ if (nTotalPoints == 0) return FALSE;
index = 0;
for (i = 0; i < nTotalPoints; i++) {
@@ -821,6 +847,7 @@ cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number
if (nInputs >= cmsMAXCHANNELS) return FALSE;
nTotalPoints = CubeSize(clutPoints, nInputs);
+ if (nTotalPoints == 0) return FALSE;
for (i = 0; i < nTotalPoints; i++) {
@@ -850,6 +877,7 @@ cmsInt32Number CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, const cmsUI
if (nInputs >= cmsMAXCHANNELS) return FALSE;
nTotalPoints = CubeSize(clutPoints, nInputs);
+ if (nTotalPoints == 0) return FALSE;
for (i = 0; i < nTotalPoints; i++) {
@@ -1298,6 +1326,9 @@ void CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStag
{
cmsStage* Anterior = NULL, *pt;
+ _cmsAssert(lut != NULL);
+ _cmsAssert(mpe != NULL);
+
switch (loc) {
case cmsAT_BEGIN:
diff --git a/src/cmsnamed.c b/src/cmsnamed.c
index e42421d..d1a86b6 100644
--- a/src/cmsnamed.c
+++ b/src/cmsnamed.c
@@ -101,7 +101,7 @@ cmsBool GrowMLUtable(cmsMLU* mlu)
AllocatedEntries = mlu ->AllocatedEntries * 2;
// Check for overflow
- if (AllocatedEntries < mlu ->AllocatedEntries) return FALSE;
+ if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE;
// Reallocate the memory
NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry));
diff --git a/src/cmstypes.c b/src/cmstypes.c
index 035e3e1..28f06d5 100644
--- a/src/cmstypes.c
+++ b/src/cmstypes.c
@@ -707,6 +707,7 @@ void *Type_Text_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
// We need to store the "\0" at the end, so +1
if (SizeOfTag == UINT_MAX) goto Error;
+
Text = (char*) _cmsMalloc(self ->ContextID, SizeOfTag + 1);
if (Text == NULL) goto Error;
@@ -1677,14 +1678,26 @@ cmsBool Write8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsUInt32Number
// Check overflow
static
-unsigned int uipow(cmsUInt32Number a, cmsUInt32Number b)
+unsigned int uipow(cmsUInt32Number n, cmsUInt32Number a, cmsUInt32Number b)
{
- cmsUInt32Number rv = 1;
+ cmsUInt32Number rv = 1, rc;
+
+ if (a == 0) return 0;
+ if (n == 0) return 0;
+
+ for (; b > 0; b--) {
- for (; b > 0; b--)
rv *= a;
- return rv;
+ // Check for overflow
+ if (rv > UINT_MAX / a) return 0;
+
+ }
+
+ rc = rv * n;
+
+ if (rv != rc / n) return 0;
+ return rc;
}
@@ -1744,7 +1757,7 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
if (!Read8bitTables(self ->ContextID, io, NewLUT, InputChannels)) goto Error;
// Get 3D CLUT. Check the overflow....
- nTabSize = (OutputChannels * uipow(CLUTpoints, InputChannels));
+ nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels);
if (nTabSize > 0) {
cmsUInt16Number *PtrW, *T;
@@ -1871,7 +1884,8 @@ cmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
// The prelinearization table
if (!Write8bitTables(self ->ContextID, io, NewLUT ->InputChannels, PreMPE)) return FALSE;
- nTabSize = (NewLUT->OutputChannels * uipow(clutPoints, NewLUT ->InputChannels));
+ nTabSize = uipow(NewLUT->OutputChannels, clutPoints, NewLUT ->InputChannels);
+ if (nTabSize > 0) {
// The 3D CLUT.
if (clut != NULL) {
@@ -1882,6 +1896,7 @@ cmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
if (!_cmsWriteUInt8Number(io, val)) return FALSE;
}
}
+ }
// The postlinearization table
if (!Write8bitTables(self ->ContextID, io, NewLUT ->OutputChannels, PostMPE)) return FALSE;
@@ -2042,7 +2057,7 @@ void *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm
if (!Read16bitTables(self ->ContextID, io, NewLUT, InputChannels, InputEntries)) goto Error;
// Get 3D CLUT
- nTabSize = (OutputChannels * uipow(CLUTpoints, InputChannels));
+ nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels);
if (nTabSize > 0) {
cmsUInt16Number *T;
@@ -2182,12 +2197,14 @@ cmsBool Type_LUT16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
if (!Write16bitTables(self ->ContextID, io, PreMPE)) return FALSE;
}
- nTabSize = (OutputChannels * uipow(clutPoints, InputChannels));
+ nTabSize = uipow(OutputChannels, clutPoints, InputChannels);
+ if (nTabSize > 0) {
// The 3D CLUT.
if (clut != NULL) {
if (!_cmsWriteUInt16Array(io, nTabSize, clut->Tab.T)) return FALSE;
}
+ }
// The postlinearization table
if (PostMPE != NULL) {
@@ -2283,6 +2300,8 @@ cmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUI
if (!_cmsReadUInt8Number(io, NULL)) return NULL;
CLUT = cmsStageAllocCLut16bitGranular(self ->ContextID, GridPoints, InputChannels, OutputChannels, NULL);
+ if (CLUT == NULL) return NULL;
+
Data = (_cmsStageCLutData*) CLUT ->Data;
// Precision can be 1 or 2 bytes
@@ -2340,26 +2359,29 @@ cmsToneCurve* ReadEmbeddedCurve(struct _cms_typehandler_struct* self, cmsIOHANDL
// Read a set of curves from specific offset
static
-cmsStage* ReadSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, int nCurves)
+cmsStage* ReadSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, cmsUInt32Number nCurves)
{
cmsToneCurve* Curves[cmsMAXCHANNELS];
- int i;
- cmsStage* Lin;
-
+ cmsUInt32Number i;
+ cmsStage* Lin = NULL;
if (nCurves > cmsMAXCHANNELS) return FALSE;
if (!io -> Seek(io, Offset)) return FALSE;
+ for (i=0; i < nCurves; i++)
+ Curves[i] = NULL;
+
for (i=0; i < nCurves; i++) {
Curves[i] = ReadEmbeddedCurve(self, io);
- if (Curves[i] == NULL) return FALSE;
- if (!_cmsReadAlignment(io)) return FALSE;
+ if (Curves[i] == NULL) goto Error;
+ if (!_cmsReadAlignment(io)) goto Error;
}
Lin = cmsStageAllocToneCurves(self ->ContextID, nCurves, Curves);
+Error:
for (i=0; i < nCurves; i++)
cmsFreeToneCurve(Curves[i]);
@@ -2427,22 +2449,22 @@ void* Type_LUTA2B_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c
if (offsetC != 0) {
mpe = ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan);
- cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
+ if (mpe != NULL) cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetM != 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetM, outputChan);
- cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
+ if (mpe != NULL) cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetMat != 0) {
mpe = ReadMatrix(self, io, BaseOffset + offsetMat);
- cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
+ if (mpe != NULL) cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetB != 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetB, outputChan);
- cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
+ if (mpe != NULL) cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
*nItems = 1;
@@ -2736,27 +2758,27 @@ void* Type_LUTB2A_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c
if (offsetB != 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetB, inputChan);
- cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
+ if (mpe != NULL) cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetMat != 0) {
mpe = ReadMatrix(self, io, BaseOffset + offsetMat);
- cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
+ if (mpe != NULL) cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetM != 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetM, inputChan);
- cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
+ if (mpe != NULL) cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetC != 0) {
mpe = ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan);
- cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
+ if (mpe != NULL) cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetA!= 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetA, outputChan);
- cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
+ if (mpe != NULL) cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
*nItems = 1;
@@ -3020,7 +3042,10 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
prefix[31] = suffix[31] = 0;
v = cmsAllocNamedColorList(self ->ContextID, count, nDeviceCoords, prefix, suffix);
- if (v == NULL) return NULL;
+ if (v == NULL) {
+ cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many named colors '%d'", count);
+ return NULL;
+ }
if (nDeviceCoords > cmsMAXCHANNELS) {
cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many device coordinates '%d'", nDeviceCoords);
@@ -3168,6 +3193,8 @@ void *Type_ProfileSequenceDesc_Read(struct _cms_typehandler_struct* self, cmsIOH
*nItems = 0;
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
+
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
@@ -3183,15 +3210,19 @@ void *Type_ProfileSequenceDesc_Read(struct _cms_typehandler_struct* self, cmsIOH
cmsPSEQDESC* sec = &OutSeq -> seq[i];
if (!_cmsReadUInt32Number(io, &sec ->deviceMfg)) return NULL;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
if (!_cmsReadUInt32Number(io, &sec ->deviceModel)) return NULL;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
if (!_cmsReadUInt64Number(io, &sec ->attributes)) return NULL;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt64Number);
if (!_cmsReadUInt32Number(io, (cmsUInt32Number *)&sec ->technology)) return NULL;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
if (!ReadEmbeddedText(self, io, &sec ->Manufacturer, SizeOfTag)) return NULL;
@@ -3409,26 +3440,33 @@ void *Type_UcrBg_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm
// First curve is Under color removal
if (!_cmsReadUInt32Number(io, &CountUcr)) return NULL;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
n ->Ucr = cmsBuildTabulatedToneCurve16(self ->ContextID, CountUcr, NULL);
if (n ->Ucr == NULL) return NULL;
if (!_cmsReadUInt16Array(io, CountUcr, n ->Ucr->Table16)) return NULL;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= CountUcr * sizeof(cmsUInt16Number);
// Second curve is Black generation
if (!_cmsReadUInt32Number(io, &CountBg)) return NULL;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
n ->Bg = cmsBuildTabulatedToneCurve16(self ->ContextID, CountBg, NULL);
if (n ->Bg == NULL) return NULL;
if (!_cmsReadUInt16Array(io, CountBg, n ->Bg->Table16)) return NULL;
+ if (SizeOfTag < CountBg * sizeof(cmsUInt16Number)) return NULL;
SizeOfTag -= CountBg * sizeof(cmsUInt16Number);
+ if (SizeOfTag == UINT_MAX) return NULL;
// Now comes the text. The length is specified by the tag size
n ->Desc = cmsMLUalloc(self ->ContextID, 1);
- ASCIIString = (char*) _cmsMalloc(self ->ContextID, sizeof(cmsUInt8Number)*(SizeOfTag + 1));
+ if (n ->Desc == NULL) return NULL;
+
+ ASCIIString = (char*) _cmsMalloc(self ->ContextID, SizeOfTag + 1);
if (io ->Read(io, ASCIIString, sizeof(char), SizeOfTag) != SizeOfTag) return NULL;
ASCIIString[SizeOfTag] = 0;
cmsMLUsetASCII(n ->Desc, cmsNoLanguage, cmsNoCountry, ASCIIString);
@@ -3525,7 +3563,9 @@ cmsBool ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
if (!_cmsReadUInt32Number(io, &Count)) return FALSE;
+ if (Count > UINT_MAX - sizeof(cmsUInt32Number)) return FALSE;
if (*SizeOfTag < Count + sizeof(cmsUInt32Number)) return FALSE;
+
Text = (char*) _cmsMalloc(self ->ContextID, Count+1);
if (Text == NULL) return FALSE;
@@ -3643,6 +3683,9 @@ void *Type_Screening_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
if (!_cmsReadUInt32Number(io, &sc ->Flag)) goto Error;
if (!_cmsReadUInt32Number(io, &sc ->nChannels)) goto Error;
+ if (sc ->nChannels > cmsMAXCHANNELS - 1)
+ sc ->nChannels = cmsMAXCHANNELS - 1;
+
for (i=0; i < sc ->nChannels; i++) {
if (!_cmsRead15Fixed16Number(io, &sc ->Channels[i].Frequency)) goto Error;
@@ -3821,6 +3864,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
if (!_cmsReadUInt16Number(io, &nSegments)) return NULL;
if (!_cmsReadUInt16Number(io, NULL)) return NULL;
+ if (nSegments < 1) return NULL;
Segments = (cmsCurveSegment*) _cmsCalloc(self ->ContextID, nSegments, sizeof(cmsCurveSegment));
if (Segments == NULL) return NULL;
@@ -4180,7 +4224,7 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
// Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number
nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans;
- for (i=0; i < nMaxGrids; i++) GridPoints[i] = Dimensions8[i];
+ for (i=0; i < nMaxGrids; i++) GridPoints[i] = (cmsUInt32Number) Dimensions8[i];
// Allocate the true CLUT
mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL);