Lines 260-270
void EvalCHRM(LPcmsCIEXYZ Dest, LPMAT3 C
Link Here
|
260 |
// Read profile header and validate it |
260 |
// Read profile header and validate it |
261 |
|
261 |
|
262 |
static |
262 |
static |
263 |
LPLCMSICCPROFILE ReadHeader(LPLCMSICCPROFILE Icc, LCMSBOOL lIsFromMemory) |
263 |
LPLCMSICCPROFILE ReadHeader(LPLCMSICCPROFILE Icc, |
|
|
264 |
LCMSBOOL lIsFromMemory, |
265 |
DWORD dwSize) |
264 |
{ |
266 |
{ |
265 |
icTag Tag; |
267 |
icTag Tag; |
266 |
icHeader Header; |
268 |
icHeader Header; |
267 |
icInt32Number TagCount, i; |
269 |
icInt32Number TagCount, i; |
|
|
270 |
icUInt32Number extent; |
268 |
|
271 |
|
269 |
if (Icc -> Read(&Header, sizeof(icHeader), 1, Icc) != 1) |
272 |
if (Icc -> Read(&Header, sizeof(icHeader), 1, Icc) != 1) |
270 |
goto ErrorCleanup; |
273 |
goto ErrorCleanup; |
Lines 286-291
LPLCMSICCPROFILE ReadHeader(LPLCMSICCPRO
Link Here
|
286 |
|
289 |
|
287 |
if (Header.magic != icMagicNumber) goto ErrorCleanup; |
290 |
if (Header.magic != icMagicNumber) goto ErrorCleanup; |
288 |
|
291 |
|
|
|
292 |
if (dwSize && dwSize != Header.size) { |
293 |
goto ErrorCleanup; |
294 |
} |
295 |
|
289 |
if (Icc ->Read(&TagCount, sizeof(icInt32Number), 1, Icc) != 1) |
296 |
if (Icc ->Read(&TagCount, sizeof(icInt32Number), 1, Icc) != 1) |
290 |
goto ErrorCleanup; |
297 |
goto ErrorCleanup; |
291 |
|
298 |
|
Lines 320-326
LPLCMSICCPROFILE ReadHeader(LPLCMSICCPRO
Link Here
|
320 |
|
327 |
|
321 |
// Read tag directory |
328 |
// Read tag directory |
322 |
|
329 |
|
323 |
if (TagCount > MAX_TABLE_TAG) { |
330 |
if (TagCount > MAX_TABLE_TAG || TagCount < 0) { |
324 |
|
331 |
|
325 |
cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", TagCount); |
332 |
cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", TagCount); |
326 |
goto ErrorCleanup; |
333 |
goto ErrorCleanup; |
Lines 337-344
LPLCMSICCPROFILE ReadHeader(LPLCMSICCPRO
Link Here
|
337 |
AdjustEndianess32((LPBYTE) &Tag.sig); // Signature |
344 |
AdjustEndianess32((LPBYTE) &Tag.sig); // Signature |
338 |
|
345 |
|
339 |
// Perform some sanity check. Offset + size should fall inside file. |
346 |
// Perform some sanity check. Offset + size should fall inside file. |
340 |
|
347 |
extent = Tag.offset + Tag.size; |
341 |
if (Tag.offset + Tag.size > Header.size) goto ErrorCleanup; |
348 |
if (extent > Header.size || extent < Tag.offset) |
|
|
349 |
goto ErrorCleanup; |
342 |
|
350 |
|
343 |
Icc -> TagNames[i] = Tag.sig; |
351 |
Icc -> TagNames[i] = Tag.sig; |
344 |
Icc -> TagOffsets[i] = Tag.offset; |
352 |
Icc -> TagOffsets[i] = Tag.offset; |
Lines 363-369
ErrorCleanup:
Link Here
|
363 |
} |
371 |
} |
364 |
|
372 |
|
365 |
|
373 |
|
|
|
374 |
int |
375 |
validateNewLUT(LPLUT NewLUT) { |
376 |
unsigned int calc = 1; |
377 |
unsigned int oldCalc; |
378 |
unsigned int power = NewLUT -> InputChan; |
379 |
|
380 |
if (NewLUT -> cLutPoints > 100) NewLUT ->cLutPoints = 100; |
381 |
if (NewLUT -> InputChan > MAXCHANNELS) NewLUT -> InputChan = MAXCHANNELS; |
382 |
if (NewLUT -> OutputChan > MAXCHANNELS) NewLUT -> OutputChan = MAXCHANNELS; |
383 |
|
384 |
for (; power > 0; power--) { |
385 |
oldCalc = calc; |
386 |
calc *= NewLUT -> cLutPoints; |
387 |
if (calc < oldCalc || calc < NewLUT -> cLutPoints) { |
388 |
return 0; |
389 |
} |
390 |
} |
391 |
|
392 |
oldCalc = calc; |
393 |
calc *= NewLUT -> OutputChan; |
394 |
if (calc < oldCalc || calc < NewLUT -> OutputChan) { |
395 |
return 0; |
396 |
} |
366 |
|
397 |
|
|
|
398 |
return 1; |
399 |
} |
367 |
|
400 |
|
368 |
static |
401 |
static |
369 |
unsigned int uipow(unsigned int a, unsigned int b) { |
402 |
unsigned int uipow(unsigned int a, unsigned int b) { |
Lines 493-501
LCMSBOOL ReadLUT8(LPLCMSICCPROFILE Icc,
Link Here
|
493 |
NewLUT -> OutputEntries = 256; |
526 |
NewLUT -> OutputEntries = 256; |
494 |
|
527 |
|
495 |
// Do some checking |
528 |
// Do some checking |
496 |
if (NewLUT -> cLutPoints > 100) NewLUT ->cLutPoints = 100; |
529 |
if (!validateNewLUT(NewLUT)) { |
497 |
if (NewLUT -> InputChan > MAXCHANNELS) NewLUT -> InputChan = MAXCHANNELS; |
530 |
return FALSE; |
498 |
if (NewLUT -> OutputChan > MAXCHANNELS) NewLUT -> OutputChan = MAXCHANNELS; |
531 |
} |
499 |
|
532 |
|
500 |
AdjustEndianess32((LPBYTE) &LUT8.e00); |
533 |
AdjustEndianess32((LPBYTE) &LUT8.e00); |
501 |
AdjustEndianess32((LPBYTE) &LUT8.e01); |
534 |
AdjustEndianess32((LPBYTE) &LUT8.e01); |
Lines 570-576
LCMSBOOL ReadLUT8(LPLCMSICCPROFILE Icc,
Link Here
|
570 |
|
603 |
|
571 |
if (nTabSize > 0) { |
604 |
if (nTabSize > 0) { |
572 |
|
605 |
|
573 |
PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * nTabSize); |
606 |
PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize); |
574 |
if (PtrW == NULL) return FALSE; |
607 |
if (PtrW == NULL) return FALSE; |
575 |
|
608 |
|
576 |
Temp = (LPBYTE) _cmsMalloc(nTabSize); |
609 |
Temp = (LPBYTE) _cmsMalloc(nTabSize); |
Lines 735-740
LCMSBOOL ReadLUT16(LPLCMSICCPROFILE Icc,
Link Here
|
735 |
NewLUT -> InputEntries = LUT16.inputEnt; |
768 |
NewLUT -> InputEntries = LUT16.inputEnt; |
736 |
NewLUT -> OutputEntries = LUT16.outputEnt; |
769 |
NewLUT -> OutputEntries = LUT16.outputEnt; |
737 |
|
770 |
|
|
|
771 |
if (!validateNewLUT(NewLUT)) { |
772 |
return FALSE; |
773 |
} |
738 |
|
774 |
|
739 |
// Matrix handling |
775 |
// Matrix handling |
740 |
|
776 |
|
Lines 797-803
LCMSBOOL ReadLUT16(LPLCMSICCPROFILE Icc,
Link Here
|
797 |
NewLUT->InputChan)); |
833 |
NewLUT->InputChan)); |
798 |
if (nTabSize > 0) { |
834 |
if (nTabSize > 0) { |
799 |
|
835 |
|
800 |
PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * nTabSize); |
836 |
PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize); |
801 |
if (PtrW == NULL) { |
837 |
if (PtrW == NULL) { |
802 |
_cmsFree(PtrW); |
838 |
_cmsFree(PtrW); |
803 |
return FALSE; |
839 |
return FALSE; |
Lines 1114-1121
LCMSBOOL ReadCLUT(LPLCMSICCPROFILE Icc,
Link Here
|
1114 |
if (Icc ->Read(&CLUT, sizeof(icCLutStruct), 1, Icc) != 1) return FALSE; |
1150 |
if (Icc ->Read(&CLUT, sizeof(icCLutStruct), 1, Icc) != 1) return FALSE; |
1115 |
|
1151 |
|
1116 |
|
1152 |
|
1117 |
cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], NewLUT ->InputChan, |
1153 |
if (cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], |
1118 |
NewLUT ->OutputChan); |
1154 |
NewLUT ->InputChan, |
|
|
1155 |
NewLUT ->OutputChan) == NULL) { |
1156 |
return FALSE; |
1157 |
} |
1119 |
|
1158 |
|
1120 |
// Precission can be 1 or 2 bytes |
1159 |
// Precission can be 1 or 2 bytes |
1121 |
|
1160 |
|
Lines 1163-1170
LCMSBOOL ReadSetOfCurves(LPLCMSICCPROFIL
Link Here
|
1163 |
{ |
1202 |
{ |
1164 |
LPGAMMATABLE Curves[MAXCHANNELS]; |
1203 |
LPGAMMATABLE Curves[MAXCHANNELS]; |
1165 |
unsigned int i, nCurves; |
1204 |
unsigned int i, nCurves; |
|
|
1205 |
LCMSBOOL ret = FALSE; |
1166 |
|
1206 |
|
1167 |
if (Icc -> Seek(Icc, Offset)) return FALSE; |
1207 |
if (Icc -> Seek(Icc, Offset)) return FALSE; |
|
|
1208 |
|
1209 |
ZeroMemory(Curves, sizeof(Curves)); |
1168 |
|
1210 |
|
1169 |
if (nLocation == 1 || nLocation == 3) |
1211 |
if (nLocation == 1 || nLocation == 3) |
1170 |
|
1212 |
|
Lines 1175-1191
LCMSBOOL ReadSetOfCurves(LPLCMSICCPROFIL
Link Here
|
1175 |
for (i=0; i < nCurves; i++) { |
1217 |
for (i=0; i < nCurves; i++) { |
1176 |
|
1218 |
|
1177 |
Curves[i] = ReadCurve(Icc); |
1219 |
Curves[i] = ReadCurve(Icc); |
1178 |
if (Curves[i] == NULL) return FALSE; |
1220 |
if (Curves[i] == NULL) goto free_out; |
1179 |
SkipAlignment(Icc); |
1221 |
SkipAlignment(Icc); |
1180 |
|
1222 |
|
1181 |
} |
1223 |
} |
1182 |
|
1224 |
|
1183 |
NewLUT = cmsAllocLinearTable(NewLUT, Curves, nLocation); |
1225 |
NewLUT = cmsAllocLinearTable(NewLUT, Curves, nLocation); |
1184 |
|
1226 |
|
|
|
1227 |
ret = TRUE; |
1228 |
|
1229 |
free_out: |
1185 |
for (i=0; i < nCurves; i++) |
1230 |
for (i=0; i < nCurves; i++) |
1186 |
cmsFreeGamma(Curves[i]); |
1231 |
cmsFreeGamma(Curves[i]); |
1187 |
|
1232 |
|
1188 |
return TRUE; |
1233 |
return ret; |
1189 |
|
1234 |
|
1190 |
} |
1235 |
} |
1191 |
|
1236 |
|
Lines 1208-1213
LCMSBOOL ReadLUT_A2B(LPLCMSICCPROFILE Ic
Link Here
|
1208 |
NewLUT -> InputChan = LUT16.inputChan; |
1253 |
NewLUT -> InputChan = LUT16.inputChan; |
1209 |
NewLUT -> OutputChan = LUT16.outputChan; |
1254 |
NewLUT -> OutputChan = LUT16.outputChan; |
1210 |
|
1255 |
|
|
|
1256 |
// Validate the NewLUT here to avoid excessive number of channels |
1257 |
// (leading to stack-based buffer overflow in ReadSetOfCurves). |
1258 |
// Needs revalidation after table size is filled in. |
1259 |
if (!validateNewLUT(NewLUT)) { |
1260 |
return FALSE; |
1261 |
} |
1262 |
|
1211 |
AdjustEndianess32((LPBYTE) &LUT16.offsetB); |
1263 |
AdjustEndianess32((LPBYTE) &LUT16.offsetB); |
1212 |
AdjustEndianess32((LPBYTE) &LUT16.offsetMat); |
1264 |
AdjustEndianess32((LPBYTE) &LUT16.offsetMat); |
1213 |
AdjustEndianess32((LPBYTE) &LUT16.offsetM); |
1265 |
AdjustEndianess32((LPBYTE) &LUT16.offsetM); |
Lines 1267-1272
LCMSBOOL ReadLUT_B2A(LPLCMSICCPROFILE Ic
Link Here
|
1267 |
NewLUT -> InputChan = LUT16.inputChan; |
1319 |
NewLUT -> InputChan = LUT16.inputChan; |
1268 |
NewLUT -> OutputChan = LUT16.outputChan; |
1320 |
NewLUT -> OutputChan = LUT16.outputChan; |
1269 |
|
1321 |
|
|
|
1322 |
// Validate the NewLUT here to avoid excessive number of channels |
1323 |
// (leading to stack-based buffer overflow in ReadSetOfCurves). |
1324 |
// Needs revalidation after table size is filled in. |
1325 |
if (!validateNewLUT(NewLUT)) { |
1326 |
return FALSE; |
1327 |
} |
1328 |
|
1270 |
AdjustEndianess32((LPBYTE) &LUT16.offsetB); |
1329 |
AdjustEndianess32((LPBYTE) &LUT16.offsetB); |
1271 |
AdjustEndianess32((LPBYTE) &LUT16.offsetMat); |
1330 |
AdjustEndianess32((LPBYTE) &LUT16.offsetMat); |
1272 |
AdjustEndianess32((LPBYTE) &LUT16.offsetM); |
1331 |
AdjustEndianess32((LPBYTE) &LUT16.offsetM); |
Lines 1415-1420
int ReadEmbeddedTextTag(LPLCMSICCPROFILE
Link Here
|
1415 |
|
1474 |
|
1416 |
|
1475 |
|
1417 |
BaseType = ReadBase(Icc); |
1476 |
BaseType = ReadBase(Icc); |
|
|
1477 |
// Looks broken: size could be 0, or essentially < sizeof(icTagBase) here. |
1418 |
size -= sizeof(icTagBase); |
1478 |
size -= sizeof(icTagBase); |
1419 |
|
1479 |
|
1420 |
switch (BaseType) { |
1480 |
switch (BaseType) { |
Lines 1557-1562
int ReadEmbeddedTextTag(LPLCMSICCPROFILE
Link Here
|
1557 |
for (i=0; i < Offset; i++) { |
1617 |
for (i=0; i < Offset; i++) { |
1558 |
|
1618 |
|
1559 |
char Discard; |
1619 |
char Discard; |
|
|
1620 |
// No return checking; could lead to large loop in |
1621 |
// combination with int oflow above computing Offset. |
1560 |
Icc ->Read(&Discard, 1, 1, Icc); |
1622 |
Icc ->Read(&Discard, 1, 1, Icc); |
1561 |
} |
1623 |
} |
1562 |
|
1624 |
|
Lines 1572-1577
int ReadEmbeddedTextTag(LPLCMSICCPROFILE
Link Here
|
1572 |
AdjustEndianessArray16((LPWORD) wchar, Len / 2); |
1634 |
AdjustEndianessArray16((LPWORD) wchar, Len / 2); |
1573 |
|
1635 |
|
1574 |
wchar[Len / 2] = L'\0'; |
1636 |
wchar[Len / 2] = L'\0'; |
|
|
1637 |
// Failure to null terminate "Name". |
1575 |
i = wcstombs(Name, wchar, size_max ); |
1638 |
i = wcstombs(Name, wchar, size_max ); |
1576 |
if (i == ((size_t) -1)) { |
1639 |
if (i == ((size_t) -1)) { |
1577 |
|
1640 |
|
Lines 1941-1946
int cmsReadICCnamedColorList(cmsHTRANSFO
Link Here
|
1941 |
char Root[33]; |
2004 |
char Root[33]; |
1942 |
|
2005 |
|
1943 |
ZeroMemory(Colorant, sizeof(WORD) * MAXCHANNELS); |
2006 |
ZeroMemory(Colorant, sizeof(WORD) * MAXCHANNELS); |
|
|
2007 |
// No return value checking; could cause trouble with |
2008 |
// large count. |
1944 |
Icc -> Read(Root, 1, 32, Icc); |
2009 |
Icc -> Read(Root, 1, 32, Icc); |
1945 |
Icc -> Read(PCS, 3, sizeof(WORD), Icc); |
2010 |
Icc -> Read(PCS, 3, sizeof(WORD), Icc); |
1946 |
|
2011 |
|
Lines 1974-1980
int cmsReadICCnamedColorList(cmsHTRANSFO
Link Here
|
1974 |
|
2039 |
|
1975 |
LPcmsNAMEDCOLORLIST LCMSEXPORT cmsReadColorantTable(cmsHPROFILE hProfile, icTagSignature sig) |
2040 |
LPcmsNAMEDCOLORLIST LCMSEXPORT cmsReadColorantTable(cmsHPROFILE hProfile, icTagSignature sig) |
1976 |
{ |
2041 |
{ |
1977 |
icInt32Number n, Count, i; |
2042 |
icInt32Number n; |
|
|
2043 |
icUInt32Number Count, i; |
1978 |
size_t offset; |
2044 |
size_t offset; |
1979 |
icTagTypeSignature BaseType; |
2045 |
icTagTypeSignature BaseType; |
1980 |
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; |
2046 |
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; |
Lines 2315-2320
LPcmsSEQ LCMSEXPORT cmsReadProfileSequen
Link Here
|
2315 |
Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc); |
2381 |
Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc); |
2316 |
AdjustEndianess32((LPBYTE) &Count); |
2382 |
AdjustEndianess32((LPBYTE) &Count); |
2317 |
|
2383 |
|
|
|
2384 |
if (Count > 1000) { |
2385 |
return NULL; |
2386 |
} |
2318 |
size = sizeof(int) + Count * sizeof(cmsPSEQDESC); |
2387 |
size = sizeof(int) + Count * sizeof(cmsPSEQDESC); |
2319 |
OutSeq = (LPcmsSEQ) _cmsMalloc(size); |
2388 |
OutSeq = (LPcmsSEQ) _cmsMalloc(size); |
2320 |
if (OutSeq == NULL) return NULL; |
2389 |
if (OutSeq == NULL) return NULL; |
Lines 2495-2501
cmsHPROFILE LCMSEXPORT cmsOpenProfileFro
Link Here
|
2495 |
NewIcc = _cmsCreateProfileFromFilePlaceholder(lpFileName); |
2564 |
NewIcc = _cmsCreateProfileFromFilePlaceholder(lpFileName); |
2496 |
if (!NewIcc) return NULL; |
2565 |
if (!NewIcc) return NULL; |
2497 |
|
2566 |
|
2498 |
if (!ReadHeader(NewIcc, FALSE)) return NULL; |
2567 |
if (!ReadHeader(NewIcc, FALSE, 0)) return NULL; |
2499 |
|
2568 |
|
2500 |
ReadCriticalTags(NewIcc); |
2569 |
ReadCriticalTags(NewIcc); |
2501 |
|
2570 |
|
Lines 2515-2521
cmsHPROFILE LCMSEXPORT cmsOpenProfileFro
Link Here
|
2515 |
NewIcc = _cmsCreateProfileFromMemPlaceholder(MemPtr, dwSize); |
2584 |
NewIcc = _cmsCreateProfileFromMemPlaceholder(MemPtr, dwSize); |
2516 |
if (!NewIcc) return NULL; |
2585 |
if (!NewIcc) return NULL; |
2517 |
|
2586 |
|
2518 |
if (!ReadHeader(NewIcc, TRUE)) return NULL; |
2587 |
if (!ReadHeader(NewIcc, TRUE, dwSize)) return NULL; |
2519 |
|
2588 |
|
2520 |
ReadCriticalTags(NewIcc); |
2589 |
ReadCriticalTags(NewIcc); |
2521 |
|
2590 |
|