diff --git a/src/rcore.c b/src/rcore.c index 4360a23ee..d1b1a8219 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2562,19 +2562,20 @@ unsigned char *DecompressData(const unsigned char *compData, int compDataSize, i #if defined(SUPPORT_COMPRESSION_API) // Decompress data from a valid DEFLATE stream - data = (unsigned char *)RL_CALLOC(MAX_DECOMPRESSION_SIZE*1024*1024, 1); + unsigned char *data0 = (unsigned char *)RL_CALLOC(MAX_DECOMPRESSION_SIZE*1024*1024, 1); int length = sinflate(data, MAX_DECOMPRESSION_SIZE*1024*1024, compData, compDataSize); - // WARNING: RL_REALLOC can make (and leave) data copies in memory, be careful with sensitive compressed data! - // TODO: Use a different approach, create another buffer, copy data manually to it and wipe original buffer memory - unsigned char *temp = (unsigned char *)RL_REALLOC(data, length); - - if (temp != NULL) data = temp; - else TRACELOG(LOG_WARNING, "SYSTEM: Failed to re-allocate required decompression memory"); + // WARNING: RL_REALLOC can make (and leave) data copies in memory, + // that can be a security concern in case of compression of sensitive data + // So, we use a second buffer to copy data manually, wiping original buffer memory + data = (unsigned char *)RL_CALLOC(length, 1); + memcpy(data, data0, length); + memset(data0, 0, MAX_DECOMPRESSION_SIZE*1024*1024); // Wipe memory, is memset() safe? + RL_FREE(data0); + + TRACELOG(LOG_INFO, "SYSTEM: Decompress data: Comp. size: %i -> Original size: %i", compDataSize, length); *dataSize = length; - - TRACELOG(LOG_INFO, "SYSTEM: Decompress data: Comp. size: %i -> Original size: %i", compDataSize, *dataSize); #endif return data; diff --git a/src/rmodels.c b/src/rmodels.c index ff71b79d6..5a824ce44 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -6573,13 +6573,23 @@ static Model LoadM3D(const char *fileName) // Materials are grouped together if (mi != m3d->face[i].materialid) { - // there should be only one material switch per material kind, but be bulletproof for non-optimal model files + // There should be only one material switch per material kind, + // but be bulletproof for non-optimal model files if (k + 1 >= model.meshCount) { model.meshCount++; - model.meshes = (Mesh *)RL_REALLOC(model.meshes, model.meshCount*sizeof(Mesh)); - memset(&model.meshes[model.meshCount - 1], 0, sizeof(Mesh)); - model.meshMaterial = (int *)RL_REALLOC(model.meshMaterial, model.meshCount*sizeof(int)); + + // Create a second buffer for mesh re-allocation + Mesh *tempMeshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh)); + memcpy(tempMeshes, model.meshes, (model.meshCount - 1)*sizeof(Mesh)); + RL_FREE(model.meshes); + model.meshes = tempMeshes; + + // Create a second buffer for material re-allocation + int *tempMeshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int)); + memcpy(tempMeshMaterial, model.meshMaterial, (model.meshCount - 1)*sizeof(int)); + RL_FREE(model.meshMaterial); + model.meshMaterial = tempMeshMaterial; } k++; diff --git a/src/rtext.c b/src/rtext.c index f54c71aef..ffa432ed3 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1920,10 +1920,11 @@ char *LoadUTF8(const int *codepoints, int length) size += bytes; } - // Resize memory to text length + string NULL terminator - void *ptr = RL_REALLOC(text, size + 1); - - if (ptr != NULL) text = (char *)ptr; + // Create second buffer and copy data manually to it + char *temp = (char *)RL_CALLOC(size + 1, 1); + memcpy(temp, text, size); + RL_FREE(text); + text = temp; return text; } @@ -1951,8 +1952,11 @@ int *LoadCodepoints(const char *text, int *count) i += codepointSize; } - // Re-allocate buffer to the actual number of codepoints loaded - codepoints = (int *)RL_REALLOC(codepoints, codepointCount*sizeof(int)); + // Create second buffer and copy data manually to it + int *temp = (int *)RL_CALLOC(codepointCount, sizeof(int)); + for (int i = 0; i < codepointCount; i++) temp[i] = codepoints[i]; + RL_FREE(codepoints); + codepoints = temp; *count = codepointCount; diff --git a/src/rtextures.c b/src/rtextures.c index dc6695452..a4c34b000 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -2400,10 +2400,11 @@ void ImageMipmaps(Image *image) if (image->mipmaps < mipCount) { - void *temp = RL_REALLOC(image->data, mipSize); - - if (temp != NULL) image->data = temp; // Assign new pointer (new size) to store mipmaps data - else TRACELOG(LOG_WARNING, "IMAGE: Mipmaps required memory could not be allocated"); + // Create second buffer and copy data manually to it + void *temp = RL_CALLOC(mipSize, 1); + memcpy(temp, image->data, GetPixelDataSize(image->width, image->height, image->format)); + RL_FREE(image->data); + image->data = temp; // Pointer to allocated memory point where store next mipmap level data unsigned char *nextmip = image->data; @@ -2429,9 +2430,7 @@ void ImageMipmaps(Image *image) if (i < image->mipmaps) continue; TRACELOGD("IMAGE: Generating mipmap level: %i (%i x %i) - size: %i - offset: 0x%x", i, mipWidth, mipHeight, mipSize, nextmip); - ImageResize(&imCopy, mipWidth, mipHeight); // Uses internally Mitchell cubic downscale filter - memcpy(nextmip, imCopy.data, mipSize); }