summaryrefslogtreecommitdiff
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
parentf379e1dbb3150a617a910c7709cc85dccc79861b (diff)
downloadrockbox-8f063d49c2e1dffb5548e40b69782963e18b1171.tar.gz
rockbox-8f063d49c2e1dffb5548e40b69782963e18b1171.zip
ImageViewer: Fix FS#13329 (GIF File handle/memory leaks)
Change-Id: Ib3ef22716c8ba35c7bb78231ca4f5c7155f16018
-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,
132 time = *rb->current_tick - time; 132 time = *rb->current_tick - time;
133 } 133 }
134 134
135 gif_decoder_destroy_memory_pool(p_decoder);
136
135 if (!iv->running_slideshow && !p_decoder->error) 137 if (!iv->running_slideshow && !p_decoder->error)
136 { 138 {
137 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ); 139 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,
142 144
143 if (p_decoder->error) 145 if (p_decoder->error)
144 { 146 {
147 if (p_decoder->error == D_GIF_ERR_NOT_ENOUGH_MEM)
148 return PLUGIN_OUTOFMEM;
149
145 rb->splashf(HZ, "%s", GifErrorString(p_decoder->error)); 150 rb->splashf(HZ, "%s", GifErrorString(p_decoder->error));
146 return PLUGIN_ERROR; 151 return PLUGIN_ERROR;
147 } 152 }
@@ -157,12 +162,9 @@ static int load_image(char *filename, struct image_info *info,
157 img_size = (p_decoder->native_img_size*p_decoder->frames_count + 3) & ~3; 162 img_size = (p_decoder->native_img_size*p_decoder->frames_count + 3) & ~3;
158 disp_size = (sizeof(unsigned char *)*p_decoder->frames_count*4 + 3) & ~3; 163 disp_size = (sizeof(unsigned char *)*p_decoder->frames_count*4 + 3) & ~3;
159 164
165 /* No memory to allocate disp matrix */
160 if (memory_size < img_size + disp_size) 166 if (memory_size < img_size + disp_size)
161 { 167 return PLUGIN_OUTOFMEM;
162 /* No memory to allocate disp matrix */
163 rb->splashf(HZ, "%s", GifErrorString(D_GIF_ERR_NOT_ENOUGH_MEM));
164 return PLUGIN_ERROR;
165 }
166 168
167 disp = (unsigned char **)(p_decoder->mem + img_size); 169 disp = (unsigned char **)(p_decoder->mem + img_size);
168 disp_buf = (unsigned char *)disp + disp_size; 170 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)
115 init_memory_pool(d->mem_size, d->mem); 115 init_memory_pool(d->mem_size, d->mem);
116} 116}
117 117
118void gif_decoder_destroy_memory_pool(struct gif_decoder *d)
119{
120 destroy_memory_pool(d->mem);
121}
122
118void gif_open(char *filename, struct gif_decoder *d) 123void gif_open(char *filename, struct gif_decoder *d)
119{ 124{
120 if ((GifFile = DGifOpenFileName(filename, &d->error)) == NULL) 125 if ((GifFile = DGifOpenFileName(filename, &d->error)) == NULL)
@@ -181,6 +186,7 @@ void gif_decode(struct gif_decoder *d,
181 { 186 {
182 /* error allocating temp space */ 187 /* error allocating temp space */
183 d->error = D_GIF_ERR_NOT_ENOUGH_MEM; 188 d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
189 DGifCloseFile(GifFile);
184 return; 190 return;
185 } 191 }
186 192
@@ -196,7 +202,7 @@ void gif_decode(struct gif_decoder *d,
196 if (pixels_buffer[0] == NULL) 202 if (pixels_buffer[0] == NULL)
197 { 203 {
198 d->error = D_GIF_ERR_NOT_ENOUGH_MEM; 204 d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
199 return; 205 goto free_and_return;
200 } 206 }
201 207
202 /* Global background color */ 208 /* Global background color */
@@ -215,7 +221,7 @@ void gif_decode(struct gif_decoder *d,
215 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) 221 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
216 { 222 {
217 d->error = GifFile->Error; 223 d->error = GifFile->Error;
218 return; 224 goto free_and_return;
219 } 225 }
220 226
221 switch (RecordType) 227 switch (RecordType)
@@ -225,7 +231,7 @@ void gif_decode(struct gif_decoder *d,
225 if (DGifGetImageDesc(GifFile) == GIF_ERROR) 231 if (DGifGetImageDesc(GifFile) == GIF_ERROR)
226 { 232 {
227 d->error = GifFile->Error; 233 d->error = GifFile->Error;
228 return; 234 goto free_and_return;
229 } 235 }
230 236
231 /* Image Position relative to canvas */ 237 /* Image Position relative to canvas */
@@ -239,7 +245,7 @@ void gif_decode(struct gif_decoder *d,
239 GifFile->SColorMap == NULL) 245 GifFile->SColorMap == NULL)
240 { 246 {
241 d->error = D_GIF_ERR_NO_COLOR_MAP; 247 d->error = D_GIF_ERR_NO_COLOR_MAP;
242 return; 248 goto free_and_return;
243 } 249 }
244 250
245 /* sanity check */ 251 /* sanity check */
@@ -247,7 +253,7 @@ void gif_decode(struct gif_decoder *d,
247 GifFile->Image.Top+GifFile->Image.Height>GifFile->SHeight) 253 GifFile->Image.Top+GifFile->Image.Height>GifFile->SHeight)
248 { 254 {
249 d->error = D_GIF_ERR_DATA_TOO_BIG; 255 d->error = D_GIF_ERR_DATA_TOO_BIG;
250 return; 256 goto free_and_return;
251 } 257 }
252 258
253 if (GifFile->Image.GCB && 259 if (GifFile->Image.GCB &&
@@ -275,7 +281,7 @@ void gif_decode(struct gif_decoder *d,
275 if (DGifGetLine(GifFile, Line, Width) == GIF_ERROR) 281 if (DGifGetLine(GifFile, Line, Width) == GIF_ERROR)
276 { 282 {
277 d->error = GifFile->Error; 283 d->error = GifFile->Error;
278 return; 284 goto free_and_return;
279 } 285 }
280 286
281 gif2pixels(Line, pixels_buffer[buf_idx], 287 gif2pixels(Line, pixels_buffer[buf_idx],
@@ -294,7 +300,7 @@ void gif_decode(struct gif_decoder *d,
294 if (DGifGetLine(GifFile, Line, Width) == GIF_ERROR) 300 if (DGifGetLine(GifFile, Line, Width) == GIF_ERROR)
295 { 301 {
296 d->error = GifFile->Error; 302 d->error = GifFile->Error;
297 return; 303 goto free_and_return;
298 } 304 }
299 305
300 gif2pixels(Line, pixels_buffer[buf_idx], 306 gif2pixels(Line, pixels_buffer[buf_idx],
@@ -310,7 +316,7 @@ void gif_decode(struct gif_decoder *d,
310 if (out == NULL) 316 if (out == NULL)
311 { 317 {
312 d->error = D_GIF_ERR_NOT_ENOUGH_MEM; 318 d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
313 return; 319 goto free_and_return;
314 } 320 }
315 321
316 bm.data = out + d->native_img_size*d->frames_count; 322 bm.data = out + d->native_img_size*d->frames_count;
@@ -350,7 +356,7 @@ void gif_decode(struct gif_decoder *d,
350 GIF_ERROR) 356 GIF_ERROR)
351 { 357 {
352 d->error = GifFile->Error; 358 d->error = GifFile->Error;
353 return; 359 goto free_and_return;
354 } 360 }
355 361
356 if (ExtCode == GRAPHICS_EXT_FUNC_CODE) 362 if (ExtCode == GRAPHICS_EXT_FUNC_CODE)
@@ -364,7 +370,7 @@ void gif_decode(struct gif_decoder *d,
364 GifFile->Image.GCB) == GIF_ERROR) 370 GifFile->Image.GCB) == GIF_ERROR)
365 { 371 {
366 d->error = GifFile->Error; 372 d->error = GifFile->Error;
367 return; 373 goto free_and_return;
368 } 374 }
369 d->delay = GifFile->Image.GCB->DelayTime; 375 d->delay = GifFile->Image.GCB->DelayTime;
370 } 376 }
@@ -375,7 +381,7 @@ void gif_decode(struct gif_decoder *d,
375 if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) 381 if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR)
376 { 382 {
377 d->error = GifFile->Error; 383 d->error = GifFile->Error;
378 return; 384 goto free_and_return;
379 } 385 }
380 } 386 }
381 break; 387 break;
@@ -391,6 +397,10 @@ void gif_decode(struct gif_decoder *d,
391 if (DGifCloseFile(GifFile) == GIF_ERROR) 397 if (DGifCloseFile(GifFile) == GIF_ERROR)
392 { 398 {
393 d->error = GifFile->Error; 399 d->error = GifFile->Error;
400 free(pixels_buffer[0]);
401 if (pixels_buffer[1])
402 free(pixels_buffer[1]);
403 free(Line);
394 return; 404 return;
395 } 405 }
396 406
@@ -472,4 +482,15 @@ void gif_decode(struct gif_decoder *d,
472 } 482 }
473 } 483 }
474#endif 484#endif
485 return;
486
487free_and_return:
488 if (Line)
489 free(Line);
490 if (pixels_buffer[0])
491 free(pixels_buffer[0]);
492 if (pixels_buffer[1])
493 free(pixels_buffer[1]);
494 DGifCloseFile(GifFile);
495 return;
475} 496}
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 {
30}; 30};
31 31
32void gif_decoder_init(struct gif_decoder *decoder, void *mem, size_t size); 32void gif_decoder_init(struct gif_decoder *decoder, void *mem, size_t size);
33void gif_decoder_destroy_memory_pool(struct gif_decoder *d);
33void gif_open(char *filename, struct gif_decoder *d); 34void gif_open(char *filename, struct gif_decoder *d);
34void gif_decode(struct gif_decoder *d, void (*pf_progress)(int current, int total)); 35void gif_decode(struct gif_decoder *d, void (*pf_progress)(int current, int total));
35 36