Removed __APPLE_CC__ from two conditional defines in order to prevent a compiler...
[privoxy.git] / parsers.c
index 96fab7f..6cba35e 100644 (file)
--- a/parsers.c
+++ b/parsers.c
@@ -1,4 +1,4 @@
-const char parsers_rcs[] = "$Id: parsers.c,v 1.269 2012/11/24 14:09:11 fabiankeil Exp $";
+const char parsers_rcs[] = "$Id: parsers.c,v 1.273 2013/01/04 12:19:47 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/parsers.c,v $
@@ -2105,17 +2105,25 @@ static jb_err server_content_type(struct client_state *csp, char **header)
    /* Remove header if it isn't the first Content-Type header */
    if ((csp->content_type & CT_DECLARED))
    {
-     /*
-      * Another, slightly slower, way to see if
-      * we already parsed another Content-Type header.
-      */
-      assert(NULL != get_header_value(csp->headers, "Content-Type:"));
-
-      log_error(LOG_LEVEL_ERROR,
-         "Multiple Content-Type headers. Removing and ignoring: \'%s\'",
-         *header);
-      freez(*header);
-
+      if (content_filters_enabled(csp->action))
+      {
+         /*
+          * Making sure the client interprets the content the same way
+          * Privoxy did is only relevant if Privoxy modified it.
+          *
+          * Checking for this is "hard" as it's not yet known when
+          * this function is called, thus go shopping and and just
+          * check if Privoxy could filter it.
+          *
+          * The main thing is that we don't mess with the headers
+          * unless the user signalled that it's acceptable.
+          */
+         log_error(LOG_LEVEL_HEADER,
+            "Multiple Content-Type headers detected. "
+            "Removing and ignoring: %s",
+            *header);
+         freez(*header);
+      }
       return JB_ERR_OK;
    }
 
@@ -3960,7 +3968,7 @@ static jb_err server_set_cookie(struct client_state *csp, char **header)
          {
             log_error(LOG_LEVEL_FATAL, "Invalid cookie lifetime limit: %s", param);
          }
-         cookie_lifetime *= 60U;
+         cookie_lifetime *= 60;
       }
 
       /* Loop through each tag in the cookie */
@@ -4212,6 +4220,44 @@ static jb_err parse_header_time(const char *header_time, time_t *result)
             continue;
          }
          *result = timegm(&gmt);
+
+#ifdef FEATURE_STRPTIME_SANITY_CHECKS
+         /*
+          * Verify that parsing the date recreated from the first
+          * parse operation gets the previous result. If it doesn't,
+          * either strptime() or strftime() are malfunctioning.
+          *
+          * We could string-compare the recreated date with the original
+          * header date, but this leads to false positives as strptime()
+          * may let %a accept all day formats while strftime() will only
+          * create one.
+          */
+         {
+            char recreated_date[100];
+            struct tm *tm;
+            time_t result2;
+
+            tm = gmtime(result);
+            strftime(recreated_date, sizeof(recreated_date), time_formats[i], tm);
+            memset(&gmt, 0, sizeof(gmt));
+            if (NULL == strptime(recreated_date, time_formats[i], &gmt))
+            {
+               log_error(LOG_LEVEL_ERROR,
+                  "Failed to parse '%s' generated with '%s' to recreate '%s'.",
+                  recreated_date, time_formats[i], header_time);
+               continue;
+            }
+            result2 = timegm(&gmt);
+            if (*result != result2)
+            {
+               log_error(LOG_LEVEL_ERROR, "strftime() and strptime() disagree. "
+                  "Format: '%s'. In: '%s', out: '%s'. %d != %d. Rejecting.",
+                  time_formats[i], header_time, recreated_date, *result, result2);
+               continue;
+            }
+         }
+#endif
+
          return JB_ERR_OK;
       }
    }