Introduce gdReallocEx which will free the original memory when realloc

fails to circumvent lost memory when doing:

    a = gdRealloc(a, s);
    if (!a)
        return;

Thanks to Niels Thykier for catching that.
master
Ondřej Surý 2013-05-20 20:50:07 +02:00
parent 525ff7480b
commit f0ddf2eccd
5 changed files with 20 additions and 8 deletions

View File

@ -2864,8 +2864,8 @@ BGD_DECLARE(void) gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int
if (overflow2(sizeof (int), im->polyAllocated)) {
return;
}
im->polyInts = (int *) gdRealloc (im->polyInts,
sizeof (int) * im->polyAllocated);
im->polyInts = (int *) gdReallocEx (im->polyInts,
sizeof (int) * im->polyAllocated);
if (!im->polyInts) {
return;
}

View File

@ -1611,7 +1611,7 @@ static int gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int colors
init_error_limit (oim, nim, cquantize);
arraysize = (size_t) ((nim->sx + 2) * (3 * sizeof (FSERROR)));
/* Allocate Floyd-Steinberg workspace. */
cquantize->fserrors = gdRealloc(cquantize->fserrors, arraysize);
cquantize->fserrors = gdReallocEx(cquantize->fserrors, arraysize);
if (!cquantize->fserrors) {
goto outOfMemory;
}

View File

@ -1185,7 +1185,7 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
xshow_pos = 0;
} else if (xshow_pos + 20 > xshow_alloc) {
xshow_alloc += 100;
strex->xshow = gdRealloc(strex->xshow, xshow_alloc);
strex->xshow = gdReallocEx(strex->xshow, xshow_alloc);
if (!strex->xshow) {
if (tmpstr)
gdFree (tmpstr);
@ -1536,7 +1536,7 @@ static char * font_path(char **fontpath, char *name_list)
* big enough for all paths to be tested.
*/
/* 2.0.22: Thorben Kundinger: +8 is needed, not +6. */
fullname = gdRealloc (fullname,
fullname = gdReallocEx(fullname,
strlen (fontsearchpath) + strlen (name) + 8);
if (!fullname) {
gdFree(fontlist);

View File

@ -61,24 +61,33 @@ gd_strtok_r (char *s, char *sep, char **state)
return result;
}
void *
inline void *
gdCalloc (size_t nmemb, size_t size)
{
return calloc (nmemb, size);
}
void *
inline void *
gdMalloc (size_t size)
{
return malloc (size);
}
void *
inline void *
gdRealloc (void *ptr, size_t size)
{
return realloc (ptr, size);
}
inline void *
gdReallocEx (void *ptr, size_t size)
{
void *newPtr = gdRealloc (ptr, size);
if (!newPtr && ptr)
gdFree(ptr);
return newPtr;
}
BGD_DECLARE(void) gdFree (void *ptr)
{
free (ptr);

View File

@ -23,6 +23,9 @@ extern "C" {
void *gdCalloc (size_t nmemb, size_t size);
void *gdMalloc (size_t size);
void *gdRealloc (void *ptr, size_t size);
/* The extended version of gdReallocEx will free *ptr if the
* realloc fails */
void *gdReallocEx (void *ptr, size_t size);
/* Returns nonzero if multiplying the two quantities will
result in integer overflow. Also returns nonzero if