diff options
author | Christian Soffke <christian.soffke@gmail.com> | 2021-12-20 00:33:34 +0100 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-01-09 14:36:14 +0000 |
commit | 8f063d49c2e1dffb5548e40b69782963e18b1171 (patch) | |
tree | a00e882a6a5c602254e710e177c2b50c376088a9 | |
parent | f379e1dbb3150a617a910c7709cc85dccc79861b (diff) | |
download | rockbox-8f063d49c2.tar.gz rockbox-8f063d49c2.zip |
ImageViewer: Fix FS#13329 (GIF File handle/memory leaks)
Change-Id: Ib3ef22716c8ba35c7bb78231ca4f5c7155f16018
-rw-r--r-- | apps/plugins/imageviewer/gif/gif.c | 12 | ||||
-rw-r--r-- | apps/plugins/imageviewer/gif/gif_decoder.c | 43 | ||||
-rw-r--r-- | apps/plugins/imageviewer/gif/gif_decoder.h | 1 |
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)); |