X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=deanimate.c;h=79751222bccaf6398c9a2ce99084d17ea7bbe952;hp=cd4274230572f3f234880346e8bda316f72c80f6;hb=aba07103acfd91d5d757defe94da356fba33af98;hpb=83a4ca758c4dccd313f23f9d736f43c34e16e08a diff --git a/deanimate.c b/deanimate.c index cd427423..79751222 100644 --- a/deanimate.c +++ b/deanimate.c @@ -1,4 +1,3 @@ -const char deanimate_rcs[] = "$Id: deanimate.c,v 1.21 2011/09/04 11:10:56 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/deanimate.c,v $ @@ -8,10 +7,10 @@ const char deanimate_rcs[] = "$Id: deanimate.c,v 1.21 2011/09/04 11:10:56 fabian * - Deanimation of GIF images * * Copyright : Written by and Copyright (C) 2001 - 2004, 2006 by the - * SourceForge Privoxy team. http://www.privoxy.org/ + * Privoxy team. https://www.privoxy.org/ * * Based on the GIF file format specification (see - * http://tronche.com/computer-graphics/gif/gif89a.html) + * https://tronche.com/computer-graphics/gif/gif89a.html) * and ideas from the Image::DeAnim Perl module by * Ken MacFarlane, * @@ -41,13 +40,11 @@ const char deanimate_rcs[] = "$Id: deanimate.c,v 1.21 2011/09/04 11:10:56 fabian #include #include -#include "errlog.h" #include "project.h" +#include "errlog.h" #include "deanimate.h" #include "miscutil.h" -const char deanimate_h_rcs[] = DEANIMATE_H_VERSION; - /********************************************************************* * * Function : buf_free @@ -134,6 +131,14 @@ static int buf_extend(struct binbuffer *buf, size_t length) *********************************************************************/ static int buf_copy(struct binbuffer *src, struct binbuffer *dst, size_t length) { + /* + * Sanity check: Make sure the source buffer contains + * data and there's work to be done. + */ + if (src->buffer == NULL || src->size == 0 || length == 0) + { + return 1; + } /* * Sanity check: Can't copy more data than we have @@ -307,8 +312,8 @@ static int gif_extract_image(struct binbuffer *src, struct binbuffer *dst) * an (optional) image block and an arbitrary number * of image extension blocks, produce an output GIF with * only one image block that contains the last image - * (extenstion) block of the original. - * Also strip Comments, Application extenstions, etc. + * (extension) block of the original. + * Also strip Comments, Application extensions, etc. * * Parameters : * 1 : src = Pointer to the source binbuffer @@ -323,11 +328,16 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im { unsigned char c; struct binbuffer *image; + int image_buffered = 0; if (NULL == src || NULL == dst) { return 1; } + if (src->size <= 10) + { + return 1; + } c = buf_getbyte(src, 10); @@ -349,7 +359,7 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im /* * Look for global colormap and copy if found. */ - if(c & 0x80) + if (c & 0x80) { int map_length = 3 * (1 << ((c & 0x07) + 1)); if (map_length <= 0) @@ -367,10 +377,7 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im /* * Reserve a buffer for the current image block */ - if (NULL == (image = (struct binbuffer *)zalloc(sizeof(*image)))) - { - return 1; - } + image = zalloc_or_die(sizeof(*image)); /* * Parse the GIF block by block and copy the relevant @@ -381,17 +388,25 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im switch(buf_getbyte(src, 0)) { /* - * End-of-GIF Marker: Append current image and return + * End-of-GIF Marker: Append current image if we got + * one and return. */ case 0x3b: + if (image->size == 0) goto failed; goto write; /* * Image block: Extract to current image buffer. */ case 0x2c: - image->offset = 0; + if (image_buffered == 1) + { + /* Discard previous image. */ + image->offset = 0; + image_buffered = 0; + } if (gif_extract_image(src, image)) goto failed; + image_buffered = 1; if (get_first_image) goto write; continue; @@ -402,14 +417,16 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im switch (buf_getbyte(src, 1)) { /* - * Image extension: Copy extension header and image - * to the current image buffer + * Image extension: Copy extension header + * and continue looking for new blocks. */ case 0xf9: - image->offset = 0; - if (buf_copy(src, image, 8) || buf_getbyte(src, 0) != 0x2c) goto failed; - if (gif_extract_image(src, image)) goto failed; - if (get_first_image) goto write; + if (image_buffered == 1) + { + image->offset = 0; + image_buffered = 0; + } + if (buf_copy(src, image, 8)) goto failed; continue; /*