summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2021-12-20 00:33:34 +0100
committerAidan MacDonald <amachronic@protonmail.com>2022-01-09 14:36:14 +0000
commit8f063d49c2e1dffb5548e40b69782963e18b1171 (patch)
treea00e882a6a5c602254e710e177c2b50c376088a9 /apps
parentf379e1dbb3150a617a910c7709cc85dccc79861b (diff)
downloadrockbox-8f063d49c2e1dffb5548e40b69782963e18b1171.tar.gz
rockbox-8f063d49c2e1dffb5548e40b69782963e18b1171.zip
ImageViewer: Fix FS#13329 (GIF File handle/memory leaks)
Change-Id: Ib3ef22716c8ba35c7bb78231ca4f5c7155f16018
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/imageviewer/gif/gif.c12
-rw-r--r--apps/plugins/imageviewer/gif/gif_decoder.c43
-rw-r--r--apps/plugins/imageviewer/gif/gif_decoder.h1
3 files changed, 40 insertions, 16 deletions
diff --git a/apps/plugins/imageviewer/gif/gif.c b/apps/plugins/imageviewer/gif/gif.c
index b78709556d..0521c29e3a 100644
--- a/apps/plugins/imageviewer/gif/gif.c
+++ b/apps/plugins/imageviewer/gif/gif.c
@@ -132,6 +132,8 @@ static int load_image(char *filename, struct image_info *info,
time = *rb->current_tick - time;
}
+ gif_decoder_destroy_memory_pool(p_decoder);
+
if (!iv->running_slideshow && !p_decoder->error)
{
rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
@@ -142,6 +144,9 @@ static int load_image(char *filename, struct image_info *info,
if (p_decoder->error)
{
+ if (p_decoder->error == D_GIF_ERR_NOT_ENOUGH_MEM)
+ return PLUGIN_OUTOFMEM;
+
rb->splashf(HZ, "%s", GifErrorString(p_decoder->error));
return PLUGIN_ERROR;
}
@@ -157,12 +162,9 @@ static int load_image(char *filename, struct image_info *info,
img_size = (p_decoder->native_img_size*p_decoder->frames_count + 3) & ~3;
disp_size = (sizeof(unsigned char *)*p_decoder->frames_count*4 + 3) & ~3;
+ /* No memory to allocate disp matrix */
if (memory_size < img_size + disp_size)
- {
- /* No memory to allocate disp matrix */
- rb->splashf(HZ, "%s", GifErrorString(D_GIF_ERR_NOT_ENOUGH_MEM));
- return PLUGIN_ERROR;
- }
+ return PLUGIN_OUTOFMEM;
disp = (unsigned char **)(p_decoder->mem + img_size);
disp_buf = (unsigned char *)disp + disp_size;
diff --git a/apps/plugins/imageviewer/gif/gif_decoder.c b/apps/plugins/imageviewer/gif/gif_decoder.c
index 0fde184ec2..a1fda43a46 100644
--- a/apps/plugins/imageviewer/gif/gif_decoder.c
+++ b/apps/plugins/imageviewer/gif/gif_decoder.c
@@ -115,6 +115,11 @@ void gif_decoder_init(struct gif_decoder *d, void *mem, size_t size)
init_memory_pool(d->mem_size, d->mem);
}
+void gif_decoder_destroy_memory_pool(struct gif_decoder *d)
+{
+ destroy_memory_pool(d->mem);
+}
+
void gif_open(char *filename, struct gif_decoder *d)
{
if ((GifFile = DGifOpenFileName(filename, &d->error)) == NULL)
@@ -181,6 +186,7 @@ void gif_decode(struct gif_decoder *d,
{
/* error allocating temp space */
d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
+ DGifCloseFile(GifFile);
return;
}
@@ -196,7 +202,7 @@ void gif_decode(struct gif_decoder *d,
if (pixels_buffer[0] == NULL)
{
d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
- return;
+ goto free_and_return;
}
/* Global background color */
@@ -215,7 +221,7 @@ void gif_decode(struct gif_decoder *d,
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
{
d->error = GifFile->Error;
- return;
+ goto free_and_return;
}
switch (RecordType)
@@ -225,7 +231,7 @@ void gif_decode(struct gif_decoder *d,
if (DGifGetImageDesc(GifFile) == GIF_ERROR)
{
d->error = GifFile->Error;
- return;
+ goto free_and_return;
}
/* Image Position relative to canvas */
@@ -239,7 +245,7 @@ void gif_decode(struct gif_decoder *d,
GifFile->SColorMap == NULL)
{
d->error = D_GIF_ERR_NO_COLOR_MAP;
- return;
+ goto free_and_return;
}
/* sanity check */
@@ -247,7 +253,7 @@ void gif_decode(struct gif_decoder *d,
GifFile->Image.Top+GifFile->Image.Height>GifFile->SHeight)
{
d->error = D_GIF_ERR_DATA_TOO_BIG;
- return;
+ goto free_and_return;
}
if (GifFile->Image.GCB &&
@@ -275,7 +281,7 @@ void gif_decode(struct gif_decoder *d,
if (DGifGetLine(GifFile, Line, Width) == GIF_ERROR)
{
d->error = GifFile->Error;
- return;
+ goto free_and_return;
}
gif2pixels(Line, pixels_buffer[buf_idx],
@@ -294,7 +300,7 @@ void gif_decode(struct gif_decoder *d,
if (DGifGetLine(GifFile, Line, Width) == GIF_ERROR)
{
d->error = GifFile->Error;
- return;
+ goto free_and_return;
}
gif2pixels(Line, pixels_buffer[buf_idx],
@@ -310,7 +316,7 @@ void gif_decode(struct gif_decoder *d,
if (out == NULL)
{
d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
- return;
+ goto free_and_return;
}
bm.data = out + d->native_img_size*d->frames_count;
@@ -350,7 +356,7 @@ void gif_decode(struct gif_decoder *d,
GIF_ERROR)
{
d->error = GifFile->Error;
- return;
+ goto free_and_return;
}
if (ExtCode == GRAPHICS_EXT_FUNC_CODE)
@@ -364,7 +370,7 @@ void gif_decode(struct gif_decoder *d,
GifFile->Image.GCB) == GIF_ERROR)
{
d->error = GifFile->Error;
- return;
+ goto free_and_return;
}
d->delay = GifFile->Image.GCB->DelayTime;
}
@@ -375,7 +381,7 @@ void gif_decode(struct gif_decoder *d,
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR)
{
d->error = GifFile->Error;
- return;
+ goto free_and_return;
}
}
break;
@@ -391,6 +397,10 @@ void gif_decode(struct gif_decoder *d,
if (DGifCloseFile(GifFile) == GIF_ERROR)
{
d->error = GifFile->Error;
+ free(pixels_buffer[0]);
+ if (pixels_buffer[1])
+ free(pixels_buffer[1]);
+ free(Line);
return;
}
@@ -472,4 +482,15 @@ void gif_decode(struct gif_decoder *d,
}
}
#endif
+ return;
+
+free_and_return:
+ if (Line)
+ free(Line);
+ if (pixels_buffer[0])
+ free(pixels_buffer[0]);
+ if (pixels_buffer[1])
+ free(pixels_buffer[1]);
+ DGifCloseFile(GifFile);
+ return;
}
diff --git a/apps/plugins/imageviewer/gif/gif_decoder.h b/apps/plugins/imageviewer/gif/gif_decoder.h
index ce8a3fa292..6af775a324 100644
--- a/apps/plugins/imageviewer/gif/gif_decoder.h
+++ b/apps/plugins/imageviewer/gif/gif_decoder.h
@@ -30,6 +30,7 @@ struct gif_decoder {
};
void gif_decoder_init(struct gif_decoder *decoder, void *mem, size_t size);
+void gif_decoder_destroy_memory_pool(struct gif_decoder *d);
void gif_open(char *filename, struct gif_decoder *d);
void gif_decode(struct gif_decoder *d, void (*pf_progress)(int current, int total));