| diff --git a/third_party/lcms/src/cmsintrp.c b/third_party/lcms/src/cmsintrp.c |
| index 3d9a40530..22de3e550 100644 |
| --- a/third_party/lcms/src/cmsintrp.c |
| +++ b/third_party/lcms/src/cmsintrp.c |
| @@ -200,8 +200,8 @@ void LinLerp1D(CMSREGISTER const cmsUInt16Number Value[], |
| int val3; |
| const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table; |
| |
| - // if last value... |
| - if (Value[0] == 0xffff) { |
| + // if last value or just one point |
| + if (Value[0] == 0xffff || p->Domain[0] == 0) { |
| |
| Output[0] = LutTable[p -> Domain[0]]; |
| } |
| @@ -240,7 +240,7 @@ void LinLerp1Dfloat(const cmsFloat32Number Value[], |
| val2 = fclamp(Value[0]); |
| |
| // if last value... |
| - if (val2 == 1.0) { |
| + if (val2 == 1.0 || p->Domain[0] == 0) { |
| Output[0] = LutTable[p -> Domain[0]]; |
| } |
| else |
| @@ -274,20 +274,34 @@ void Eval1Input(CMSREGISTER const cmsUInt16Number Input[], |
| cmsUInt32Number OutChan; |
| const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table; |
| |
| - v = Input[0] * p16 -> Domain[0]; |
| - fk = _cmsToFixedDomain(v); |
| |
| - k0 = FIXED_TO_INT(fk); |
| - rk = (cmsUInt16Number) FIXED_REST_TO_INT(fk); |
| + // if last value... |
| + if (Input[0] == 0xffff || p16->Domain[0] == 0) { |
| + |
| + cmsUInt16Number y0 = LutTable[p16->Domain[0]]; |
| + |
| + for (OutChan = 0; OutChan < p16->nOutputs; OutChan++) { |
| + Output[OutChan] = y0; |
| + } |
| + } |
| + else |
| + { |
| + |
| + v = Input[0] * p16->Domain[0]; |
| + fk = _cmsToFixedDomain(v); |
| + |
| + k0 = FIXED_TO_INT(fk); |
| + rk = (cmsUInt16Number)FIXED_REST_TO_INT(fk); |
| |
| - k1 = k0 + (Input[0] != 0xFFFFU ? 1 : 0); |
| + k1 = k0 + (Input[0] != 0xFFFFU ? 1 : 0); |
| |
| - K0 = p16 -> opta[0] * k0; |
| - K1 = p16 -> opta[0] * k1; |
| + K0 = p16->opta[0] * k0; |
| + K1 = p16->opta[0] * k1; |
| |
| - for (OutChan=0; OutChan < p16->nOutputs; OutChan++) { |
| + for (OutChan = 0; OutChan < p16->nOutputs; OutChan++) { |
| |
| - Output[OutChan] = LinearInterp(rk, LutTable[K0+OutChan], LutTable[K1+OutChan]); |
| + Output[OutChan] = LinearInterp(rk, LutTable[K0 + OutChan], LutTable[K1 + OutChan]); |
| + } |
| } |
| } |
| |
| @@ -308,7 +322,7 @@ void Eval1InputFloat(const cmsFloat32Number Value[], |
| val2 = fclamp(Value[0]); |
| |
| // if last value... |
| - if (val2 == 1.0) { |
| + if (val2 == 1.0 || p->Domain[0] == 0) { |
| |
| y0 = LutTable[p->Domain[0]]; |
| |
| diff --git a/third_party/lcms/src/cmsio0.c b/third_party/lcms/src/cmsio0.c |
| index 743b958df..ff8c464fc 100644 |
| --- a/third_party/lcms/src/cmsio0.c |
| +++ b/third_party/lcms/src/cmsio0.c |
| @@ -1538,8 +1538,12 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig) |
| if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return NULL; |
| |
| n = _cmsSearchTag(Icc, sig, TRUE); |
| - if (n < 0) goto Error; // Not found, return NULL |
| - |
| + if (n < 0) |
| + { |
| + // Not found, return NULL |
| + _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex); |
| + return NULL; |
| + } |
| |
| // If the element is already in memory, return the pointer |
| if (Icc -> TagPtrs[n]) { |
| diff --git a/third_party/lcms/src/cmstypes.c b/third_party/lcms/src/cmstypes.c |
| index 825b11eb1..49207735b 100644 |
| --- a/third_party/lcms/src/cmstypes.c |
| +++ b/third_party/lcms/src/cmstypes.c |
| @@ -3515,42 +3515,48 @@ void *Type_UcrBg_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm |
| { |
| cmsUcrBg* n = (cmsUcrBg*) _cmsMallocZero(self ->ContextID, sizeof(cmsUcrBg)); |
| cmsUInt32Number CountUcr, CountBg; |
| + cmsInt32Number SignedSizeOfTag = (cmsInt32Number)SizeOfTag; |
| char* ASCIIString; |
| |
| *nItems = 0; |
| if (n == NULL) return NULL; |
| |
| // First curve is Under color removal |
| + |
| + if (SignedSizeOfTag < sizeof(cmsUInt32Number)) return NULL; |
| if (!_cmsReadUInt32Number(io, &CountUcr)) return NULL; |
| - if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; |
| - SizeOfTag -= sizeof(cmsUInt32Number); |
| + SignedSizeOfTag -= sizeof(cmsUInt32Number); |
| |
| n ->Ucr = cmsBuildTabulatedToneCurve16(self ->ContextID, CountUcr, NULL); |
| if (n ->Ucr == NULL) return NULL; |
| |
| + if (SignedSizeOfTag < (cmsInt32Number)CountUcr * sizeof(cmsUInt16Number)) return NULL; |
| if (!_cmsReadUInt16Array(io, CountUcr, n ->Ucr->Table16)) return NULL; |
| - if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; |
| - SizeOfTag -= CountUcr * sizeof(cmsUInt16Number); |
| + |
| + SignedSizeOfTag -= CountUcr * sizeof(cmsUInt16Number); |
| |
| // Second curve is Black generation |
| + |
| + if (SignedSizeOfTag < sizeof(cmsUInt32Number)) return NULL; |
| if (!_cmsReadUInt32Number(io, &CountBg)) return NULL; |
| - if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; |
| - SizeOfTag -= sizeof(cmsUInt32Number); |
| + SignedSizeOfTag -= sizeof(cmsUInt32Number); |
| |
| n ->Bg = cmsBuildTabulatedToneCurve16(self ->ContextID, CountBg, NULL); |
| if (n ->Bg == NULL) return NULL; |
| + |
| + if (SignedSizeOfTag < (cmsInt32Number) CountBg * sizeof(cmsUInt16Number)) 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; |
| + SignedSizeOfTag -= CountBg * sizeof(cmsUInt16Number); |
| + |
| + if (SignedSizeOfTag < 0 || SignedSizeOfTag > 32000) return NULL; |
| |
| // Now comes the text. The length is specified by the tag size |
| n ->Desc = cmsMLUalloc(self ->ContextID, 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; |
| + ASCIIString = (char*) _cmsMalloc(self ->ContextID, SignedSizeOfTag + 1); |
| + if (io ->Read(io, ASCIIString, sizeof(char), SignedSizeOfTag) != (cmsUInt32Number) SignedSizeOfTag) return NULL; |
| + ASCIIString[SignedSizeOfTag] = 0; |
| cmsMLUsetASCII(n ->Desc, cmsNoLanguage, cmsNoCountry, ASCIIString); |
| _cmsFree(self ->ContextID, ASCIIString); |
| |