Block feedproxy.google.com/~r/.*/~4/.
[privoxy.git] / deanimate.c
index 5eaccb3..2ad811c 100644 (file)
@@ -1,16 +1,18 @@
-const char deanimate_rcs[] = "$Id: deanimate.c,v 1.5 2001/09/10 10:16:06 oes Exp $";
+const char deanimate_rcs[] = "$Id: deanimate.c,v 1.18 2008/03/28 15:13:38 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/deanimate.c,v $
  *
- * Purpose     :  Declares functions to deanimate GIF images on the fly.
+ * Purpose     :  Declares functions to manipulate binary images on the
+ *                fly.  High-level functions include:
+ *                  - Deanimation of GIF images
  *                
  *                Functions declared include: gif_deanimate, buf_free,
- *                buf_copy,  buf_getbyte, gif_skip_data_block, and
- *                gif_extract_image
+ *                buf_copy,  buf_getbyte, gif_skip_data_block
+ *                and gif_extract_image
  *
- * Copyright   :  Written by and Copyright (C) 2001 by the the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ * Copyright   :  Written by and Copyright (C) 2001 - 2004, 2006 by the
+ *                SourceForge Privoxy team. http://www.privoxy.org/
  *
  *                Based on the GIF file format specification (see
  *                http://tronche.com/computer-graphics/gif/gif89a.html)
@@ -37,6 +39,53 @@ const char deanimate_rcs[] = "$Id: deanimate.c,v 1.5 2001/09/10 10:16:06 oes Exp
  *
  * Revisions   :
  *    $Log: deanimate.c,v $
+ *    Revision 1.18  2008/03/28 15:13:38  fabiankeil
+ *    Remove inspect-jpegs action.
+ *
+ *    Revision 1.17  2007/08/05 13:42:22  fabiankeil
+ *    #1763173 from Stefan Huehner: declare some more functions static.
+ *
+ *    Revision 1.16  2007/07/14 08:01:58  fabiankeil
+ *    s@failiure@failure@
+ *
+ *    Revision 1.15  2007/01/03 14:39:19  fabiankeil
+ *    Fix a gcc43 warning and mark the binbuffer
+ *    as immutable for buf_getbyte().
+ *
+ *    Revision 1.14  2006/07/18 14:48:45  david__schmidt
+ *    Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
+ *    with what was really the latest development (the v_3_0_branch branch)
+ *
+ *    Revision 1.12.2.1  2004/10/03 12:53:32  david__schmidt
+ *    Add the ability to check jpeg images for invalid
+ *    lengths of comment blocks.  Defensive strategy
+ *    against the exploit:
+ *       Microsoft Security Bulletin MS04-028
+ *       Buffer Overrun in JPEG Processing (GDI+) Could
+ *       Allow Code Execution (833987)
+ *    Enabled with +inspect-jpegs in actions files.
+ *
+ *    Revision 1.12  2002/05/12 21:36:29  jongfoster
+ *    Correcting function comments
+ *
+ *    Revision 1.11  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.10  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.9  2002/03/13 00:27:04  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.8  2002/03/09 19:42:47  jongfoster
+ *    Fixing more warnings
+ *
+ *    Revision 1.7  2002/03/08 17:46:04  jongfoster
+ *    Fixing int/size_t warnings
+ *
+ *    Revision 1.6  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
  *    Revision 1.5  2001/09/10 10:16:06  oes
  *    Silenced compiler warnings
  *
@@ -62,6 +111,7 @@ const char deanimate_rcs[] = "$Id: deanimate.c,v 1.5 2001/09/10 10:16:06 oes Exp
 #include <string.h>
 #include <fcntl.h>
 
+#include "errlog.h"
 #include "project.h"
 #include "deanimate.h"
 #include "miscutil.h"
@@ -100,7 +150,7 @@ void buf_free(struct binbuffer *buf)
  *
  * Description :  Ensure that a given binbuffer can hold a given amount
  *                of bytes, by reallocating its buffer if necessary.
- *                Allocate new mem in chunks of 1000 bytes, so we don't
+ *                Allocate new mem in chunks of 1024 bytes, so we don't
  *                have to realloc() too often.
  *
  * Parameters  :
@@ -108,16 +158,16 @@ void buf_free(struct binbuffer *buf)
  *          2  :  length = Desired minimum size
  *                
  *
- * Returns     :  0 on success, 1 on failiure.
+ * Returns     :  0 on success, 1 on failure.
  *
  *********************************************************************/
-int buf_extend(struct binbuffer *buf, size_t length)
+static int buf_extend(struct binbuffer *buf, size_t length)
 {
    char *newbuf;
 
    if (buf->offset + length > buf->size)
    {
-      buf->size = buf->size + length + 1000 - (buf->size + length) % 1000;
+      buf->size = ((buf->size + length + (size_t)1023) & ~(size_t)1023);
       newbuf = (char *)realloc(buf->buffer, buf->size);
 
       if (newbuf == NULL)
@@ -149,10 +199,10 @@ int buf_extend(struct binbuffer *buf, size_t length)
  *          2  :  dst = Pointer to the destination binbuffer
  *          3  :  length = Number of bytes to be copied
  *
- * Returns     :  0 on success, 1 on failiure.
+ * Returns     :  0 on success, 1 on failure.
  *
  *********************************************************************/
-int buf_copy(struct binbuffer *src, struct binbuffer *dst, size_t length)
+static int buf_copy(struct binbuffer *src, struct binbuffer *dst, size_t length)
 {
 
    /*
@@ -192,13 +242,13 @@ int buf_copy(struct binbuffer *src, struct binbuffer *dst, size_t length)
  *                given offset
  *
  * Parameters  :
- *          1  :  buf = Pointer to the source binbuffer
+ *          1  :  src = Pointer to the source binbuffer
  *          2  :  offset = Offset to the desired byte
  *
- * Returns     :  The byte on success, or 0 on failiure
+ * Returns     :  The byte on success, or 0 on failure
  *
  *********************************************************************/
-unsigned char buf_getbyte(struct binbuffer *src, int offset)
+static unsigned char buf_getbyte(const struct binbuffer *src, size_t offset)
 {
    if (src->offset + offset < src->size)
    {
@@ -224,10 +274,10 @@ unsigned char buf_getbyte(struct binbuffer *src, int offset)
  * Parameters  :
  *          1  :  buf = Pointer to the binbuffer
  *
- * Returns     :  0 on success, or 1 on failiure
+ * Returns     :  0 on success, or 1 on failure
  *
  *********************************************************************/
-int gif_skip_data_block(struct binbuffer *buf)
+static int gif_skip_data_block(struct binbuffer *buf)
 {
    unsigned char c;
 
@@ -236,9 +286,10 @@ int gif_skip_data_block(struct binbuffer *buf)
     * by a one-byte length field, with the last chunk having
     * zero length.
     */
-   while((c = buf_getbyte(buf, 0)))
+   while((c = buf_getbyte(buf, 0)) != '\0')
    {
-      if ((buf->offset += c + 1) >= buf->size - 1)
+      buf->offset += (size_t)c + 1;
+      if (buf->offset >= buf->size - 1)
       {
          return 1;
       }
@@ -263,13 +314,13 @@ int gif_skip_data_block(struct binbuffer *buf)
  *          1  :  src = Pointer to the source binbuffer
  *          2  :  dst = Pointer to the destination binbuffer
  *
- * Returns     :  0 on success, or 1 on failiure
+ * Returns     :  0 on success, or 1 on failure
  *
  *********************************************************************/
-int gif_extract_image(struct binbuffer *src, struct binbuffer *dst)
+static int gif_extract_image(struct binbuffer *src, struct binbuffer *dst)
 {
    unsigned char c;
-   
+
    /*
     * Remember the colormap flag and copy the image head
     */
@@ -284,7 +335,14 @@ int gif_extract_image(struct binbuffer *src, struct binbuffer *dst)
     */
    if (c & 0x80)
    {
-      if (buf_copy(src, dst, (size_t) 3 * (1 << ((c & 0x07) + 1))))
+      int map_length = 3 * (1 << ((c & 0x07) + 1));
+      if (map_length <= 0)
+      {
+         log_error(LOG_LEVEL_DEANIMATE,
+            "colormap length = %d (%c)?", map_length, c);
+         return 1;
+      }
+      if (buf_copy(src, dst, (size_t)map_length))
       {
          return 1;
       }           
@@ -294,16 +352,16 @@ int gif_extract_image(struct binbuffer *src, struct binbuffer *dst)
    /*
     * Copy the image chunk by chunk.
     */
-   while((c = buf_getbyte(src, 0)))
+   while((c = buf_getbyte(src, 0)) != '\0')
    {
-      if (buf_copy(src, dst, (size_t) c + 1)) return 1;
+      if (buf_copy(src, dst, 1 + (size_t) c)) return 1;
    }
    if (buf_copy(src, dst, 1)) return 1;
 
    /*
     * Trim and rewind the dst buffer
     */
-   if (NULL == (dst->buffer = (char *)realloc(dst->buffer, (size_t) dst->offset))) return 1;
+   if (NULL == (dst->buffer = (char *)realloc(dst->buffer, dst->offset))) return 1;
    dst->size = dst->offset;
    dst->offset = 0;
 
@@ -328,7 +386,7 @@ int gif_extract_image(struct binbuffer *src, struct binbuffer *dst)
  *          3  :  get_first_image = Flag: If set, get the first image
  *                                        If unset (default), get the last
  *
- * Returns     :  0 on success, or 1 on failiure
+ * Returns     :  0 on success, or 1 on failure
  *
  *********************************************************************/
 int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_image)
@@ -363,7 +421,14 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im
     */
    if(c & 0x80)
    {
-      if (buf_copy(src, dst, (size_t) 3 * (1 << ((c & 0x07) + 1))))
+      int map_length = 3 * (1 << ((c & 0x07) + 1));
+      if (map_length <= 0)
+      {
+         log_error(LOG_LEVEL_DEANIMATE,
+            "colormap length = %d (%c)?", map_length, c);
+         return 1;
+      }
+      if (buf_copy(src, dst, (size_t)map_length))
       {
          return 1;
       }