From 1f96d8ca0499639c06e73054b8e4a6baf2883eaa Mon Sep 17 00:00:00 2001 From: Marti Maria Date: Tue, 24 May 2011 17:27:03 +0200 Subject: Dictionary Fix for NULL objects --- src/cmsnamed.c | 4 +--- src/cmstypes.c | 49 ++++++++++++++++++++++++++++++++++++++----------- testbed/testcms2.c | 18 ++++++++++++++---- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/cmsnamed.c b/src/cmsnamed.c index a36abf8..1bcde4a 100644 --- a/src/cmsnamed.c +++ b/src/cmsnamed.c @@ -817,8 +817,7 @@ void CMSEXPORT cmsDictFree(cmsHANDLE hDict) static wchar_t* DupWcs(cmsContext ContextID, const wchar_t* ptr) { - _cmsAssert(ptr != NULL); - + if (ptr == NULL) return NULL; return (wchar_t*) _cmsDupMem(ContextID, ptr, (mywcslen(ptr) + 1) * sizeof(wchar_t)); } @@ -830,7 +829,6 @@ cmsBool CMSEXPORT cmsDictAddEntry(cmsHANDLE hDict, const wchar_t* Name, const wc _cmsAssert(dict != NULL); _cmsAssert(Name != NULL); - _cmsAssert(Value != NULL); entry = (cmsDICTentry*) _cmsMallocZero(dict ->ContextID, sizeof(cmsDICTentry)); if (entry == NULL) return FALSE; diff --git a/src/cmstypes.c b/src/cmstypes.c index 5fd702f..d6b9d2a 100644 --- a/src/cmstypes.c +++ b/src/cmstypes.c @@ -4820,7 +4820,9 @@ cmsBool ReadOneElem(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, cmsUIn if (!_cmsReadUInt32Number(io, &e->Offsets[i])) return FALSE; if (!_cmsReadUInt32Number(io, &e ->Sizes[i])) return FALSE; - e ->Offsets[i] += BaseOffset; + // An offset of zero has special meaning and shal be preserved + if (e ->Offsets[i] > 0) + e ->Offsets[i] += BaseOffset; return TRUE; } @@ -4890,10 +4892,19 @@ cmsBool ReadOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, wchar { cmsUInt32Number nChars; + + // Special case for undefined strings (see ICC Votable + // Proposal Submission, Dictionary Type and Metadata TAG Definition) + if (e -> Offsets[i] == 0) { + + *wcstr = NULL; + return TRUE; + } if (!io -> Seek(io, e -> Offsets[i])) return FALSE; nChars = e ->Sizes[i] / sizeof(cmsUInt16Number); + *wcstr = (wchar_t*) _cmsMallocZero(e ->ContextID, (nChars + 1) * sizeof(wchar_t)); if (*wcstr == NULL) return FALSE; @@ -4923,15 +4934,22 @@ cmsUInt32Number mywcslen(const wchar_t *s) static cmsBool WriteOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, const wchar_t * wcstr, cmsUInt32Number BaseOffset) { - cmsUInt32Number Before = io ->Tell(io); - cmsUInt32Number n = mywcslen(wcstr); - - e ->Offsets[i] = Before - BaseOffset; + cmsUInt32Number Before = io ->Tell(io); + cmsUInt32Number n; - if (!_cmsWriteWCharArray(io, n, wcstr)) return FALSE; - - e ->Sizes[i] = io ->Tell(io) - Before; - return TRUE; + e ->Offsets[i] = Before - BaseOffset; + + if (wcstr == NULL) { + e ->Sizes[i] = 0; + e ->Offsets[i] = 0; + return TRUE; + } + + n = mywcslen(wcstr); + if (!_cmsWriteWCharArray(io, n, wcstr)) return FALSE; + + e ->Sizes[i] = io ->Tell(io) - Before; + return TRUE; } static @@ -4940,7 +4958,7 @@ cmsBool ReadOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cm cmsUInt32Number nItems = 0; // A way to get null MLUCs - if (e -> Sizes[i] == 0) { + if (e -> Offsets[i] == 0 || e ->Sizes[i] == 0) { *mlu = NULL; return TRUE; @@ -4955,8 +4973,17 @@ cmsBool ReadOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cm static cmsBool WriteOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, const cmsMLU* mlu, cmsUInt32Number BaseOffset) { - cmsUInt32Number Before = io ->Tell(io); + cmsUInt32Number Before; + + // Special case for undefined strings (see ICC Votable + // Proposal Submission, Dictionary Type and Metadata TAG Definition) + if (mlu == NULL) { + e ->Sizes[i] = 0; + e ->Offsets[i] = 0; + return TRUE; + } + Before = io ->Tell(io); e ->Offsets[i] = Before - BaseOffset; if (!Type_MLU_Write(self, io, (void*) mlu, 1)) return FALSE; diff --git a/testbed/testcms2.c b/testbed/testcms2.c index 4e6501b..362d09f 100644 --- a/testbed/testcms2.c +++ b/testbed/testcms2.c @@ -4826,6 +4826,8 @@ cmsInt32Number CheckVCGT(cmsInt32Number Pass, cmsHPROFILE hProfile) return 0; } + +// Only one of the two following may be used, as they share the same tag static cmsInt32Number CheckDictionary16(cmsInt32Number Pass, cmsHPROFILE hProfile) { @@ -4835,7 +4837,8 @@ cmsInt32Number CheckDictionary16(cmsInt32Number Pass, cmsHPROFILE hProfile) case 1: hDict = cmsDictAlloc(DbgThread()); - + cmsDictAddEntry(hDict, L"Name0", NULL, NULL, NULL); + cmsDictAddEntry(hDict, L"Name1", L"", NULL, NULL); cmsDictAddEntry(hDict, L"Name", L"String", NULL, NULL); cmsDictAddEntry(hDict, L"Name2", L"12", NULL, NULL); if (!cmsWriteTag(hProfile, cmsSigMetaTag, hDict)) return 0; @@ -4847,15 +4850,22 @@ cmsInt32Number CheckDictionary16(cmsInt32Number Pass, cmsHPROFILE hProfile) hDict = cmsReadTag(hProfile, cmsSigMetaTag); if (hDict == NULL) return 0; - e = cmsDictGetEntryList(hDict); if (memcmp(e ->Name, L"Name2", sizeof(wchar_t) * 5) != 0) return 0; if (memcmp(e ->Value, L"12", sizeof(wchar_t) * 2) != 0) return 0; e = cmsDictNextEntry(e); - if (memcmp(e ->Name, L"Name", sizeof(wchar_t) * 4) != 0) return 0; + if (memcmp(e ->Name, L"Name", sizeof(wchar_t) * 4) != 0) return 0; if (memcmp(e ->Value, L"String", sizeof(wchar_t) * 5) != 0) return 0; + e = cmsDictNextEntry(e); + if (memcmp(e ->Name, L"Name1", sizeof(wchar_t) *5) != 0) return 0; + if (e ->Value == NULL) return 0; + if (*e->Value != 0) return 0; + e = cmsDictNextEntry(e); + if (memcmp(e ->Name, L"Name0", sizeof(wchar_t) * 5) != 0) return 0; + if (e ->Value != NULL) return 0; return 1; + default:; } @@ -5094,7 +5104,7 @@ cmsInt32Number CheckProfileCreation(void) if (!CheckRAWtags(Pass, h)) return 0; SubTest("Dictionary meta tags"); - if (!CheckDictionary16(Pass, h)) return 0; + // if (!CheckDictionary16(Pass, h)) return 0; if (!CheckDictionary24(Pass, h)) return 0; if (Pass == 1) { -- cgit v1.2.1