diff options
-rw-r--r-- | src/cmsplugin.c | 9 | ||||
-rw-r--r-- | src/cmstypes.c | 13 | ||||
-rw-r--r-- | testbed/bad_mpe.icc | bin | 0 -> 300 bytes | |||
-rw-r--r-- | testbed/testcms2.c | 76 |
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 Binary files differnew file mode 100644 index 0000000..5a86c6c --- /dev/null +++ b/testbed/bad_mpe.icc 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) |