diff options
author | Marti Maria <info@littlecms.com> | 2010-10-21 12:50:46 +0200 |
---|---|---|
committer | Marti Maria <info@littlecms.com> | 2010-10-21 12:50:46 +0200 |
commit | 4bd08b41fa98610816e73999297ed1648fe8b999 (patch) | |
tree | 9e77cf3bcc025ce54d2bff74b2a84060e8c5b570 | |
parent | 80966a65a38ea9cb140b7fdba6bb3d32af0195db (diff) | |
download | lcms2-4bd08b41fa98610816e73999297ed1648fe8b999.tar.gz |
2.1 code review changes
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/cmserr.c | 5 | ||||
-rw-r--r-- | src/cmsgamma.c | 4 | ||||
-rw-r--r-- | src/cmsio0.c | 9 | ||||
-rw-r--r-- | src/cmslut.c | 18 | ||||
-rw-r--r-- | src/cmsnamed.c | 3 | ||||
-rw-r--r-- | src/cmstypes.c | 21 |
7 files changed, 54 insertions, 10 deletions
@@ -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; |