summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmsplugin.c9
-rw-r--r--src/cmstypes.c13
-rw-r--r--testbed/bad_mpe.iccbin0 -> 300 bytes
-rw-r--r--testbed/testcms2.c76
4 files changed, 91 insertions, 7 deletions
diff --git a/src/cmsplugin.c b/src/cmsplugin.c
index 257fc42..e3f9215 100644
--- a/src/cmsplugin.c
+++ b/src/cmsplugin.c
@@ -180,7 +180,10 @@ cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
tmp = _cmsAdjustEndianess32(tmp);
*n = *(cmsFloat32Number*) (void*) &tmp;
}
- return TRUE;
+
+ // fpclassify() required by C99
+ return ((fpclassify(*n) == FP_ZERO) || (fpclassify(*n) == FP_NORMAL));
+
}
@@ -194,7 +197,9 @@ cmsBool CMSEXPORT _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
return FALSE;
if (n != NULL) _cmsAdjustEndianess64(n, &tmp);
- return TRUE;
+
+ // fpclassify() required by C99
+ return ((fpclassify(*n) == FP_ZERO) || (fpclassify(*n) == FP_NORMAL));
}
diff --git a/src/cmstypes.c b/src/cmstypes.c
index bf51326..ef54f34 100644
--- a/src/cmstypes.c
+++ b/src/cmstypes.c
@@ -60,6 +60,11 @@ typedef struct _cmsTagTypeLinkedList_st {
// Helper macro to define a MPE handler. Callbacks do have a fixed naming convention
#define TYPE_MPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree, NULL, 0 }
+// Infinites
+#define MINUS_INF (-1E22F)
+#define PLUS_INF (+1E22F)
+
+
// Register a new type handler. This routine is shared between normal types and MPE. LinkedList points to the optional list head
static
cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos)
@@ -3920,7 +3925,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
cmsUInt16Number nSegments;
cmsCurveSegment* Segments;
cmsToneCurve* Curve;
- cmsFloat32Number PrevBreak = -1E22F; // - infinite
+ cmsFloat32Number PrevBreak = MINUS_INF; // - infinite
// Take signature and channels for each element.
if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return NULL;
@@ -3945,7 +3950,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
}
Segments[nSegments-1].x0 = PrevBreak;
- Segments[nSegments-1].x1 = 1E22F; // A big cmsFloat32Number number
+ Segments[nSegments-1].x1 = PLUS_INF; // A big cmsFloat32Number number
// Read segments
for (i=0; i < nSegments; i++) {
@@ -4318,11 +4323,11 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL);
if (mpe == NULL) goto Error;
- // Read the data
+ // Read and sanitize the data
clut = (_cmsStageCLutData*) mpe ->Data;
for (i=0; i < clut ->nEntries; i++) {
- if (!_cmsReadFloat32Number(io, &clut ->Tab.TFloat[i])) goto Error;
+ if (!_cmsReadFloat32Number(io, &clut->Tab.TFloat[i])) goto Error;
}
*nItems = 1;
diff --git a/testbed/bad_mpe.icc b/testbed/bad_mpe.icc
new file mode 100644
index 0000000..5a86c6c
--- /dev/null
+++ b/testbed/bad_mpe.icc
Binary files differ
diff --git a/testbed/testcms2.c b/testbed/testcms2.c
index f4e6bf1..166b528 100644
--- a/testbed/testcms2.c
+++ b/testbed/testcms2.c
@@ -7995,9 +7995,81 @@ int CheckSE(void)
return 0;
return 1;
-
}
+/**
+* Bug reported.
+*/
+static
+int CheckForgedMPE(void)
+{
+ cmsUInt32Number i;
+ cmsHPROFILE srcProfile;
+ cmsHPROFILE dstProfile;
+ cmsColorSpaceSignature srcCS;
+ cmsUInt32Number nSrcComponents;
+ cmsUInt32Number srcFormat;
+ cmsUInt32Number intent = 0;
+ cmsUInt32Number flags = 0;
+ cmsHTRANSFORM hTransform;
+ cmsUInt8Number output[4];
+
+ srcProfile = cmsOpenProfileFromFile("bad_mpe.icc", "r");
+ if (!srcProfile)
+ return 0;
+
+ dstProfile = cmsCreate_sRGBProfile();
+ if (!dstProfile) {
+ cmsCloseProfile(srcProfile);
+ return 0;
+ }
+
+ srcCS = cmsGetColorSpace(srcProfile);
+ nSrcComponents = cmsChannelsOf(srcCS);
+
+ if (srcCS == cmsSigLabData) {
+ srcFormat =
+ COLORSPACE_SH(PT_Lab) | CHANNELS_SH(nSrcComponents) | BYTES_SH(0);
+ }
+ else {
+ srcFormat =
+ COLORSPACE_SH(PT_ANY) | CHANNELS_SH(nSrcComponents) | BYTES_SH(1);
+ }
+
+ cmsSetLogErrorHandler(ErrorReportingFunction);
+
+ hTransform = cmsCreateTransform(srcProfile, srcFormat, dstProfile,
+ TYPE_BGR_8, intent, flags);
+ cmsCloseProfile(srcProfile);
+ cmsCloseProfile(dstProfile);
+
+ cmsSetLogErrorHandler(FatalErrorQuit);
+
+ // Should report error
+ if (!TrappedError) return 0;
+
+ TrappedError = FALSE;
+
+ // Transform should NOT be created
+ if (!hTransform) return 1;
+
+ // Never should reach here
+ if (T_BYTES(srcFormat) == 0) { // 0 means double
+ double input[128];
+ for (i = 0; i < nSrcComponents; i++)
+ input[i] = 0.5f;
+ cmsDoTransform(hTransform, input, output, 1);
+ }
+ else {
+ cmsUInt8Number input[128];
+ for (i = 0; i < nSrcComponents; i++)
+ input[i] = 128;
+ cmsDoTransform(hTransform, input, output, 1);
+ }
+ cmsDeleteTransform(hTransform);
+
+ return 0;
+}
// --------------------------------------------------------------------------------------------------
@@ -8645,6 +8717,8 @@ int main(int argc, char* argv[])
Check("Transform line stride RGB", CheckTransformLineStride);
+ Check("Forged MPE profile", CheckForgedMPE);
+
}
if (DoPluginTests)