summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Maria <info@littlecms.com>2010-10-21 12:50:46 +0200
committerMarti Maria <info@littlecms.com>2010-10-21 12:50:46 +0200
commit4bd08b41fa98610816e73999297ed1648fe8b999 (patch)
tree9e77cf3bcc025ce54d2bff74b2a84060e8c5b570
parent80966a65a38ea9cb140b7fdba6bb3d32af0195db (diff)
downloadlcms2-4bd08b41fa98610816e73999297ed1648fe8b999.tar.gz
2.1 code review changes
-rw-r--r--ChangeLog4
-rw-r--r--src/cmserr.c5
-rw-r--r--src/cmsgamma.c4
-rw-r--r--src/cmsio0.c9
-rw-r--r--src/cmslut.c18
-rw-r--r--src/cmsnamed.c3
-rw-r--r--src/cmstypes.c21
7 files changed, 54 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 63b69c8..c7f88d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,4 +14,6 @@ Fixed some typos in error messages
Peliminary Delphi wrapper
Fixed a bug in tificc in floating point formats
Fixed a bug in device link creation on v4 profiles
-Fixed a bug in psid and profile sequence tags \ No newline at end of file
+Fixed a bug in psid and profile sequence tags
+Fixed memory leaks on when recovering from errors
+Fixed an issue on curve inversion \ No newline at end of file
diff --git a/src/cmserr.c b/src/cmserr.c
index 4a55024..b8fda2d 100644
--- a/src/cmserr.c
+++ b/src/cmserr.c
@@ -131,6 +131,11 @@ void* _cmsCallocDefaultFn(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Nu
{
cmsUInt32Number Total = num * size;
+ // Preserve calloc behaviour
+ if (Total == 0) return NULL;
+
+ if (num >= UINT_MAX / size) return NULL; // Safe check for overflow.
+
// Check for overflow
if (Total < num || Total < size) {
return NULL;
diff --git a/src/cmsgamma.c b/src/cmsgamma.c
index 8f8146d..ec6c41d 100644
--- a/src/cmsgamma.c
+++ b/src/cmsgamma.c
@@ -799,7 +799,7 @@ int GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const str
cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, const cmsToneCurve* InCurve)
{
cmsToneCurve *out;
- cmsFloat64Number a = 1, b = 0, y, x1, y1, x2, y2;
+ cmsFloat64Number a = 0, b = 0, y, x1, y1, x2, y2;
int i, j;
int Ascending;
@@ -830,6 +830,7 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, con
j = GetInterval(y, InCurve->Table16, InCurve->InterpParams);
if (j >= 0) {
+
// Get limits of interval
x1 = InCurve ->Table16[j];
x2 = InCurve ->Table16[j+1];
@@ -854,6 +855,7 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, con
out ->Table16[i] = _cmsQuickSaturateWord(a* y + b);
}
+
return out;
}
diff --git a/src/cmsio0.c b/src/cmsio0.c
index 08aaa0e..5cb36a9 100644
--- a/src/cmsio0.c
+++ b/src/cmsio0.c
@@ -620,6 +620,11 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
// Get size as reported in header
HeaderSize = _cmsAdjustEndianess32(Header.size);
+ // Make sure HeaderSize is lower than profile size
+ // if (HeaderSize >= ???)
+ // HeaderSize = ???;
+
+
// Get creation date/time
_cmsDecodeDateTimeNumber(&Header.date, &Icc ->Created);
@@ -635,6 +640,7 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
return FALSE;
}
+
// Read tag directory
Icc -> TagCount = 0;
for (i=0; i < TagCount; i++) {
@@ -644,7 +650,8 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
if (!_cmsReadUInt32Number(io, &Tag.size)) return FALSE;
// Perform some sanity check. Offset + size should fall inside file.
- if (Tag.offset + Tag.size > HeaderSize)
+ if (Tag.offset + Tag.size > HeaderSize ||
+ Tag.offset + Tag.size < Tag.offset)
continue;
Icc -> TagNames[Icc ->TagCount] = Tag.sig;
diff --git a/src/cmslut.c b/src/cmslut.c
index 6ee2663..11aafb7 100644
--- a/src/cmslut.c
+++ b/src/cmslut.c
@@ -168,9 +168,14 @@ void EvaluateCurves(const cmsFloat32Number In[],
cmsFloat32Number Out[],
const cmsStage *mpe)
{
- _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*) mpe ->Data;
+ _cmsStageToneCurvesData* Data;
cmsUInt32Number i;
+ _cmsAssert(mpe != NULL);
+
+ Data = (_cmsStageToneCurvesData*) mpe ->Data;
+ if (Data == NULL) return;
+
if (Data ->TheCurves == NULL) return;
for (i=0; i < Data ->nCurves; i++) {
@@ -181,9 +186,14 @@ void EvaluateCurves(const cmsFloat32Number In[],
static
void CurveSetElemTypeFree(cmsStage* mpe)
{
- _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*) mpe ->Data;
+ _cmsStageToneCurvesData* Data;
cmsUInt32Number i;
+ _cmsAssert(mpe != NULL);
+
+ Data = (_cmsStageToneCurvesData*) mpe ->Data;
+ if (Data == NULL) return;
+
if (Data ->TheCurves != NULL) {
for (i=0; i < Data ->nCurves; i++) {
if (Data ->TheCurves[i] != NULL)
@@ -373,6 +383,9 @@ cmsStage* CMSEXPORT cmsStageAllocMatrix(cmsContext ContextID, cmsUInt32Number R
n = Rows * Cols;
// Check for overflow
+ if (n == 0) return NULL;
+ if (n >= UINT_MAX / Cols) return NULL;
+ if (n >= UINT_MAX / Rows) return NULL;
if (n < Rows || n < Cols) return NULL;
NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigMatrixElemType, Cols, Rows,
@@ -611,6 +624,7 @@ 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;
diff --git a/src/cmsnamed.c b/src/cmsnamed.c
index bb12167..e42421d 100644
--- a/src/cmsnamed.c
+++ b/src/cmsnamed.c
@@ -462,6 +462,9 @@ cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v)
else
size = v ->Allocated * 2;
+ // Keep a maximum color lists can grow, 100K entries seems reasonable
+ if (size > 1024*100) return FALSE;
+
NewPtr = (_cmsNAMEDCOLOR*) _cmsRealloc(v ->ContextID, v ->List, size * sizeof(_cmsNAMEDCOLOR));
if (NewPtr == NULL)
return FALSE;
diff --git a/src/cmstypes.c b/src/cmstypes.c
index 1c02d38..035e3e1 100644
--- a/src/cmstypes.c
+++ b/src/cmstypes.c
@@ -706,6 +706,7 @@ void *Type_Text_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
*nItems = 0;
// 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;
@@ -800,13 +801,20 @@ void *Type_Data_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
cmsUInt32Number LenOfData;
*nItems = 0;
+
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
+
LenOfData = SizeOfTag - sizeof(cmsUInt32Number);
+ if (LenOfData > INT_MAX) return NULL;
BinData = (cmsICCData*) _cmsMalloc(self ->ContextID, sizeof(cmsICCData) + LenOfData - 1);
if (BinData == NULL) return NULL;
BinData ->len = LenOfData;
- if (!_cmsReadUInt32Number(io, &BinData->flag)) return NULL;
+ if (!_cmsReadUInt32Number(io, &BinData->flag)) {
+ _cmsFree(self ->ContextID, BinData);
+ return NULL;
+ }
if (io -> Read(io, BinData ->data, sizeof(cmsUInt8Number), LenOfData) != LenOfData) {
@@ -1667,11 +1675,15 @@ cmsBool Write8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsUInt32Number
}
+// Check overflow
static
-unsigned int uipow(cmsUInt32Number a, cmsUInt32Number b) {
+unsigned int uipow(cmsUInt32Number a, cmsUInt32Number b)
+{
cmsUInt32Number rv = 1;
+
for (; b > 0; b--)
rv *= a;
+
return rv;
}
@@ -1731,7 +1743,7 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
// Get input tables
if (!Read8bitTables(self ->ContextID, io, NewLUT, InputChannels)) goto Error;
- // Get 3D CLUT
+ // Get 3D CLUT. Check the overflow....
nTabSize = (OutputChannels * uipow(CLUTpoints, InputChannels));
if (nTabSize > 0) {
@@ -1988,13 +2000,12 @@ void *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm
if (!_cmsReadUInt8Number(io, &InputChannels)) return NULL;
if (!_cmsReadUInt8Number(io, &OutputChannels)) return NULL;
- if (!_cmsReadUInt8Number(io, &CLUTpoints)) return NULL;
+ if (!_cmsReadUInt8Number(io, &CLUTpoints)) return NULL; // 255 maximum
// Padding
if (!_cmsReadUInt8Number(io, NULL)) return NULL;
// Do some checking
- if (CLUTpoints > 100) goto Error;
if (InputChannels > cmsMAXCHANNELS) goto Error;
if (OutputChannels > cmsMAXCHANNELS) goto Error;