summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Maria <info@littlecms.com>2011-05-24 17:27:03 +0200
committerMarti Maria <info@littlecms.com>2011-05-24 17:27:03 +0200
commit1f96d8ca0499639c06e73054b8e4a6baf2883eaa (patch)
treef663f73420d90e948050cf424424c2a76303d697
parenta4d8ee129fdd10b980e8a77badbb45df786c48ef (diff)
downloadlcms2-1f96d8ca0499639c06e73054b8e4a6baf2883eaa.tar.gz
Dictionary Fix for NULL objects
-rw-r--r--src/cmsnamed.c4
-rw-r--r--src/cmstypes.c49
-rw-r--r--testbed/testcms2.c18
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) {