Enable sending a custom 'blocked' image. Shows up as
[privoxy.git] / src / filters.c
index 60f47e9..2918ed4 100644 (file)
@@ -1,7 +1,7 @@
-const char filters_rcs[] = "$Id: filters.c,v 1.58 2002/04/24 02:11:17 oes Exp $";
+const char filters_rcs[] = "$Id: filters.c,v 2.4 2003/01/21 02:49:27 david__schmidt Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /cvsroot/ijbswa/current/filters.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/src/filters.c,v $
  *
  * Purpose     :  Declares functions to parse/crunch headers and pages.
  *                Functions declared include:
@@ -38,6 +38,34 @@ const char filters_rcs[] = "$Id: filters.c,v 1.58 2002/04/24 02:11:17 oes Exp $"
  *
  * Revisions   :
  *    $Log: filters.c,v $
+ *    Revision 2.4  2003/01/21 02:49:27  david__schmidt
+ *    Developer TODO 612294: src: C++ keyword as variable name
+ *    I changed all ocurrences of 'new' to 'new_something' wherever I found
+ *    one.  I also brought up all the source files in MSDEV to see if I could
+ *    spot any highlighted keywords that really were variables.  Non-scientific,
+ *    but at least I tried. :-)
+ *
+ *    Revision 2.3  2002/12/28 03:58:19  david__schmidt
+ *    Initial drop of dashboard instrumentation - enabled with
+ *    --enable-activity-console
+ *
+ *    Revision 2.2  2002/09/04 15:38:24  oes
+ *    Synced with the stable branch:
+ *        Revision 1.58.2.2  2002/08/01 17:18:28  oes
+ *        Fixed BR 537651 / SR 579724 (MSIE image detect improper for IE/Mac)
+ *
+ *        Revision 1.58.2.1  2002/07/26 15:18:53  oes
+ *        - Bugfix: Executing a filters without jobs no longer results in
+ *          turing off *all* filters.
+ *        - Security fix: Malicious web servers can't cause a seg fault
+ *          through bogus chunk sizes anymore
+ *
+ *    Revision 2.1  2002/08/26 11:08:18  sarantis
+ *    Fix typo.
+ *
+ *    Revision 2.0  2002/06/04 14:34:21  jongfoster
+ *    Moving source files to src/
+ *
  *    Revision 1.58  2002/04/24 02:11:17  oes
  *    Jon's multiple AF patch: url_actions now evaluates rules
  *    from all AFs.
@@ -215,7 +243,7 @@ const char filters_rcs[] = "$Id: filters.c,v 1.58 2002/04/24 02:11:17 oes Exp $"
  *       generic content modification interface of pcrs_filter_response
  *       and acts as a wrapper to deanimate.c:gif_deanimate()
  *     - Renamed re_process_buffer to pcrs_filter_response
- *     - pcrs_filter_response now returns NULL on failiure
+ *     - pcrs_filter_response now returns NULL on failure
  *     - Removed all #ifdef PCRS
  *
  *    Revision 1.20  2001/07/01 17:01:04  oes
@@ -434,7 +462,9 @@ const char filters_rcs[] = "$Id: filters.c,v 1.58 2002/04/24 02:11:17 oes Exp $"
 #include "list.h"
 #include "deanimate.h"
 #include "urlmatch.h"
-
+#ifdef FEATURE_ACTIVITY_CONSOLE
+#include "stats.h"
+#endif /* def FEATURE_ACTIVITY_CONSOLE */
 #ifdef _WIN32
 #include "win32.h"
 #endif
@@ -500,6 +530,9 @@ int block_acl(struct access_control_addr *dst, struct client_state *csp)
             }
             else
             {
+#ifdef FEATURE_ACTIVITY_CONSOLE
+               accumulate_stats(STATS_ACL_RESTRICT, 1);
+#endif /* def FEATURE_ACTIVITY_CONSOLE */
                return(1);
             }
          }
@@ -718,6 +751,9 @@ struct http_response *block_url(struct client_state *csp)
       /* and handle accordingly: */
       if ((p == NULL) || (0 == strcmpic(p, "pattern")))
       {
+#ifdef FEATURE_ACTIVITY_CONSOLE
+         accumulate_stats(STATS_IMAGE_BLOCK, 1);
+#endif /* def FEATURE_ACTIVITY_CONSOLE */
          rsp->body = bindup(image_pattern_data, image_pattern_length);
          if (rsp->body == NULL)
          {
@@ -735,6 +771,9 @@ struct http_response *block_url(struct client_state *csp)
 
       else if (0 == strcmpic(p, "blank"))
       {
+#ifdef FEATURE_ACTIVITY_CONSOLE
+         accumulate_stats(STATS_IMAGE_BLOCK, 1);
+#endif /* def FEATURE_ACTIVITY_CONSOLE */
          rsp->body = bindup(image_blank_data, image_blank_length);
          if (rsp->body == NULL)
          {
@@ -750,6 +789,23 @@ struct http_response *block_url(struct client_state *csp)
          }
       }
 
+      else if (0 == strcmpic(p, "custom"))
+      {
+         rsp->body = bindup(csp->config->image_blocker_data, csp->config->image_blocker_length);
+         if (rsp->body == NULL)
+         {
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+         rsp->content_length = csp->config->image_blocker_length;
+
+         if (enlist_unique_header(rsp->headers, "Content-Type", csp->config->image_blocker_format))
+         {
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+      }
+
       else
       {
          rsp->status = strdup("302 Local Redirect from Privoxy");
@@ -1078,8 +1134,9 @@ struct http_response *redirect_url(struct client_state *csp)
  *
  * Description :  Given a URL, decide whether it is an image or not,
  *                using either the info from a previous +image action
- *                or, #ifdef FEATURE_IMAGE_DETECT_MSIE, the info from
- *                the browser's accept header.
+ *                or, #ifdef FEATURE_IMAGE_DETECT_MSIE, and the browser
+ *                is MSIE and not on a Mac, tell from the browser's accept
+ *                header.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
@@ -1094,7 +1151,7 @@ int is_imageurl(struct client_state *csp)
    char *tmp;
 
    tmp = get_header_value(csp->headers, "User-Agent:");
-   if (tmp && strstr(tmp, "MSIE"))
+   if (tmp && strstr(tmp, "MSIE") && !strstr(tmp, "Mac_"))
    {
       tmp = get_header_value(csp->headers, "Accept:");
       if (tmp && strstr(tmp, "image/gif"))
@@ -1261,7 +1318,7 @@ char *pcrs_filter_response(struct client_state *csp)
    int hits=0;
    size_t size;
 
-   char *old = csp->iob->cur, *new = NULL;
+   char *old_buf = csp->iob->cur, *new_buf = NULL;
    pcrs_job *job;
 
    struct file_list *fl;
@@ -1315,7 +1372,7 @@ char *pcrs_filter_response(struct client_state *csp)
             if ( NULL == b->joblist )
             {
                log_error(LOG_LEVEL_RE_FILTER, "Filter %s has empty joblist. Nothing to do.", b->name);
-               return(NULL);
+               continue;
             }
 
             log_error(LOG_LEVEL_RE_FILTER, "re_filtering %s%s (size %d) with filter %s...",
@@ -1324,9 +1381,9 @@ char *pcrs_filter_response(struct client_state *csp)
             /* Apply all jobs from the joblist */
             for (job = b->joblist; NULL != job; job = job->next)
             {
-               current_hits += pcrs_execute(job, old, size, &new, &size);
-               if (old != csp->iob->cur) free(old);
-               old=new;
+               current_hits += pcrs_execute(job, old_buf, size, &new_buf, &size);
+               if (old_buf != csp->iob->cur) free(old_buf);
+               old_buf=new_buf;
             }
 
             log_error(LOG_LEVEL_RE_FILTER, " ...produced %d hits (new size %d).", current_hits, size);
@@ -1341,15 +1398,19 @@ char *pcrs_filter_response(struct client_state *csp)
     */
    if (!hits)
    {
-      free(new);
+      free(new_buf);
       return(NULL);
    }
+#ifdef FEATURE_ACTIVITY_CONSOLE
+   else
+     accumulate_stats(STATS_FILTER, hits);
+#endif /* def FEATURE_ACTIVITY_CONSOLE */
 
    csp->flags |= CSP_FLAG_MODIFIED;
    csp->content_length = size;
    IOB_RESET(csp);
 
-   return(new);
+   return(new_buf);
 
 }
 
@@ -1415,6 +1476,9 @@ char *gif_deanimate_response(struct client_state *csp)
       }
       else
       {
+#ifdef FEATURE_ACTIVITY_CONSOLE
+         accumulate_stats(STATS_GIF_DEANIMATE, 1);
+#endif /* def FEATURE_ACTIVITY_CONSOLE */
          log_error(LOG_LEVEL_DEANIMATE, "Success! GIF shrunk from %d bytes to %d.", size, out->offset);
       }
       csp->content_length = out->offset;
@@ -1466,7 +1530,12 @@ int remove_chunked_transfer_coding(char *buffer, const size_t size)
          log_error(LOG_LEVEL_ERROR, "Parse error while stripping \"chunked\" transfer coding");
          return(0);
       }
-      newsize += chunksize;
+
+      if ((newsize += chunksize) >= size)
+      {
+         log_error(LOG_LEVEL_ERROR, "Chunksize exceeds buffer in  \"chunked\" transfer coding");
+         return(0);
+      }
       from_p += 2;
 
       memmove(to_p, from_p, (size_t) chunksize);