< prev index next >
src/share/native/sun/java2d/cmm/lcms/cmstypes.c
Print this page
*** 28,38 ****
// file:
//
//---------------------------------------------------------------------------------
//
// Little Color Management System
! // Copyright (c) 1998-2014 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"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
--- 28,38 ----
// file:
//
//---------------------------------------------------------------------------------
//
// Little Color Management System
! // 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"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
*** 57,67 ****
// Tag Serialization -----------------------------------------------------------------------------
// 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
// 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.
//--------------------------------------------------------------------------------------------------
--- 57,67 ----
// Tag Serialization -----------------------------------------------------------------------------
// 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 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.
//--------------------------------------------------------------------------------------------------
*** 140,150 ****
return NULL;
}
! // Auxiliar to convert UTF-32 to UTF-16 in some cases
static
cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array)
{
cmsUInt32Number i;
--- 140,150 ----
return NULL;
}
! // Auxiliary to convert UTF-32 to UTF-16 in some cases
static
cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array)
{
cmsUInt32Number i;
*** 156,166 ****
}
return TRUE;
}
! // Auxiliar to read an array of wchar_t
static
cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array)
{
cmsUInt32Number i;
cmsUInt16Number tmp;
--- 156,166 ----
}
return TRUE;
}
! // Auxiliary to read an array of wchar_t
static
cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array)
{
cmsUInt32Number i;
cmsUInt16Number tmp;
*** 187,197 ****
cmsIOHANDLER* io,
void* Cargo,
cmsUInt32Number n,
cmsUInt32Number SizeOfTag);
! // Helper function to deal with position tables as decribed 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
cmsBool ReadPositionTable(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
--- 187,197 ----
cmsIOHANDLER* io,
void* Cargo,
cmsUInt32Number n,
cmsUInt32Number SizeOfTag);
! // 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
cmsBool ReadPositionTable(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
*** 978,1008 ****
cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsMLU* mlu = (cmsMLU*) Ptr;
char *Text = NULL;
wchar_t *Wide = NULL;
! cmsUInt32Number len, len_aligned, len_filler_alignment;
cmsBool rc = FALSE;
char Filler[68];
// Used below for writting zeroes
memset(Filler, 0, sizeof(Filler));
// 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
//(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;
// Null strings
if (len <= 0) {
Text = (char*) _cmsDupMem(self ->ContextID, "", sizeof(char));
--- 978,1009 ----
cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsMLU* mlu = (cmsMLU*) Ptr;
char *Text = NULL;
wchar_t *Wide = NULL;
! cmsUInt32Number len, len_text, len_tag_requirement, len_aligned;
cmsBool rc = FALSE;
char Filler[68];
// Used below for writting zeroes
memset(Filler, 0, sizeof(Filler));
// Get the len of string
len = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0);
! // 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.
! //
! // 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) {
Text = (char*) _cmsDupMem(self ->ContextID, "", sizeof(char));
*** 1019,1058 ****
// Get both representations.
cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, len * sizeof(char));
cmsMLUgetWide(mlu, cmsNoLanguage, cmsNoCountry, Wide, len * sizeof(wchar_t));
}
// * cmsUInt32Number count; * Description length
// * cmsInt8Number desc[count] * NULL terminated ascii string
// * cmsUInt32Number ucLangCode; * UniCode language code
// * cmsUInt32Number ucCount; * UniCode description length
// * cmsInt16Number ucDesc[ucCount];* The UniCode description
// * cmsUInt16Number scCode; * ScriptCode code
// * 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, 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;
!
// 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;
// ScriptCode Code & count (unused)
if (!_cmsWriteUInt16Number(io, 0)) goto Error;
if (!_cmsWriteUInt8Number(io, 0)) goto Error;
if (!io ->Write(io, 67, Filler)) goto Error;
rc = TRUE;
Error:
if (Text) _cmsFree(self ->ContextID, Text);
if (Wide) _cmsFree(self ->ContextID, Wide);
--- 1020,1063 ----
// Get both representations.
cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, len * sizeof(char));
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
// * cmsUInt32Number ucCount; * UniCode description length
// * cmsInt16Number ucDesc[ucCount];* The UniCode description
// * cmsUInt16Number scCode; * ScriptCode code
// * cmsUInt8Number scCount; * ScriptCode count
// * cmsInt8Number scDesc[67]; * ScriptCode Description
! if (!_cmsWriteUInt32Number(io, len_text)) goto Error;
! if (!io ->Write(io, len_text, Text)) goto Error;
if (!_cmsWriteUInt32Number(io, 0)) goto Error; // ucLanguageCode
! if (!_cmsWriteUInt32Number(io, len_text)) goto Error;
// Note that in some compilers sizeof(cmsUInt16Number) != sizeof(wchar_t)
! if (!_cmsWriteWCharArray(io, len_text, Wide)) goto Error;
// ScriptCode Code & count (unused)
if (!_cmsWriteUInt16Number(io, 0)) goto Error;
if (!_cmsWriteUInt8Number(io, 0)) goto Error;
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:
if (Text) _cmsFree(self ->ContextID, Text);
if (Wide) _cmsFree(self ->ContextID, Wide);
*** 1496,1506 ****
EndOfThisString = BeginOfThisString + Len;
if (EndOfThisString > LargestPosition)
LargestPosition = EndOfThisString;
}
! // Now read the remaining of tag and fill all strings. Substract the directory
SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
if (SizeOfTag == 0)
{
Block = NULL;
NumOfWchar = 0;
--- 1501,1511 ----
EndOfThisString = BeginOfThisString + Len;
if (EndOfThisString > LargestPosition)
LargestPosition = EndOfThisString;
}
! // Now read the remaining of tag and fill all strings. Subtract the directory
SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
if (SizeOfTag == 0)
{
Block = NULL;
NumOfWchar = 0;
*** 1530,1540 ****
cmsBool Type_MLU_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsMLU* mlu =(cmsMLU*) Ptr;
cmsUInt32Number HeaderSize;
cmsUInt32Number Len, Offset;
! int i;
if (Ptr == NULL) {
// Empty placeholder
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
--- 1535,1545 ----
cmsBool Type_MLU_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsMLU* mlu =(cmsMLU*) Ptr;
cmsUInt32Number HeaderSize;
cmsUInt32Number Len, Offset;
! cmsUInt32Number i;
if (Ptr == NULL) {
// Empty placeholder
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
*** 3131,3140 ****
--- 3136,3147 ----
cmsUInt16Number Colorant[cmsMAXCHANNELS];
char Root[33];
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;
if (!cmsAppendNamedColor(v, Root, PCS, Colorant)) goto Error;
}
*** 3153,3164 ****
// Saves a named color list into a named color profile
static
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
int i, nColors;
nColors = cmsNamedColorCount(NamedColorList);
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
--- 3160,3171 ----
// Saves a named color list into a named color profile
static
cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
! char prefix[33]; // Prefix for each color name
! char suffix[33]; // Suffix for each color name
int i, nColors;
nColors = cmsNamedColorCount(NamedColorList);
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
*** 3166,3176 ****
if (!_cmsWriteUInt32Number(io, NamedColorList ->ColorantCount)) return FALSE;
strncpy(prefix, (const char*) NamedColorList->Prefix, 32);
strncpy(suffix, (const char*) NamedColorList->Suffix, 32);
! suffix[31] = prefix[31] = 0;
if (!io ->Write(io, 32, prefix)) return FALSE;
if (!io ->Write(io, 32, suffix)) return FALSE;
for (i=0; i < nColors; i++) {
--- 3173,3183 ----
if (!_cmsWriteUInt32Number(io, NamedColorList ->ColorantCount)) return FALSE;
strncpy(prefix, (const char*) NamedColorList->Prefix, 32);
strncpy(suffix, (const char*) NamedColorList->Suffix, 32);
! suffix[32] = prefix[32] = 0;
if (!io ->Write(io, 32, prefix)) return FALSE;
if (!io ->Write(io, 32, suffix)) return FALSE;
for (i=0; i < nColors; i++) {
*** 3178,3187 ****
--- 3185,3195 ----
cmsUInt16Number PCS[3];
cmsUInt16Number Colorant[cmsMAXCHANNELS];
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;
}
*** 3628,3638 ****
#3: Rendering intent 3 CRD name
*/
! // Auxiliar, read an string specified as count + string
static
cmsBool ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section)
{
cmsUInt32Number Count;
char* Text;
--- 3636,3646 ----
#3: Rendering intent 3 CRD name
*/
! // 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)
{
cmsUInt32Number Count;
char* Text;
*** 3877,3887 ****
static
void* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
! return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening));
cmsUNUSED_PARAMETER(n);
}
--- 3885,3895 ----
static
void* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
! return _cmsDupMem(self->ContextID, Ptr, sizeof(cmsICCViewingConditions));
cmsUNUSED_PARAMETER(n);
}
*** 4331,4347 ****
// Write a CLUT in floating point
static
cmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
! cmsUInt8Number Dimensions8[16];
cmsUInt32Number i;
cmsStage* mpe = (cmsStage*) Ptr;
_cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data;
! // Check for maximum number of channels
! if (mpe -> InputChannels > 15) return FALSE;
// Only floats are supported in MPE
if (clut ->HasFloatValues == FALSE) return FALSE;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE;
--- 4339,4355 ----
// Write a CLUT in floating point
static
cmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
! 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 supported by lcms
! if (mpe -> InputChannels > MAX_INPUT_DIMENSIONS) return FALSE;
// Only floats are supported in MPE
if (clut ->HasFloatValues == FALSE) return FALSE;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE;
*** 5476,5486 ****
{ 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}
};
/*
--- 5484,5495 ----
{ 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}, &SupportedTags[63]},
! { cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL}
};
/*
< prev index next >