Merge in changes from Debian packages 3.0.0-3 to 3.0.0-5
[privoxy.git] / src / filters.c
index 9dd36b9..814cf20 100644 (file)
@@ -1,4 +1,4 @@
-const char filters_rcs[] = "$Id: filters.c,v 2.0 2002/06/04 14:34:21 jongfoster Exp $";
+const char filters_rcs[] = "$Id: filters.c,v 2.3 2002/12/28 03:58:19 david__schmidt Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/src/filters.c,v $
@@ -38,6 +38,24 @@ const char filters_rcs[] = "$Id: filters.c,v 2.0 2002/06/04 14:34:21 jongfoster
  *
  * Revisions   :
  *    $Log: filters.c,v $
+ *    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/
  *
@@ -437,7 +455,9 @@ const char filters_rcs[] = "$Id: filters.c,v 2.0 2002/06/04 14:34:21 jongfoster
 #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
@@ -503,6 +523,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);
             }
          }
@@ -721,6 +744,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)
          {
@@ -738,6 +764,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)
          {
@@ -1081,8 +1110,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...)
@@ -1097,7 +1127,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"))
@@ -1264,7 +1294,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;
@@ -1318,7 +1348,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...",
@@ -1327,9 +1357,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);
@@ -1344,15 +1374,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);
 
 }
 
@@ -1418,6 +1452,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;
@@ -1469,7 +1506,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);