| 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) | |
| @@ -67,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 writer 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 amount 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 overridden | |
| 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) { | |
| @@ -214,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); | |
| } | |
| // ******************************************************************************************** |