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 /apps | |
parent | f379e1dbb3150a617a910c7709cc85dccc79861b (diff) | |
download | rockbox-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.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, | |||
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 | ||
118 | void gif_decoder_destroy_memory_pool(struct gif_decoder *d) | ||
119 | { | ||
120 | destroy_memory_pool(d->mem); | ||
121 | } | ||
122 | |||
118 | void gif_open(char *filename, struct gif_decoder *d) | 123 | void 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 | |||
487 | free_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 | ||
32 | void gif_decoder_init(struct gif_decoder *decoder, void *mem, size_t size); | 32 | void gif_decoder_init(struct gif_decoder *decoder, void *mem, size_t size); |
33 | void gif_decoder_destroy_memory_pool(struct gif_decoder *d); | ||
33 | void gif_open(char *filename, struct gif_decoder *d); | 34 | void gif_open(char *filename, struct gif_decoder *d); |
34 | void gif_decode(struct gif_decoder *d, void (*pf_progress)(int current, int total)); | 35 | void gif_decode(struct gif_decoder *d, void (*pf_progress)(int current, int total)); |
35 | 36 | ||