diff --git a/third_party/lcms/src/cmserr.c b/third_party/lcms/src/cmserr.c index 700152ee3..3c3848b2a 100644 --- a/third_party/lcms/src/cmserr.c +++ b/third_party/lcms/src/cmserr.c @@ -25,6 +25,8 @@ #include "lcms2_internal.h" +#include "core/fxcrt/fx_memory.h" +#include "core/fxcrt/fx_system.h" // This function is here to help applications to prevent mixing lcms versions on header and shared objects. int CMSEXPORT cmsGetEncodedCMMversion(void) @@ -65,140 +67,75 @@ long int CMSEXPORT cmsfilelength(FILE* f) return n; } - -// Memory handling ------------------------------------------------------------------ -// -// This is the interface to low-level memory management routines. By default a simple -// wrapping to malloc/free/realloc is provided, although there is a limit on the max -// amount of memoy that can be reclaimed. This is mostly as a safety feature to prevent -// bogus or evil code to allocate huge blocks that otherwise lcms would never need. - -#define MAX_MEMORY_FOR_ALLOC ((cmsUInt32Number)(1024U*1024U*512U)) - -// User may override this behaviour by using a memory plug-in, which basically replaces -// the default memory management functions. In this case, no check is performed and it -// is up to the plug-in writter to keep in the safe side. There are only three functions -// required to be implemented: malloc, realloc and free, although the user may want to -// replace the optional mallocZero, calloc and dup as well. - -cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin); - -// ********************************************************************************* - -// This is the default memory allocation function. It does a very coarse -// check of amout of memory, just to prevent exploits -static -void* _cmsMallocDefaultFn(cmsContext ContextID, cmsUInt32Number size) +cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin) { - if (size > MAX_MEMORY_FOR_ALLOC) return NULL; // Never allow over maximum - - return (void*) malloc(size); + return TRUE; +} - cmsUNUSED_PARAMETER(ContextID); +// Generic allocate +void* CMSEXPORT _cmsMalloc(cmsContext ContextID, cmsUInt32Number size) +{ + return FXMEM_DefaultAlloc(size); } // Generic allocate & zero -static -void* _cmsMallocZeroDefaultFn(cmsContext ContextID, cmsUInt32Number size) +void* CMSEXPORT _cmsMallocZero(cmsContext ContextID, cmsUInt32Number size) { - void *pt = _cmsMalloc(ContextID, size); - if (pt == NULL) return NULL; - - memset(pt, 0, size); - return pt; + void* p = FXMEM_DefaultAlloc(size); + if (p) memset(p, 0, size); + return p; } - -// The default free function. The only check proformed is against NULL pointers -static -void _cmsFreeDefaultFn(cmsContext ContextID, void *Ptr) +// Generic calloc +void* CMSEXPORT _cmsCalloc(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size) { - // free(NULL) is defined a no-op by C99, therefore it is safe to - // avoid the check, but it is here just in case... - - if (Ptr) free(Ptr); + cmsUInt32Number total = num * size; + if (total == 0 || total / size != num || total >= 512 * 1024 * 1024) + return NULL; - cmsUNUSED_PARAMETER(ContextID); + return _cmsMallocZero(ContextID, num * size); } -// The default realloc function. Again it checks for exploits. If Ptr is NULL, -// realloc behaves the same way as malloc and allocates a new block of size bytes. -static -void* _cmsReallocDefaultFn(cmsContext ContextID, void* Ptr, cmsUInt32Number size) +// Generic reallocate +void* CMSEXPORT _cmsRealloc(cmsContext ContextID, void* Ptr, cmsUInt32Number size) { - - if (size > MAX_MEMORY_FOR_ALLOC) return NULL; // Never realloc over 512Mb - - return realloc(Ptr, size); - - cmsUNUSED_PARAMETER(ContextID); + return FXMEM_DefaultRealloc(Ptr, size); } - -// The default calloc function. Allocates an array of num elements, each one of size bytes -// all memory is initialized to zero. -static -void* _cmsCallocDefaultFn(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size) +// Generic free memory +void CMSEXPORT _cmsFree(cmsContext ContextID, void* Ptr) { - cmsUInt32Number Total = num * size; - - // Preserve calloc behaviour - if (Total == 0) return NULL; - - // Safe check for overflow. - if (num >= UINT_MAX / size) return NULL; - - // Check for overflow - if (Total < num || Total < size) { - return NULL; - } - - if (Total > MAX_MEMORY_FOR_ALLOC) return NULL; // Never alloc over 512Mb - - return _cmsMallocZero(ContextID, Total); + if (Ptr != NULL) FXMEM_DefaultFree(Ptr); } // Generic block duplication -static -void* _cmsDupDefaultFn(cmsContext ContextID, const void* Org, cmsUInt32Number size) +void* CMSEXPORT _cmsDupMem(cmsContext ContextID, const void* Org, cmsUInt32Number size) { - void* mem; - - if (size > MAX_MEMORY_FOR_ALLOC) return NULL; // Never dup over 512Mb - - mem = _cmsMalloc(ContextID, size); - - if (mem != NULL && Org != NULL) - memmove(mem, Org, size); - - return mem; + void* p = FXMEM_DefaultAlloc(size); + memmove(p, Org, size); + return p; } - -// Pointers to memory manager functions in Context0 -_cmsMemPluginChunkType _cmsMemPluginChunk = { _cmsMallocDefaultFn, _cmsMallocZeroDefaultFn, _cmsFreeDefaultFn, - _cmsReallocDefaultFn, _cmsCallocDefaultFn, _cmsDupDefaultFn +_cmsMemPluginChunkType _cmsMemPluginChunk = {_cmsMalloc, _cmsMallocZero, _cmsFree, + _cmsRealloc, _cmsCalloc, _cmsDupMem }; - -// Reset and duplicate memory manager void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src) { _cmsAssert(ctx != NULL); - if (src != NULL) { + if (src != NULL) { // Duplicate - ctx ->chunks[MemPlugin] = _cmsSubAllocDup(ctx ->MemPool, src ->chunks[MemPlugin], sizeof(_cmsMemPluginChunkType)); + ctx ->chunks[MemPlugin] = _cmsSubAllocDup(ctx ->MemPool, src ->chunks[MemPlugin], sizeof(_cmsMemPluginChunkType)); } else { // To reset it, we use the default allocators, which cannot be overriden ctx ->chunks[MemPlugin] = &ctx ->DefaultMemoryManager; - } + } } -// Auxiliary to fill memory management functions from plugin (or context 0 defaults) void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr) { if (Plugin == NULL) { @@ -212,94 +149,15 @@ void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkTy ptr ->ReallocPtr = Plugin -> ReallocPtr; // Make sure we revert to defaults - ptr ->MallocZeroPtr= _cmsMallocZeroDefaultFn; - ptr ->CallocPtr = _cmsCallocDefaultFn; - ptr ->DupPtr = _cmsDupDefaultFn; - + ptr ->MallocZeroPtr= _cmsMallocZero; + ptr ->CallocPtr = _cmsCalloc; + ptr ->DupPtr = _cmsDupMem; + if (Plugin ->MallocZeroPtr != NULL) ptr ->MallocZeroPtr = Plugin -> MallocZeroPtr; if (Plugin ->CallocPtr != NULL) ptr ->CallocPtr = Plugin -> CallocPtr; if (Plugin ->DupPtr != NULL) ptr ->DupPtr = Plugin -> DupPtr; - - } -} - -// Plug-in replacement entry -cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase *Data) -{ - cmsPluginMemHandler* Plugin = (cmsPluginMemHandler*) Data; - _cmsMemPluginChunkType* ptr; - - // NULL forces to reset to defaults. In this special case, the defaults are stored in the context structure. - // Remaining plug-ins does NOT have any copy in the context structure, but this is somehow special as the - // context internal data should be malloce'd by using those functions. - if (Data == NULL) { - - struct _cmsContext_struct* ctx = ( struct _cmsContext_struct*) ContextID; - - // Return to the default allocators - if (ContextID != NULL) { - ctx->chunks[MemPlugin] = (void*) &ctx->DefaultMemoryManager; - } - return TRUE; } - - // Check for required callbacks - if (Plugin -> MallocPtr == NULL || - Plugin -> FreePtr == NULL || - Plugin -> ReallocPtr == NULL) return FALSE; - - // Set replacement functions - ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); - if (ptr == NULL) - return FALSE; - - _cmsInstallAllocFunctions(Plugin, ptr); - return TRUE; -} - -// Generic allocate -void* CMSEXPORT _cmsMalloc(cmsContext ContextID, cmsUInt32Number size) -{ - _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); - return ptr ->MallocPtr(ContextID, size); -} - -// Generic allocate & zero -void* CMSEXPORT _cmsMallocZero(cmsContext ContextID, cmsUInt32Number size) -{ - _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); - return ptr->MallocZeroPtr(ContextID, size); -} - -// Generic calloc -void* CMSEXPORT _cmsCalloc(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size) -{ - _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); - return ptr->CallocPtr(ContextID, num, size); -} - -// Generic reallocate -void* CMSEXPORT _cmsRealloc(cmsContext ContextID, void* Ptr, cmsUInt32Number size) -{ - _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); - return ptr->ReallocPtr(ContextID, Ptr, size); -} - -// Generic free memory -void CMSEXPORT _cmsFree(cmsContext ContextID, void* Ptr) -{ - if (Ptr != NULL) { - _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); - ptr ->FreePtr(ContextID, Ptr); - } -} - -// Generic block duplication -void* CMSEXPORT _cmsDupMem(cmsContext ContextID, const void* Org, cmsUInt32Number size) -{ - _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); - return ptr ->DupPtr(ContextID, Org, size); } // ********************************************************************************************