summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Maria <mmaria@abindustries.com>2022-01-14 13:29:58 +0100
committerMarti Maria <mmaria@abindustries.com>2022-01-14 13:29:58 +0100
commite090fcf461b9cd86733cd642856ab478ee6278e8 (patch)
tree84ef0b787940e8d388f36c286d86f80c40aba273
parent1c3ccf4724333743dbef6d828bb22fc7776ad1e8 (diff)
downloadlcms2-e090fcf461b9cd86733cd642856ab478ee6278e8.tar.gz
more code guards on uncommon tags
Not used on normal color management, but it's good to have robust code.
-rw-r--r--src/cmstypes.c70
1 files changed, 52 insertions, 18 deletions
diff --git a/src/cmstypes.c b/src/cmstypes.c
index d64369f..b855d2e 100644
--- a/src/cmstypes.c
+++ b/src/cmstypes.c
@@ -3577,40 +3577,55 @@ void *Type_UcrBg_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm
SignedSizeOfTag -= sizeof(cmsUInt32Number);
n ->Ucr = cmsBuildTabulatedToneCurve16(self ->ContextID, CountUcr, NULL);
- if (n ->Ucr == NULL) return NULL;
+ if (n ->Ucr == NULL) goto error;
- if (SignedSizeOfTag < (cmsInt32Number)CountUcr * sizeof(cmsUInt16Number)) return NULL;
- if (!_cmsReadUInt16Array(io, CountUcr, n ->Ucr->Table16)) return NULL;
+ if (SignedSizeOfTag < (cmsInt32Number)CountUcr * sizeof(cmsUInt16Number)) goto error;
+ if (!_cmsReadUInt16Array(io, CountUcr, n ->Ucr->Table16)) goto error;
SignedSizeOfTag -= CountUcr * sizeof(cmsUInt16Number);
// Second curve is Black generation
- if (SignedSizeOfTag < sizeof(cmsUInt32Number)) return NULL;
- if (!_cmsReadUInt32Number(io, &CountBg)) return NULL;
+ if (SignedSizeOfTag < sizeof(cmsUInt32Number)) goto error;
+ if (!_cmsReadUInt32Number(io, &CountBg)) goto error;
SignedSizeOfTag -= sizeof(cmsUInt32Number);
n ->Bg = cmsBuildTabulatedToneCurve16(self ->ContextID, CountBg, NULL);
- if (n ->Bg == NULL) return NULL;
+ if (n ->Bg == NULL) goto error;
- if (SignedSizeOfTag < (cmsInt32Number) CountBg * sizeof(cmsUInt16Number)) return NULL;
- if (!_cmsReadUInt16Array(io, CountBg, n ->Bg->Table16)) return NULL;
+ if (SignedSizeOfTag < (cmsInt32Number) CountBg * sizeof(cmsUInt16Number)) goto error;
+ if (!_cmsReadUInt16Array(io, CountBg, n ->Bg->Table16)) goto error;
SignedSizeOfTag -= CountBg * sizeof(cmsUInt16Number);
- if (SignedSizeOfTag < 0 || SignedSizeOfTag > 32000) return NULL;
+ if (SignedSizeOfTag < 0 || SignedSizeOfTag > 32000) goto error;
// Now comes the text. The length is specified by the tag size
n ->Desc = cmsMLUalloc(self ->ContextID, 1);
- if (n ->Desc == NULL) return NULL;
+ if (n ->Desc == NULL) goto error;
ASCIIString = (char*) _cmsMalloc(self ->ContextID, SignedSizeOfTag + 1);
- if (io ->Read(io, ASCIIString, sizeof(char), SignedSizeOfTag) != (cmsUInt32Number) SignedSizeOfTag) return NULL;
+ if (io->Read(io, ASCIIString, sizeof(char), SignedSizeOfTag) != (cmsUInt32Number)SignedSizeOfTag)
+ {
+ _cmsFree(self->ContextID, ASCIIString);
+ goto error;
+ }
+
ASCIIString[SignedSizeOfTag] = 0;
cmsMLUsetASCII(n ->Desc, cmsNoLanguage, cmsNoCountry, ASCIIString);
_cmsFree(self ->ContextID, ASCIIString);
*nItems = 1;
return (void*) n;
+
+error:
+
+ if (n->Ucr) cmsFreeToneCurve(n->Ucr);
+ if (n->Bg) cmsFreeToneCurve(n->Bg);
+ if (n->Desc) cmsMLUfree(n->Desc);
+ _cmsFree(self->ContextID, n);
+ *nItems = 0;
+ return NULL;
+
}
static
@@ -5008,27 +5023,41 @@ cmsBool ReadOneElem(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, cmsUIn
static
-cmsBool ReadOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length, cmsUInt32Number BaseOffset)
+cmsBool ReadOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a,
+ cmsUInt32Number Count, cmsUInt32Number Length, cmsUInt32Number BaseOffset,
+ cmsInt32Number* SignedSizeOfTagPtr)
{
cmsUInt32Number i;
+ cmsInt32Number SignedSizeOfTag = *SignedSizeOfTagPtr;
// Read column arrays
for (i=0; i < Count; i++) {
+ if (SignedSizeOfTag < 4 * sizeof(cmsUInt32Number)) return FALSE;
+ SignedSizeOfTag -= 4 * sizeof(cmsUInt32Number);
+
if (!ReadOneElem(io, &a -> Name, i, BaseOffset)) return FALSE;
if (!ReadOneElem(io, &a -> Value, i, BaseOffset)) return FALSE;
if (Length > 16) {
+ if (SignedSizeOfTag < 2 * sizeof(cmsUInt32Number)) return FALSE;
+ SignedSizeOfTag -= 2 * sizeof(cmsUInt32Number);
+
if (!ReadOneElem(io, &a ->DisplayName, i, BaseOffset)) return FALSE;
}
if (Length > 24) {
+ if (SignedSizeOfTag < 2 * sizeof(cmsUInt32Number)) return FALSE;
+ SignedSizeOfTag -= 2 * sizeof(cmsUInt32Number);
+
if (!ReadOneElem(io, & a -> DisplayValue, i, BaseOffset)) return FALSE;
}
}
+
+ *SignedSizeOfTagPtr = SignedSizeOfTag;
return TRUE;
}
@@ -5176,26 +5205,31 @@ cmsBool WriteOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _c
static
void *Type_Dictionary_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
- cmsHANDLE hDict;
+ cmsHANDLE hDict = NULL;
cmsUInt32Number i, Count, Length;
cmsUInt32Number BaseOffset;
_cmsDICarray a;
wchar_t *NameWCS = NULL, *ValueWCS = NULL;
cmsMLU *DisplayNameMLU = NULL, *DisplayValueMLU=NULL;
cmsBool rc;
+ cmsInt32Number SignedSizeOfTag = (cmsInt32Number)SizeOfTag;
*nItems = 0;
+ memset(&a, 0, sizeof(a));
// Get actual position as a basis for element offsets
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
// Get name-value record count
+ SignedSizeOfTag -= sizeof(cmsUInt32Number);
+ if (SignedSizeOfTag < 0) goto Error;
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
- SizeOfTag -= sizeof(cmsUInt32Number);
-
+
// Get rec length
+ SignedSizeOfTag -= sizeof(cmsUInt32Number);
+ if (SignedSizeOfTag < 0) goto Error;
if (!_cmsReadUInt32Number(io, &Length)) return NULL;
- SizeOfTag -= sizeof(cmsUInt32Number);
+
// Check for valid lengths
if (Length != 16 && Length != 24 && Length != 32) {
@@ -5211,7 +5245,7 @@ void *Type_Dictionary_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
if (!AllocArray(self -> ContextID, &a, Count, Length)) goto Error;
// Read column arrays
- if (!ReadOffsetArray(io, &a, Count, Length, BaseOffset)) goto Error;
+ if (!ReadOffsetArray(io, &a, Count, Length, BaseOffset, &SignedSizeOfTag)) goto Error;
// Seek to each element and read it
for (i=0; i < Count; i++) {
@@ -5251,7 +5285,7 @@ void *Type_Dictionary_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
Error:
FreeArray(&a);
- cmsDictFree(hDict);
+ if (hDict != NULL) cmsDictFree(hDict);
return NULL;
}