--- old/src/share/native/sun/java2d/cmm/lcms/cmstypes.c 2016-07-26 11:31:39.126889565 -0700 +++ new/src/share/native/sun/java2d/cmm/lcms/cmstypes.c 2016-07-26 11:31:38.998889562 -0700 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2014 Marti Maria Saguer +// Copyright (c) 1998-2016 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -59,7 +59,7 @@ // This file implements every single tag and tag type as described in the ICC spec. Some types // have been deprecated, like ncl and Data. There is no implementation for those types as there // are no profiles holding them. The programmer can also extend this list by defining his own types -// by using the appropiate plug-in. There are three types of plug ins regarding that. First type +// by using the appropriate plug-in. There are three types of plug ins regarding that. First type // allows to define new tags using any existing type. Next plug-in type allows to define new types // and the third one is very specific: allows to extend the number of elements in the multiprocessing // elements special type. @@ -142,7 +142,7 @@ } -// Auxiliar to convert UTF-32 to UTF-16 in some cases +// Auxiliary to convert UTF-32 to UTF-16 in some cases static cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array) { @@ -158,7 +158,7 @@ return TRUE; } -// Auxiliar to read an array of wchar_t +// Auxiliary to read an array of wchar_t static cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array) { @@ -189,7 +189,7 @@ cmsUInt32Number n, cmsUInt32Number SizeOfTag); -// Helper function to deal with position tables as decribed in ICC spec 4.3 +// Helper function to deal with position tables as described in ICC spec 4.3 // A table of n elements is readed, where first comes n records containing offsets and sizes and // then a block containing the data itself. This allows to reuse same data in more than one entry static @@ -980,7 +980,7 @@ cmsMLU* mlu = (cmsMLU*) Ptr; char *Text = NULL; wchar_t *Wide = NULL; - cmsUInt32Number len, len_aligned, len_filler_alignment; + cmsUInt32Number len, len_text, len_tag_requirement, len_aligned; cmsBool rc = FALSE; char Filler[68]; @@ -990,17 +990,18 @@ // Get the len of string len = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0); - // From ICC3.4: It has been found that textDescriptionType can contain misaligned data + // Specification ICC.1:2001-04 (v2.4.0): It has been found that textDescriptionType can contain misaligned data //(see clause 4.1 for the definition of “aligned”). Because the Unicode language // code and Unicode count immediately follow the ASCII description, their // alignment is not correct if the ASCII count is not a multiple of four. The // ScriptCode code is misaligned when the ASCII count is odd. Profile reading and // writing software must be written carefully in order to handle these alignment // problems. - - // Compute an aligned size - len_aligned = _cmsALIGNLONG(len); - len_filler_alignment = len_aligned - len; + // + // The above last sentence suggest to handle alignment issues in the + // parser. The provided example (Table 69 on Page 60) makes this clear. + // The padding only in the ASCII count is not sufficient for a aligned tag + // size, with the same text size in ASCII and Unicode. // Null strings if (len <= 0) { @@ -1021,6 +1022,12 @@ cmsMLUgetWide(mlu, cmsNoLanguage, cmsNoCountry, Wide, len * sizeof(wchar_t)); } + // Tell the real text len including the null terminator and padding + len_text = (cmsUInt32Number) strlen(Text) + 1; + // Compute an total tag size requirement + len_tag_requirement = (8+4+len_text+4+4+2*len_text+2+1+67); + len_aligned = _cmsALIGNLONG(len_tag_requirement); + // * cmsUInt32Number count; * Description length // * cmsInt8Number desc[count] * NULL terminated ascii string // * cmsUInt32Number ucLangCode; * UniCode language code @@ -1030,20 +1037,14 @@ // * cmsUInt8Number scCount; * ScriptCode count // * cmsInt8Number scDesc[67]; * ScriptCode Description - if (!_cmsWriteUInt32Number(io, len_aligned)) goto Error; - if (!io ->Write(io, len, Text)) goto Error; - if (!io ->Write(io, len_filler_alignment, Filler)) goto Error; + if (!_cmsWriteUInt32Number(io, len_text)) goto Error; + if (!io ->Write(io, len_text, Text)) goto Error; if (!_cmsWriteUInt32Number(io, 0)) goto Error; // ucLanguageCode - // This part is tricky: we need an aligned tag size, and the ScriptCode part - // takes 70 bytes, so we need 2 extra bytes to do the alignment - - if (!_cmsWriteUInt32Number(io, len_aligned+1)) goto Error; - + if (!_cmsWriteUInt32Number(io, len_text)) goto Error; // Note that in some compilers sizeof(cmsUInt16Number) != sizeof(wchar_t) - if (!_cmsWriteWCharArray(io, len, Wide)) goto Error; - if (!_cmsWriteUInt16Array(io, len_filler_alignment+1, (cmsUInt16Number*) Filler)) goto Error; + if (!_cmsWriteWCharArray(io, len_text, Wide)) goto Error; // ScriptCode Code & count (unused) if (!_cmsWriteUInt16Number(io, 0)) goto Error; @@ -1051,6 +1052,10 @@ if (!io ->Write(io, 67, Filler)) goto Error; + // possibly add pad at the end of tag + if(len_aligned - len_tag_requirement > 0) + if (!io ->Write(io, len_aligned - len_tag_requirement, Filler)) goto Error; + rc = TRUE; Error: @@ -1498,7 +1503,7 @@ LargestPosition = EndOfThisString; } - // Now read the remaining of tag and fill all strings. Substract the directory + // Now read the remaining of tag and fill all strings. Subtract the directory SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number); if (SizeOfTag == 0) { @@ -1532,7 +1537,7 @@ cmsMLU* mlu =(cmsMLU*) Ptr; cmsUInt32Number HeaderSize; cmsUInt32Number Len, Offset; - int i; + cmsUInt32Number i; if (Ptr == NULL) { @@ -3133,6 +3138,8 @@ memset(Colorant, 0, sizeof(Colorant)); if (io -> Read(io, Root, 32, 1) != 1) return NULL; + Root[32] = 0; // To prevent exploits + if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error; if (!_cmsReadUInt16Array(io, nDeviceCoords, Colorant)) goto Error; @@ -3155,8 +3162,8 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) { cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr; - char prefix[32]; // Prefix for each color name - char suffix[32]; // Suffix for each color name + char prefix[33]; // Prefix for each color name + char suffix[33]; // Suffix for each color name int i, nColors; nColors = cmsNamedColorCount(NamedColorList); @@ -3168,7 +3175,7 @@ strncpy(prefix, (const char*) NamedColorList->Prefix, 32); strncpy(suffix, (const char*) NamedColorList->Suffix, 32); - suffix[31] = prefix[31] = 0; + suffix[32] = prefix[32] = 0; if (!io ->Write(io, 32, prefix)) return FALSE; if (!io ->Write(io, 32, suffix)) return FALSE; @@ -3180,6 +3187,7 @@ char Root[33]; if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0; + Root[32] = 0; if (!io ->Write(io, 32 , Root)) return FALSE; if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE; if (!_cmsWriteUInt16Array(io, NamedColorList ->ColorantCount, Colorant)) return FALSE; @@ -3630,7 +3638,7 @@ -// Auxiliar, read an string specified as count + string +// Auxiliary, read an string specified as count + string static cmsBool ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section) { @@ -3879,7 +3887,7 @@ static void* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) { - return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening)); + return _cmsDupMem(self->ContextID, Ptr, sizeof(cmsICCViewingConditions)); cmsUNUSED_PARAMETER(n); } @@ -4333,13 +4341,13 @@ static cmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) { - cmsUInt8Number Dimensions8[16]; + cmsUInt8Number Dimensions8[16]; // 16 because the spec says 16 and not max number of channels cmsUInt32Number i; cmsStage* mpe = (cmsStage*) Ptr; _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data; - // Check for maximum number of channels - if (mpe -> InputChannels > 15) return FALSE; + // Check for maximum number of channels supported by lcms + if (mpe -> InputChannels > MAX_INPUT_DIMENSIONS) return FALSE; // Only floats are supported in MPE if (clut ->HasFloatValues == FALSE) return FALSE; @@ -5477,8 +5485,9 @@ { cmsSigScreeningTag, { 1, 1, { cmsSigScreeningType}, NULL }, &SupportedTags[59]}, { cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]}, { cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]}, - { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]}, - { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, NULL} + { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]}, + { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]}, + { cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL} };