Plug memory leak introduced with my last commit.
[privoxy.git] / parsers.c
index 2bd062b..361eb27 100644 (file)
--- a/parsers.c
+++ b/parsers.c
@@ -1,4 +1,4 @@
-const char parsers_rcs[] = "$Id: parsers.c,v 1.108 2007/08/28 18:21:03 fabiankeil Exp $";
+const char parsers_rcs[] = "$Id: parsers.c,v 1.112 2007/10/09 16:38:40 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/parsers.c,v $
@@ -44,6 +44,21 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.108 2007/08/28 18:21:03 fabiankei
  *
  * Revisions   :
  *    $Log: parsers.c,v $
+ *    Revision 1.112  2007/10/09 16:38:40  fabiankeil
+ *    Remove Range and If-Range headers if content filtering is enabled.
+ *
+ *    Revision 1.111  2007/10/04 18:07:00  fabiankeil
+ *    Move ACTION_VANILLA_WAFER handling from jcc's chat() into
+ *    client_cookie_adder() to make sure send-vanilla-wafer can be
+ *    controlled through tags (and thus regression-tested).
+ *
+ *    Revision 1.110  2007/09/29 10:42:37  fabiankeil
+ *    - Remove "scanning headers for" log message again.
+ *    - Some more whitespace fixes.
+ *
+ *    Revision 1.109  2007/09/08 14:25:48  fabiankeil
+ *    Refactor client_referrer() and add conditional-forge parameter.
+ *
  *    Revision 1.108  2007/08/28 18:21:03  fabiankeil
  *    A bunch of whitespace fixes, pointy hat to me.
  *
@@ -785,6 +800,7 @@ static jb_err client_accept_language    (struct client_state *csp, char **header
 static jb_err client_if_none_match      (struct client_state *csp, char **header);
 static jb_err crunch_client_header      (struct client_state *csp, char **header);
 static jb_err client_x_filter           (struct client_state *csp, char **header);
+static jb_err client_range              (struct client_state *csp, char **header);
 static jb_err server_set_cookie         (struct client_state *csp, char **header);
 static jb_err server_content_type       (struct client_state *csp, char **header);
 static jb_err server_content_length     (struct client_state *csp, char **header);
@@ -824,6 +840,8 @@ const struct parsers client_patterns[] = {
    { "max-forwards:",            13,   client_max_forwards },
    { "Accept-Language:",         16,   client_accept_language },
    { "if-none-match:",           14,   client_if_none_match },
+   { "Range:",                    6,   client_range },
+   { "If-Range:",                 9,   client_range },
    { "X-Filter:",                 9,   client_x_filter },
    { "*",                         0,   crunch_client_header },
    { "*",                         0,   filter_header },
@@ -865,12 +883,21 @@ const add_header_func_ptr add_client_headers[] = {
    NULL
 };
 
-
 const add_header_func_ptr add_server_headers[] = {
    connection_close_adder,
    NULL
 };
 
+/* The vanilla wafer. */
+static const char VANILLA_WAFER[] =
+   "NOTICE=TO_WHOM_IT_MAY_CONCERN_"
+   "Do_not_send_me_any_copyrighted_information_other_than_the_"
+   "document_that_I_am_requesting_or_any_of_its_necessary_components._"
+   "In_particular_do_not_send_me_any_cookies_that_"
+   "are_subject_to_a_claim_of_copyright_by_anybody._"
+   "Take_notice_that_I_refuse_to_be_bound_by_any_license_condition_"
+   "(copyright_or_otherwise)_applying_to_any_cookie._";
+
 /*********************************************************************
  *
  * Function    :  flush_socket
@@ -1104,7 +1131,7 @@ jb_err decompress_iob(struct client_state *csp)
              * The number of bytes to skip should be positive
              * and we'd like to stay in the buffer.
              */
-            if((skip_bytes < 0) || (skip_bytes >= (csp->iob->eod - cur)))
+            if ((skip_bytes < 0) || (skip_bytes >= (csp->iob->eod - cur)))
             {
                log_error(LOG_LEVEL_ERROR,
                   "Unreasonable amount of bytes to skip (%d). Stopping decompression",
@@ -1481,8 +1508,6 @@ static jb_err scan_headers(struct client_state *csp)
    struct list_entry *h; /* Header */
    jb_err err = JB_ERR_OK;
 
-   log_error(LOG_LEVEL_HEADER, "scanning headers for: %s", csp->http->url);
-
    for (h = csp->headers->first; (err == JB_ERR_OK) && (h != NULL) ; h = h->next)
    {
       /* Header crunch()ed in previous run? -> ignore */
@@ -1507,6 +1532,8 @@ static jb_err scan_headers(struct client_state *csp)
  *                As a side effect it frees the space used by the original
  *                header lines.
  *
+ *                XXX: should be split to remove the first_run hack.
+ *
  * Parameters  :
  *          1  :  pats = list of patterns to match against headers
  *          2  :  more_headers = list of functions to add more
@@ -1936,7 +1963,7 @@ static jb_err filter_header(struct client_state *csp, char **header)
                      /* RegEx failure */
                      log_error(LOG_LEVEL_ERROR, "Filtering \'%s\' with \'%s\' didn't work out: %s",
                         *header, b->name, pcrs_strerror(matches));
-                     ifnewheader != NULL)
+                     if (newheader != NULL)
                      {
                         log_error(LOG_LEVEL_ERROR, "Freeing what's left: %s", newheader);
                         freez(newheader);
@@ -2042,6 +2069,7 @@ static jb_err crumble(struct client_state *csp, char **header)
    return JB_ERR_OK;
 }
 
+
 /*********************************************************************
  *
  * Function    :  crunch_server_header
@@ -2398,6 +2426,7 @@ static jb_err server_content_md5(struct client_state *csp, char **header)
    return JB_ERR_OK;
 }
 
+
 /*********************************************************************
  *
  * Function    :  server_content_disposition
@@ -2461,6 +2490,7 @@ static jb_err server_content_disposition(struct client_state *csp, char **header
    return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
 }
 
+
 /*********************************************************************
  *
  * Function    :  server_last_modified
@@ -2580,7 +2610,7 @@ static jb_err server_last_modified(struct client_state *csp, char **header)
                return JB_ERR_MEMORY;  
             }
 
-            if(LOG_LEVEL_HEADER & debug) /* Save cycles if the user isn't interested. */
+            if (LOG_LEVEL_HEADER & debug) /* Save cycles if the user isn't interested. */
             {
                days    = rtime / (3600 * 24);
                hours   = rtime / 3600 % 24;
@@ -2904,6 +2934,7 @@ static jb_err client_uagent(struct client_state *csp, char **header)
    return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
 }
 
+
 /*********************************************************************
  *
  * Function    :  client_ua
@@ -3197,6 +3228,7 @@ static jb_err client_host(struct client_state *csp, char **header)
    return JB_ERR_OK;
 }
 
+
 /*********************************************************************
  *
  * Function    :  client_if_modified_since
@@ -3261,11 +3293,11 @@ static jb_err client_if_modified_since(struct client_state *csp, char **header)
          else
          {
             rtime = strtol(newval, &endptr, 0);
-            if(rtime)
+            if (rtime)
             {
                log_error(LOG_LEVEL_HEADER, "Randomizing: %s (random range: %d minut%s)",
                   *header, rtime, (rtime == 1 || rtime == -1) ? "e": "es");
-               if(rtime < 0)
+               if (rtime < 0)
                {
                   rtime *= -1; 
                   negative = 1;
@@ -3300,7 +3332,7 @@ static jb_err client_if_modified_since(struct client_state *csp, char **header)
                return JB_ERR_MEMORY;  
             }
 
-            if(LOG_LEVEL_HEADER & debug) /* Save cycles if the user isn't interested. */
+            if (LOG_LEVEL_HEADER & debug) /* Save cycles if the user isn't interested. */
             {
                hours   = rtime / 3600;
                minutes = rtime / 60 % 60;
@@ -3317,6 +3349,7 @@ static jb_err client_if_modified_since(struct client_state *csp, char **header)
    return JB_ERR_OK;
 }
 
+
 /*********************************************************************
  *
  * Function    :  client_if_none_match
@@ -3345,6 +3378,7 @@ static jb_err client_if_none_match(struct client_state *csp, char **header)
    return JB_ERR_OK;
 }
 
+
 /*********************************************************************
  *
  * Function    :  client_x_filter
@@ -3390,6 +3424,42 @@ jb_err client_x_filter(struct client_state *csp, char **header)
    return JB_ERR_OK; 
 }
 
+
+/*********************************************************************
+ *
+ * Function    :  client_range
+ *
+ * Description :  Removes Range and If-Range headers if content
+ *                filtering is enabled. If the client's version of
+ *                the document has been altered by Privoxy, the server
+ *                could interpret the range differently than the client
+ *                intended in which case the user could end up with
+ *                corrupted content.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
+ *
+ * Returns     :  JB_ERR_OK
+ *
+ *********************************************************************/
+static jb_err client_range(struct client_state *csp, char **header)
+{
+   if (((csp->rlist != NULL) &&
+       (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER]))) ||
+       (csp->action->flags & (ACTION_DEANIMATE|ACTION_JPEG_INSPECT|ACTION_NO_POPUPS)))
+   {
+      log_error(LOG_LEVEL_HEADER, "Content filtering is enabled."
+         " Crunching: \'%s\' to prevent range-mismatch problems.", *header);
+      freez(*header);
+   }
+
+   return JB_ERR_OK; 
+}
+
 /* the following functions add headers directly to the header list */
 
 /*********************************************************************
@@ -3462,9 +3532,21 @@ jb_err client_cookie_adder(struct client_state *csp)
 {
    char *tmp;
    struct list_entry *wafer;
-   struct list_entry *wafer_list = csp->action->multi[ACTION_MULTI_WAFER]->first;
+   struct list_entry *wafer_list;
    jb_err err;
 
+   /*
+    * If the user has not supplied any wafers, and the user has not
+    * told us to suppress the vanilla wafer, then send the vanilla wafer.
+    */
+   if ((0 != (csp->action->flags & ACTION_VANILLA_WAFER))
+      && list_is_empty(csp->action->multi[ACTION_MULTI_WAFER]))
+   {
+      enlist(csp->action->multi[ACTION_MULTI_WAFER], VANILLA_WAFER);
+   }
+
+   wafer_list = csp->action->multi[ACTION_MULTI_WAFER]->first;
+
    if (NULL == wafer_list)
    {
       /* Nothing to do */
@@ -3950,6 +4032,7 @@ int strclean(const char *string, const char *substring)
 }
 #endif /* def FEATURE_FORCE_LOAD */
 
+
 /*********************************************************************
  *
  * Function    :  parse_header_time
@@ -3999,6 +4082,7 @@ static jb_err parse_header_time(const char *header_time, time_t *result)
 
 }
 
+
 /*********************************************************************
  *
  * Function    :  get_destination_from_headers