ANALYSIS: Fix potential memory leak when using realloc

When reallocation is unsuccessful, the passed buffer is not freed. In this case, assigning the result (NULL) will result in a leak of the original memory buffer.
See http://msdn.microsoft.com/en-us/library/kkedhy7c.aspx
This commit is contained in:
Julien 2011-06-04 03:43:16 +08:00 committed by Julien
parent a8b13e8a6b
commit 2f200ac493
5 changed files with 60 additions and 22 deletions

View File

@ -118,7 +118,11 @@ static byte *loadVOCFromStream(Common::ReadStream &stream, int &size, int &rate,
debug(9, "VOC Data Block: %d, %d, %d", rate, packing, len);
if (packing == 0) {
if (size) {
ret_sound = (byte *)realloc(ret_sound, size + len);
byte *tmp = (byte *)realloc(ret_sound, size + len);
if (!tmp)
error("Cannot reallocate memory for VOC Data Block");
ret_sound = tmp;
} else {
ret_sound = (byte *)malloc(len);
}

View File

@ -93,8 +93,12 @@ void MemoryBlock::copyFrom(const byte *src, uint32 srcPos, uint32 destPos, uint3
void MemoryBlock::reallocate(uint32 size1) {
_size = size1;
_data = (byte *) realloc(_data, size1);
if (!_data) error ("Failed reallocating memory block");
byte *tmp = (byte *) realloc(_data, size1);
if (!tmp)
error ("[MemoryBlock::reallocate] Failed reallocating memory block");
_data = tmp;
}
} // End of namespace Lure

View File

@ -167,9 +167,14 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) {
if (points != NULL && n_points >= 2) {
if (n_segs == n_segs_max) {
n_segs_max <<= 1;
svp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
(n_segs_max - 1) *
sizeof(ArtSVPSeg));
ArtSVP *tmp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
(n_segs_max - 1) *
sizeof(ArtSVPSeg));
if (!tmp)
error("Cannot reallocate memory in art_svp_from_vpath()");
svp = tmp;
}
svp->segs[n_segs].n_points = n_points;
svp->segs[n_segs].dir = (dir > 0);
@ -204,9 +209,14 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) {
y = points[n_points - 1].y;
if (n_segs == n_segs_max) {
n_segs_max <<= 1;
svp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
(n_segs_max - 1) *
sizeof(ArtSVPSeg));
ArtSVP *tmp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
(n_segs_max - 1) *
sizeof(ArtSVPSeg));
if (!tmp)
error("Cannot reallocate memory in art_svp_from_vpath()");
svp = tmp;
}
svp->segs[n_segs].n_points = n_points;
svp->segs[n_segs].dir = (dir > 0);
@ -246,9 +256,14 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) {
if (n_points >= 2) {
if (n_segs == n_segs_max) {
n_segs_max <<= 1;
svp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
(n_segs_max - 1) *
sizeof(ArtSVPSeg));
ArtSVP *tmp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) +
(n_segs_max - 1) *
sizeof(ArtSVPSeg));
if (!tmp)
error("Cannot reallocate memory in art_svp_from_vpath()");
svp = tmp;
}
svp->segs[n_segs].n_points = n_points;
svp->segs[n_segs].dir = (dir > 0);
@ -1157,8 +1172,13 @@ static int art_svp_writer_rewind_add_segment(ArtSvpWriter *self, int wind_left,
(swr->n_segs_max - 1) *
sizeof(ArtSVPSeg));
swr->svp = svp;
swr->n_points_max = art_renew(swr->n_points_max, int,
swr->n_segs_max);
int *tmp = art_renew(swr->n_points_max, int,
swr->n_segs_max);
if (!tmp)
error("Cannot reallocate memory in art_svp_writer_rewind_add_segment()");
swr->n_points_max = tmp;
}
seg = &svp->segs[seg_num];
seg->n_points = 1;

View File

@ -51,7 +51,9 @@ namespace Sword25 {
#define art_expand(p, type, max) \
do { \
if(max) {\
p = art_renew(p, type, max <<= 1); \
type *tmp = art_renew(p, type, max <<= 1); \
if (!tmp) error("Cannot reallocate memory for art data"); \
p = tmp; \
} else { \
max = 1; \
p = art_new(type, 1); \

View File

@ -468,14 +468,22 @@ void ToucheEngine::res_loadSprite(int num, int index) {
if (size > spr->size) {
debug(8, "Reallocating memory for sprite %d (index %d), %d bytes needed", num, index, size - spr->size);
spr->size = size;
if (spr->ptr) {
spr->ptr = (uint8 *)realloc(spr->ptr, size);
} else {
spr->ptr = (uint8 *)malloc(size);
}
if (!spr->ptr) {
error("Unable to reallocate memory for sprite %d (%d bytes)", num, size);
uint8 *buffer = NULL;
if (spr->ptr)
buffer = (uint8 *)realloc(spr->ptr, size);
if (!buffer) {
// Free previously allocated sprite (when realloc failed)
free(spr->ptr);
buffer = (uint8 *)malloc(size);
}
if (!buffer)
error("[ToucheEngine::res_loadSprite] Unable to reallocate memory for sprite %d (%d bytes)", num, size);
spr->ptr = buffer;
}
for (int i = 0; i < _currentImageHeight; ++i) {
res_decodeScanLineImageRLE(spr->ptr + _currentImageWidth * i, _currentImageWidth);