changeset 1522:85062b64ae9d

cookies allow Expires attr's value to be quoted. sourceforge sends cookies this way. It seems that quotes around values are generally to be ignored, i.e., not stripped or anything, but I asked the draft spec author about this case, and he reports that he has fixed his algorithm to allow leading and trailing delimiters around cookie-date. If I/someone eventually does make the timestamp code follow the algorithm more closely, the stripping would no longer need to be done here. As for whether we'd want to continue to use that code for the stricter server_date that we get from the HTTP Date header, I'm not sure at the moment. I've already added one case to it that wouldn't be legal for the header, though...
author corvid <corvid@lavabit.com>
date Mon, 18 Jan 2010 00:57:58 +0000
parents 96f19eb5687f
children 2339c63f60c5
files dpi/cookies.c
diffstat 1 files changed, 39 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/dpi/cookies.c	Fri Jan 15 19:23:04 2010 +0000
+++ b/dpi/cookies.c	Mon Jan 18 00:57:58 2010 +0000
@@ -639,6 +639,44 @@
 }
 
 /*
+ * Handle Expires attribute.
+ * Note that this CAN MODIFY the value string.
+ */
+static time_t Cookies_expires_attr(char *value, const char *server_date)
+{
+   time_t exptime;
+
+   if (*value == '"' && value[strlen(value) - 1] == '"') {
+      /* In this one case, pay attention to quotes */
+      value[strlen(value) - 1] = '\0';
+      value++;
+   }
+   exptime = Cookies_create_timestamp(value);
+   if (exptime && server_date) {
+      time_t server_time = Cookies_create_timestamp(server_date);
+
+      if (server_time) {
+         time_t now = time(NULL);
+         time_t client_time = exptime + now - server_time;
+
+         if (server_time == exptime) {
+             exptime = now;
+         } else if ((exptime > now) == (client_time > now)) {
+            exptime = client_time;
+         } else {
+            /* Don't want to wrap around at the extremes of representable
+             * values thanks to clock skew.
+             */
+            MSG("At %ld, %ld was trying to turn into %ld\n",
+                (long)now, (long)exptime,
+                (long)client_time);
+         }
+      }
+   }
+   return exptime;
+}
+
+/*
  * Parse cookie. A cookie might look something like:
  * "Name=Val; Domain=example.com; Max-Age=3600; HttpOnly"
  */
@@ -703,30 +741,7 @@
       } else if (dStrcasecmp(attr, "Expires") == 0) {
          if (!max_age) {
             value = Cookies_parse_value(&str);
-            cookie->expires_at = Cookies_create_timestamp(value);
-            if (cookie->expires_at && server_date) {
-               time_t server_time = Cookies_create_timestamp(server_date);
-
-               if (server_time) {
-                  time_t now = time(NULL);
-                  time_t client_time = cookie->expires_at + now - server_time;
-
-                  if (server_time == cookie->expires_at) {
-                      cookie->expires_at = now;
-                  } else if ((cookie->expires_at > now) ==
-                             (client_time > now)) {
-                     cookie->expires_at = client_time;
-                  } else {
-                     /* It seems not at all unlikely that bad server code will
-                      * fail to take normal clock skew into account when
-                      * setting max/min cookie values.
-                      */
-                     MSG("At %ld, %ld was trying to turn into %ld\n",
-                         (long)now, (long)cookie->expires_at,
-                         (long)client_time);
-                  }
-               }
-            }
+            cookie->expires_at = Cookies_expires_attr(value, server_date);
             expires = TRUE;
             dFree(value);
             MSG("Expires in %ld seconds, at %s",