--- src/cmsio1.c +++ src/cmsio1.c @@ -345,13 +345,14 @@ ErrorCleanup: Icc ->Close(Icc); - free(Icc); if (lIsFromMemory) cmsSignalError(LCMS_ERRC_ABORTED, "Corrupted memory profile"); else cmsSignalError(LCMS_ERRC_ABORTED, "Corrupted profile: '%s'", Icc->PhysicalFile); + + free(Icc); return NULL; } @@ -1317,7 +1318,7 @@ // handles such special case. static -int ReadEmbeddedTextTag(LPLCMSICCPROFILE Icc, size_t size, char* Name) +int ReadEmbeddedTextTag(LPLCMSICCPROFILE Icc, size_t size, char* Name, size_t size_max) { icTagTypeSignature BaseType; @@ -1336,18 +1337,25 @@ icUInt8Number ScriptCodeCount; Icc ->Read(&AsciiCount, sizeof(icUInt32Number), 1, Icc); + + if (size < sizeof(icUInt32Number)) return (int) size; size -= sizeof(icUInt32Number); AdjustEndianess32((LPBYTE) &AsciiCount); - Icc ->Read(Name, 1, AsciiCount, Icc); + Icc ->Read(Name, 1, + (AsciiCount >= size_max) ? (size_max-1) : AsciiCount, Icc); + + if (size < AsciiCount) return (int) size; size -= AsciiCount; // Skip Unicode code Icc ->Read(&UnicodeCode, sizeof(icUInt32Number), 1, Icc); + if (size < sizeof(icUInt32Number)) return (int) size; size -= sizeof(icUInt32Number); Icc ->Read(&UnicodeCount, sizeof(icUInt32Number), 1, Icc); + if (size < sizeof(icUInt32Number)) return (int) size; size -= sizeof(icUInt32Number); AdjustEndianess32((LPBYTE) &UnicodeCount); @@ -1378,8 +1386,21 @@ case icSigCopyrightTag: // Broken profiles from agfa does store copyright info in such type case icSigTextType: + { + char Dummy; + size_t i, Missing = 0; + + if (size >= size_max) { + + Missing = size - size_max + 1; + size = size_max - 1; + } Icc -> Read(Name, 1, size, Icc); + + for (i=0; i < Missing; i++) + Icc -> Read(&Dummy, 1, 1, Icc); + } break; // MultiLocalizedUnicodeType, V4 only @@ -1453,7 +1474,7 @@ AdjustEndianessArray16((LPWORD) wchar, Len / 2); wchar[Len / 2] = L'\0'; - i = wcstombs(Name, wchar, 2047 ); + i = wcstombs(Name, wchar, size_max ); if (i == ((size_t) -1)) { Name[0] = 0; // Error @@ -1475,7 +1496,7 @@ // Take an ASCII item -int LCMSEXPORT cmsReadICCText(cmsHPROFILE hProfile, icTagSignature sig, char *Name) +int LCMSEXPORT cmsReadICCTextEx(cmsHPROFILE hProfile, icTagSignature sig, char *Name, size_t size_max) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; size_t offset, size; @@ -1497,10 +1518,15 @@ if (Icc -> Seek(Icc, offset)) return -1; - return ReadEmbeddedTextTag(Icc, size, Name); - + return ReadEmbeddedTextTag(Icc, size, Name, size_max); } +// Keep compatibility with older versions + +int LCMSEXPORT cmsReadICCText(cmsHPROFILE hProfile, icTagSignature sig, char *Text) +{ + return cmsReadICCTextEx(hProfile, sig, Text, 512); +} // Take an XYZ item @@ -1796,6 +1822,7 @@ if (!CheckHeader(v->NamedColorList, &nc2)) { cmsSignalError(LCMS_ERRC_WARNING, "prefix/suffix/device for named color profiles mismatch."); + return 0; } strncpy(v ->NamedColorList->Prefix, nc2.prefix, 32); @@ -2030,7 +2057,7 @@ if (cmsIsTag(hProfile, icSigCopyrightTag)) { - char Copyright[2048]; + char Copyright[512]; cmsReadICCText(hProfile, icSigCopyrightTag, Copyright); strcat(Info, Copyright); @@ -2047,7 +2074,7 @@ if (cmsIsTag(hProfile, K007)) { - char MonCal[1024]; + char MonCal[512]; cmsReadICCText(hProfile, K007, MonCal); strcat(Info, MonCal); @@ -2094,7 +2121,7 @@ return FALSE; } - if (cmsReadICCText(hProfile, icSigCharTargetTag, *Data) < 0) + if (cmsReadICCTextEx(hProfile, icSigCharTargetTag, *Data, *len) < 0) return FALSE; (*Data)[*len] = 0; // Force a zero marker. Shouldn't be needed, but is @@ -2200,8 +2227,8 @@ sec ->deviceModel = DescStruct.deviceModel; sec ->technology = DescStruct.technology; - if (ReadEmbeddedTextTag(Icc, size, sec ->Manufacturer) < 0) return NULL; - if (ReadEmbeddedTextTag(Icc, size, sec ->Model) < 0) return NULL; + if (ReadEmbeddedTextTag(Icc, size, sec ->Manufacturer, 512) < 0) return NULL; + if (ReadEmbeddedTextTag(Icc, size, sec ->Model, 512) < 0) return NULL; } @@ -2335,7 +2362,7 @@ return NULL; } - ReadEmbeddedTextTag(Icc, 256, gex ->Description); + ReadEmbeddedTextTag(Icc, 256, gex ->Description, 512); // Read viewing conditions @@ -3566,12 +3593,14 @@ // update BytesSaved so caller knows how many bytes are needed for MemPtr *BytesNeeded = Icc ->UsedSpace; + CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE)); return TRUE; } if (*BytesNeeded < Icc ->UsedSpace) { // need at least UsedSpace in MemPtr to continue + CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE)); return FALSE; }