gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libmicrohttpd] 06/06: Refactored cookies parsing.


From: gnunet
Subject: [libmicrohttpd] 06/06: Refactored cookies parsing.
Date: Mon, 19 Dec 2022 16:18:03 +0100

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

commit 1e7ad3010da7d2be1afe219da0ba84dd129f9c4e
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Tue Dec 6 23:40:21 2022 +0300

    Refactored cookies parsing.
    
    The new code is more compact as duplicated code was removed.
    Added testing for various cookies parsing strictness levels.
---
 src/microhttpd/connection.c       | 299 ++++++++-------------
 src/testcurl/Makefile.am          |  14 +-
 src/testcurl/test_parse_cookies.c | 540 ++++++++++++++++++++++++++++++++++----
 3 files changed, 614 insertions(+), 239 deletions(-)

diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 960c22db..16c5fb93 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -2826,146 +2826,6 @@ enum _MHD_ParseCookie
 };
 
 
-/**
- * Parse the cookies string (see RFC 6265).
- *
- * Parsing may fail if the string is not formed strictly as defined by RFC 
6265.
- *
- * @param str the string to parse, without leading whitespaces
- * @param str_len the size of the @a str, not including mandatory
- *                zero-termination
- * @param connection the connection to add parsed cookies
- * @return #MHD_PARSE_COOKIE_OK for success, error code otherwise
- */
-static enum _MHD_ParseCookie
-parse_cookies_string_strict (char *str,
-                             size_t str_len,
-                             struct MHD_Connection *connection)
-{
-  size_t i;
-
-  i = 0;
-  while (i < str_len)
-  {
-    size_t name_start;
-    size_t name_len;
-    size_t value_start;
-    size_t value_len;
-    bool val_quoted;
-    /* 'i' must point to the first char of cookie-name */
-    name_start = i;
-    /* Find the end of the cookie-name */
-    do
-    {
-      const char l = str[i];
-      if (('=' == l) || (' ' == l) || ('\t' == l) || ('"' == l) || (',' == l) 
||
-          (';' == l) || (0 == l))
-        break;
-    } while (str_len > ++i);
-    if ((str_len == i) || ('=' != str[i]) || (name_start == i))
-      return MHD_PARSE_COOKIE_MALFORMED; /* Incomplete cookie name */
-    name_len = i - name_start;
-    /* 'i' must point to the '=' char */
-    mhd_assert ('=' == str[i]);
-    i++;
-    /* 'i' must point to the first char of cookie-value */
-    if (str_len == i)
-    {
-      value_start = 0;
-      value_len = 0;
-#ifdef _DEBUG
-      val_quoted = false; /* This assignment used in assert */
-#endif
-    }
-    else
-    {
-      bool valid_cookie;
-      val_quoted = ('"' == str[i]);
-      if (val_quoted)
-        i++;
-      value_start = i;
-      /* Find the end of the cookie-value */
-      while (str_len > i)
-      {
-        const char l = str[i];
-        if ((';' == l) || ('"' == l) || (' ' == l) || ('\t' == l)
-            || (',' == l) || ('\\' == l) || (0 == l))
-          break;
-        i++;
-      }
-      value_len = i - value_start;
-      if (val_quoted)
-      {
-        if ((str_len == i) || ('"' != str[i]))
-          return MHD_PARSE_COOKIE_MALFORMED; /* Incomplete cookie value, no 
closing quote */
-        i++;
-      }
-      if (str_len == i)
-        valid_cookie = true;
-      else if (';' == str[i])
-        valid_cookie = true;
-      else if ((' ' == str[i]) || ('\t' == str[i]))
-      { /* Optional whitespace at the end of the string? */
-        while (str_len > ++i)
-        {
-          if ((' ' != str[i]) && ('\t' != str[i]))
-            break;
-        }
-        if (str_len == i)
-          valid_cookie = true;
-        else
-          valid_cookie = false;
-      }
-      else
-        valid_cookie = false;
-
-      if (! valid_cookie)
-        return MHD_PARSE_COOKIE_MALFORMED; /* Garbage at the end of the cookie 
value */
-    }
-    mhd_assert (0 != name_len);
-    str[name_start + name_len] = 0; /* Zero-terminate the name */
-    if (0 != value_len)
-    {
-      mhd_assert (0 == str[i] || ';' == str[i]);
-      mhd_assert (! val_quoted || ';' == str[i]);
-      str[value_start + value_len] = 0; /* Zero-terminate the value */
-      if (MHD_NO ==
-          MHD_set_connection_value_n_nocheck_ (connection,
-                                               MHD_COOKIE_KIND,
-                                               str + name_start,
-                                               name_len,
-                                               str + value_start,
-                                               value_len))
-        return MHD_PARSE_COOKIE_NO_MEMORY;
-    }
-    else
-    {
-      if (MHD_NO ==
-          MHD_set_connection_value_n_nocheck_ (connection,
-                                               MHD_COOKIE_KIND,
-                                               str + name_start,
-                                               name_len,
-                                               "",
-                                               0))
-        return MHD_PARSE_COOKIE_NO_MEMORY;
-    }
-    if (str_len > i)
-    {
-      mhd_assert (0 == str[i] || ';' == str[i]);
-      mhd_assert (! val_quoted || ';' == str[i]);
-      mhd_assert (';' != str[i] || val_quoted || 0 == value_len);
-      i++;
-      if (str_len == i)
-        return MHD_PARSE_COOKIE_MALFORMED;  /* No cookie name after semicolon 
*/
-      if (' ' != str[i])
-        return MHD_PARSE_COOKIE_MALFORMED;  /* No space after semicolon */
-      i++;
-    }
-  }
-  return MHD_PARSE_COOKIE_OK;
-}
-
-
 /**
  * Parse the cookies string (see RFC 6265).
  *
@@ -2979,12 +2839,22 @@ parse_cookies_string_strict (char *str,
  * @return #MHD_PARSE_COOKIE_OK for success, error code otherwise
  */
 static enum _MHD_ParseCookie
-parse_cookies_string_lenient (char *str,
-                              size_t str_len,
-                              struct MHD_Connection *connection)
+parse_cookies_string (char *str,
+                      const size_t str_len,
+                      struct MHD_Connection *connection)
 {
   size_t i;
   bool non_strict;
+  /* Skip extra whitespaces and empty cookies */
+  const bool allow_wsp_empty = (0 >= connection->daemon->strict_for_client);
+  /* Allow whitespaces around '=' character */
+  const bool wsp_around_eq = (0 > connection->daemon->strict_for_client);
+  /* Allow whitespaces in quoted cookie value */
+  const bool wsp_in_quoted = (0 >= connection->daemon->strict_for_client);
+  /* Allow tab as space after semicolon between cookies */
+  const bool tab_as_sp = (0 >= connection->daemon->strict_for_client);
+  /* Allow no space after semicolon between cookies */
+  const bool allow_no_space = (0 >= connection->daemon->strict_for_client);
 
   non_strict = false;
   i = 0;
@@ -2998,6 +2868,8 @@ parse_cookies_string_lenient (char *str,
     /* Skip any whitespaces and empty cookies */
     while (' ' == str[i] || '\t' == str[i] || ';' == str[i])
     {
+      if (! allow_wsp_empty)
+        return MHD_PARSE_COOKIE_MALFORMED;
       non_strict = true;
       i++;
       if (i == str_len)
@@ -3017,6 +2889,8 @@ parse_cookies_string_lenient (char *str,
     /* Skip any whitespaces */
     while (str_len > i && (' ' == str[i] || '\t' == str[i]))
     {
+      if (! wsp_around_eq)
+        return MHD_PARSE_COOKIE_MALFORMED;
       non_strict = true;
       i++;
     }
@@ -3028,6 +2902,8 @@ parse_cookies_string_lenient (char *str,
     /* Skip any whitespaces */
     while (str_len > i && (' ' == str[i] || '\t' == str[i]))
     {
+      if (! wsp_around_eq)
+        return MHD_PARSE_COOKIE_MALFORMED;
       non_strict = true;
       i++;
     }
@@ -3058,6 +2934,8 @@ parse_cookies_string_lenient (char *str,
         {
           if (! val_quoted)
             break;
+          if (! wsp_in_quoted)
+            return MHD_PARSE_COOKIE_MALFORMED;
           non_strict = true;
         }
         i++;
@@ -3070,10 +2948,19 @@ parse_cookies_string_lenient (char *str,
         i++;
       }
       /* Skip any whitespaces */
-      while (str_len > i && (' ' == str[i] || '\t' == str[i]))
+      if ((str_len > i) && ((' ' == str[i]) || ('\t' == str[i])))
       {
-        non_strict = true;
-        i++;
+        do
+        {
+          i++;
+        } while (str_len > i && (' ' == str[i] || '\t' == str[i]));
+        /* Whitespace at the end? */
+        if (str_len > i)
+        {
+          if (! allow_wsp_empty)
+            return MHD_PARSE_COOKIE_MALFORMED;
+          non_strict = true;
+        }
       }
       if (str_len == i)
         valid_cookie = true;
@@ -3118,11 +3005,29 @@ parse_cookies_string_lenient (char *str,
       mhd_assert (';' != str[i] || val_quoted || non_strict || 0 == value_len);
       i++;
       if (str_len == i)
-        non_strict = true;  /* No cookie name after semicolon */
+      { /* No next cookie after semicolon */
+        if (! allow_wsp_empty)
+          return MHD_PARSE_COOKIE_MALFORMED;
+        non_strict = true;
+      }
       else if (' ' != str[i])
-        non_strict = true;  /* No space after semicolon */
+      {/* No space after semicolon */
+        if (('\t' == str[i]) && tab_as_sp)
+          i++;
+        else if (! allow_no_space)
+          return MHD_PARSE_COOKIE_MALFORMED;
+        non_strict = true;
+      }
       else
+      {
         i++;
+        if (str_len == i)
+        {
+          if (! allow_wsp_empty)
+            return MHD_PARSE_COOKIE_MALFORMED;
+          non_strict = true;
+        }
+      }
     }
   }
   return non_strict? MHD_PARSE_COOKIE_OK_LAX : MHD_PARSE_COOKIE_OK;
@@ -3141,8 +3046,10 @@ parse_cookie_header (struct MHD_Connection *connection)
   const char *hdr;
   size_t hdr_len;
   char *cpy;
-  bool strict_parsing;
   size_t i;
+  enum _MHD_ParseCookie parse_res;
+  const struct MHD_HTTP_Req_Header *const saved_tail =
+    connection->rq.headers_received_tail;
 
   if (MHD_NO ==
       MHD_lookup_connection_value_n (connection,
@@ -3159,25 +3066,61 @@ parse_cookie_header (struct MHD_Connection *connection)
   cpy = MHD_connection_alloc_memory_ (connection,
                                       hdr_len + 1);
   if (NULL == cpy)
-    return MHD_PARSE_COOKIE_NO_MEMORY;
-
-  memcpy (cpy,
-          hdr,
-          hdr_len);
-  cpy[hdr_len] = '\0';
+    parse_res = MHD_PARSE_COOKIE_NO_MEMORY;
+  else
+  {
+    memcpy (cpy,
+            hdr,
+            hdr_len);
+    cpy[hdr_len] = '\0';
+
+    i = 0;
+    /* Skip all initial whitespaces */
+    while (i < hdr_len && (' ' == cpy[i] || '\t' == cpy[i]))
+      i++;
 
-  /* TODO: add individual configuration */
-  strict_parsing = (0 < connection->daemon->strict_for_client);
-  i = 0;
-  /* Skip all initial whitespaces */
-  while (i < hdr_len && (' ' == cpy[i] || '\t' == cpy[i]))
-    i++;
+    parse_res = parse_cookies_string (cpy + i, hdr_len - i, connection);
+  }
 
-  /* 'i' points to the first non-whitespace char or to the end of the string */
-  if (strict_parsing)
-    return parse_cookies_string_strict (cpy + i, hdr_len - i, connection);
+  switch (parse_res)
+  {
+  case MHD_PARSE_COOKIE_OK:
+    break;
+  case MHD_PARSE_COOKIE_OK_LAX:
+#ifdef HAVE_MESSAGES
+    if (saved_tail != connection->rq.headers_received_tail)
+      MHD_DLOG (connection->daemon,
+                _ ("The Cookie header has been parsed, but it is not fully "
+                   "compliant with the standard.\n"));
+#endif /* HAVE_MESSAGES */
+    break;
+  case MHD_PARSE_COOKIE_MALFORMED:
+#ifdef HAVE_MESSAGES
+    if (saved_tail != connection->rq.headers_received_tail)
+      MHD_DLOG (connection->daemon,
+                _ ("The Cookie header has been only partially parsed as it "
+                   "contains malformed data.\n"));
+    else
+      MHD_DLOG (connection->daemon,
+                _ ("The Cookie header has malformed data.\n"));
+#endif /* HAVE_MESSAGES */
+    break;
+  case MHD_PARSE_COOKIE_NO_MEMORY:
+#ifdef HAVE_MESSAGES
+    MHD_DLOG (connection->daemon,
+              _ ("Not enough memory in the connection pool to "
+                 "parse client cookies!\n"));
+#endif /* HAVE_MESSAGES */
+    break;
+  default:
+    mhd_assert (0);
+    break;
+  }
+#ifndef HAVE_MESSAGES
+  (void) saved_tail; /* Mute compiler warning */
+#endif /* ! HAVE_MESSAGES */
 
-  return parse_cookies_string_lenient (cpy + i, hdr_len - i, connection);
+  return parse_res;
 }
 
 
@@ -3946,37 +3889,13 @@ parse_connection_headers (struct MHD_Connection 
*connection)
   size_t val_len;
 
 #ifdef COOKIE_SUPPORT
-  enum _MHD_ParseCookie cookie_res;
-
-  cookie_res = parse_cookie_header (connection);
-  if (MHD_PARSE_COOKIE_NO_MEMORY == cookie_res)
+  if (MHD_PARSE_COOKIE_NO_MEMORY == parse_cookie_header (connection))
   {
-#ifdef HAVE_MESSAGES
-    MHD_DLOG (connection->daemon,
-              _ ("Not enough memory in pool to parse cookies!\n"));
-#endif
     transmit_error_response_static (connection,
                                     MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
                                     REQUEST_TOO_BIG);
     return;
   }
-  else if (MHD_PARSE_COOKIE_OK_LAX == cookie_res)
-  {
-#ifdef HAVE_MESSAGES
-    MHD_DLOG (connection->daemon,
-              _ ("The Cookie header has been parsed, but is not fully "
-                 "compliant with the standard.\n"));
-#endif
-    (void) 0; /* Mute compiler warning */
-  }
-  else if (MHD_PARSE_COOKIE_MALFORMED == cookie_res)
-  {
-#ifdef HAVE_MESSAGES
-    MHD_DLOG (connection->daemon,
-              _ ("The Cookie header has malformed data.\n"));
-#endif
-    (void) 0; /* Mute compiler warning */
-  }
 #endif /* COOKIE_SUPPORT */
   if ( (1 <= connection->daemon->strict_for_client) &&
        (MHD_IS_HTTP_VER_1_1_COMPAT (connection->rq.http_ver)) &&
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 010ec2ef..0d190f9d 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -144,8 +144,9 @@ check_PROGRAMS = \
 
 if ENABLE_COOKIE
 check_PROGRAMS += \
-  test_parse_cookies \
-  test_parse_cookies_nonstrict
+  test_parse_cookies_strict_p1 \
+  test_parse_cookies_strict_zero \
+  test_parse_cookies_strict_n1
 endif
 
 if HEAVY_TESTS
@@ -467,11 +468,14 @@ test_post_SOURCES = \
 test_process_headers_SOURCES = \
   test_process_headers.c mhd_has_in_name.h
 
-test_parse_cookies_SOURCES = \
+test_parse_cookies_strict_zero_SOURCES = \
   test_parse_cookies.c mhd_has_in_name.h mhd_has_param.h
 
-test_parse_cookies_nonstrict_SOURCES = \
-  $(test_parse_cookies_SOURCES)
+test_parse_cookies_strict_p1_SOURCES = \
+  $(test_parse_cookies_strict_zero_SOURCES)
+
+test_parse_cookies_strict_n1_SOURCES = \
+  $(test_parse_cookies_strict_zero_SOURCES)
 
 test_process_arguments_SOURCES = \
   test_process_arguments.c mhd_has_in_name.h
diff --git a/src/testcurl/test_parse_cookies.c 
b/src/testcurl/test_parse_cookies.c
index 987ddbf4..308b751e 100644
--- a/src/testcurl/test_parse_cookies.c
+++ b/src/testcurl/test_parse_cookies.c
@@ -189,7 +189,7 @@ _mhdErrorExit_func (const char *errDesc, const char 
*funcName, int lineNum)
 
 
 /* Could be increased to facilitate debugging */
-#define TIMEOUTS_VAL 5
+#define TIMEOUTS_VAL 500000
 
 #define EXPECTED_URI_BASE_PATH  "/"
 
@@ -203,6 +203,9 @@ _mhdErrorExit_func (const char *errDesc, const char 
*funcName, int lineNum)
   "<html><head><title>libmicrohttpd test page</title></head>" \
   "<body>Success!</body></html>"
 
+#define PAGE_ERROR \
+  "<html><body>Cookies parsing error</body></html>"
+
 
 #ifndef MHD_STATICSTR_LEN_
 /**
@@ -234,19 +237,293 @@ struct strct_test_data
 {
   unsigned int line_num;
   const char *header_str;
-  unsigned int num_cookies_non_strict;
-  unsigned int num_cookies_strict;
+  unsigned int num_cookies_strict_p2; /* Reserved */
+  unsigned int num_cookies_strict_p1;
+  unsigned int num_cookies_strict_zero;
+  unsigned int num_cookies_strict_n1;
   struct strct_cookie cookies[5];
 };
 
 static const struct strct_test_data test_data[] = {
+  {
+    __LINE__,
+    "name1=value1",
+    1,
+    1,
+    1,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1;",
+    1,
+    1,
+    1,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1; ",
+    0,
+    1,
+    1,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "; name1=value1",
+    0,
+    0,
+    1,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    ";name1=value1",
+    0,
+    0,
+    1,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1 ",
+    1,
+    1,
+    1,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1 ;",
+    0,
+    0,
+    1,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1 ; ",
+    0,
+    0,
+    1,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name2=\"value 2\"",
+    0,
+    0,
+    1,
+    1,
+    {
+      COOKIE_ ("name2", "value 2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1;\tname2=value2",
+    0,
+    1,
+    2,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1; name1=value1",
+    2,
+    2,
+    2,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1; name2=value2",
+    2,
+    2,
+    2,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1; name2=value2",
+    2,
+    2,
+    2,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1; name2=value2",
+    2,
+    2,
+    2,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1; name2=value2",
+    2,
+    2,
+    2,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1; name2=value2",
+    2,
+    2,
+    2,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1; name2=value2",
+    2,
+    2,
+    2,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1; name2=value2",
+    2,
+    2,
+    2,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
   {
     __LINE__,
     "name1=var1; name2=var2; name3=; " \
     "name4=\"var4 with spaces\"; " \
     "name5=var_with_=_char",
-    5,
     0,
+    3,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
@@ -260,8 +537,10 @@ static const struct strct_test_data test_data[] = {
     "name1=var1;name2=var2;name3=;" \
     "name4=\"var4 with spaces\";" \
     "name5=var_with_=_char",
-    5,
     0,
+    1,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
@@ -275,8 +554,10 @@ static const struct strct_test_data test_data[] = {
     "name1=var1;  name2=var2;  name3=;  " \
     "name4=\"var4 with spaces\";  " \
     "name5=var_with_=_char\t \t",
-    5,
     0,
+    1,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
@@ -290,8 +571,10 @@ static const struct strct_test_data test_data[] = {
     "name1=var1;;name2=var2;;name3=;;" \
     "name4=\"var4 with spaces\";;" \
     "name5=var_with_=_char;\t \t",
-    5,
     0,
+    1,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
@@ -305,14 +588,16 @@ static const struct strct_test_data test_data[] = {
     "name3=; name1=var1; name2=var2; " \
     "name5=var_with_=_char;" \
     "name4=\"var4 with spaces\"",
-    5,
     0,
+    4,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
       COOKIE_ ("name3", ""),
-      COOKIE_ ("name4", "var4 with spaces"),
-      COOKIE_ ("name5", "var_with_=_char")
+      COOKIE_ ("name5", "var_with_=_char"),
+      COOKIE_ ("name4", "var4 with spaces")
     }
   },
   {
@@ -320,14 +605,16 @@ static const struct strct_test_data test_data[] = {
     "name2=var2; name1=var1; " \
     "name5=var_with_=_char; name3=; " \
     "name4=\"var4 with spaces\";",
-    5,
     0,
+    4,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
       COOKIE_ ("name3", ""),
-      COOKIE_ ("name4", "var4 with spaces"),
-      COOKIE_ ("name5", "var_with_=_char")
+      COOKIE_ ("name5", "var_with_=_char"),
+      COOKIE_ ("name4", "var4 with spaces")
     }
   },
   {
@@ -335,14 +622,16 @@ static const struct strct_test_data test_data[] = {
     "name2=var2; name1=var1; " \
     "name5=var_with_=_char; " \
     "name4=\"var4 with spaces\"; name3=",
-    5,
     0,
+    3,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
+      COOKIE_ ("name5", "var_with_=_char"),
       COOKIE_ ("name3", ""),
-      COOKIE_ ("name4", "var4 with spaces"),
-      COOKIE_ ("name5", "var_with_=_char")
+      COOKIE_ ("name4", "var4 with spaces")
     }
   },
   {
@@ -350,8 +639,10 @@ static const struct strct_test_data test_data[] = {
     "name2=var2; name1=var1; " \
     "name4=\"var4 with spaces\"; " \
     "name5=var_with_=_char; name3=;",
-    5,
     0,
+    2,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
@@ -365,8 +656,10 @@ static const struct strct_test_data test_data[] = {
     ";;;;;;;;name1=var1; name2=var2; name3=; " \
     "name4=\"var4 with spaces\"; " \
     "name5=var_with_=_char",
-    5,
     0,
+    0,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
@@ -380,8 +673,10 @@ static const struct strct_test_data test_data[] = {
     "name1=var1; name2=var2; name3=; " \
     "name4=\"var4 with spaces\"; ; ; ; ; " \
     "name5=var_with_=_char",
-    5,
     0,
+    3,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
@@ -395,8 +690,10 @@ static const struct strct_test_data test_data[] = {
     "name1=var1; name2=var2; name3=; " \
     "name4=\"var4 with spaces\"; " \
     "name5=var_with_=_char;;;;;;;;",
-    5,
     0,
+    3,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
@@ -408,16 +705,18 @@ static const struct strct_test_data test_data[] = {
   {
     __LINE__,
     "name1=var1; name2=var2; " \
-    "name4=\"var4 with spaces\"" \
+    "name4=\"var4 with spaces\";" \
     "name5=var_with_=_char; ; ; ; ; name3=",
-    5,
     0,
+    2,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
+      COOKIE_ ("name5", "var_with_=_char"),
       COOKIE_ ("name3", ""),
-      COOKIE_ ("name4", "var4 with spaces"),
-      COOKIE_ ("name5", "var_with_=_char")
+      COOKIE_ ("name4", "var4 with spaces")
     }
   },
   {
@@ -425,8 +724,10 @@ static const struct strct_test_data test_data[] = {
     "name5=var_with_=_char ;" \
     "name1=var1; name2=var2; name3=; " \
     "name4=\"var4 with spaces\" ",
-    5,
     0,
+    0,
+    5,
+    5,
     {
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
@@ -439,14 +740,106 @@ static const struct strct_test_data test_data[] = {
     __LINE__,
     "name5=var_with_=_char; name4=\"var4 with spaces\";" \
     "name1=var1; name2=var2; name3=",
-    5,
     0,
+    1,
+    5,
+    5,
     {
+      COOKIE_ ("name5", "var_with_=_char"),
       COOKIE_ ("name1", "var1"),
       COOKIE_ ("name2", "var2"),
       COOKIE_ ("name3", ""),
-      COOKIE_ ("name4", "var4 with spaces"),
-      COOKIE_ ("name5", "var_with_=_char")
+      COOKIE_ ("name4", "var4 with spaces")
+    }
+  },
+  {
+    __LINE__,
+    "name1 = value1",
+    0,
+    0,
+    0,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1\t=\tvalue1",
+    0,
+    0,
+    0,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1\t = \tvalue1",
+    0,
+    0,
+    0,
+    1,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1 = value1; name2 =\tvalue2",
+    0,
+    0,
+    0,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1=value1; name2 =\tvalue2",
+    0,
+    1,
+    1,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
+    }
+  },
+  {
+    __LINE__,
+    "name1 = value1; name2=value2",
+    0,
+    0,
+    0,
+    2,
+    {
+      COOKIE_ ("name1", "value1"),
+      COOKIE_ ("name2", "value2"),
+      COOKIE_NULL,
+      COOKIE_NULL,
+      COOKIE_NULL
     }
   },
   {
@@ -454,6 +847,8 @@ static const struct strct_test_data test_data[] = {
     "",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -467,6 +862,8 @@ static const struct strct_test_data test_data[] = {
     "      ",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -480,6 +877,8 @@ static const struct strct_test_data test_data[] = {
     "\t",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -493,6 +892,8 @@ static const struct strct_test_data test_data[] = {
     "var=,",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -506,6 +907,8 @@ static const struct strct_test_data test_data[] = {
     "var=\"\\ \"",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -519,6 +922,8 @@ static const struct strct_test_data test_data[] = {
     "var=value  space",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -532,6 +937,8 @@ static const struct strct_test_data test_data[] = {
     "var=value\ttab",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -545,6 +952,8 @@ static const struct strct_test_data test_data[] = {
     "=",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -558,6 +967,8 @@ static const struct strct_test_data test_data[] = {
     "====",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -571,6 +982,8 @@ static const struct strct_test_data test_data[] = {
     ";=",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -584,6 +997,8 @@ static const struct strct_test_data test_data[] = {
     "var",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -597,6 +1012,8 @@ static const struct strct_test_data test_data[] = {
     "=;",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -610,6 +1027,8 @@ static const struct strct_test_data test_data[] = {
     "= ;",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -623,6 +1042,8 @@ static const struct strct_test_data test_data[] = {
     ";= ;",
     0,
     0,
+    0,
+    0,
     {
       COOKIE_NULL,
       COOKIE_NULL,
@@ -636,7 +1057,10 @@ static const struct strct_test_data test_data[] = {
 /* Global parameters */
 static int verbose;
 static int oneone;                  /**< If false use HTTP/1.0 for requests*/
-static int use_non_strict;
+static int use_strict_n1;
+static int use_strict_zero;
+static int use_strict_p1;
+static int strict_level;
 
 static void
 test_global_init (void)
@@ -700,12 +1124,19 @@ ahcCheck (void *cls,
   struct MHD_Response *response;
   enum MHD_Result ret;
   struct ahc_cls_type *const param = (struct ahc_cls_type *) cls;
-  const unsigned int expected_num_cookies =
-    use_non_strict ? param->check->num_cookies_non_strict :
-    param->check->num_cookies_strict;
+  unsigned int expected_num_cookies;
   unsigned int i;
   int cookie_failed;
 
+  if (use_strict_p1)
+    expected_num_cookies = param->check->num_cookies_strict_p1;
+  else if (use_strict_zero)
+    expected_num_cookies = param->check->num_cookies_strict_zero;
+  else if (use_strict_n1)
+    expected_num_cookies = param->check->num_cookies_strict_n1;
+  else
+    externalErrorExit ();
+
   if (NULL == param)
     mhdErrorExitDesc ("cls parameter is NULL");
 
@@ -813,7 +1244,17 @@ ahcCheck (void *cls,
     cookie_failed = 1;
   }
   if (cookie_failed)
-    return MHD_NO; /* Break connection */
+  {
+    response =
+      MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (PAGE_ERROR),
+                                              PAGE_ERROR);
+    ret = MHD_queue_response (connection,
+                              MHD_HTTP_BAD_REQUEST,
+                              response);
+    MHD_destroy_response (response);
+
+    return ret;
+  }
 
   if (&marker != *req_cls)
   {
@@ -1057,7 +1498,6 @@ check_result (CURLcode curl_code, CURL *c, long 
expected_code,
               struct CBC *pcbc)
 {
   long code;
-  unsigned int ret;
 
   if (CURLE_OK != curl_code)
   {
@@ -1079,15 +1519,15 @@ check_result (CURLcode curl_code, CURL *c, long 
expected_code,
   if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
     libcurlErrorExit ();
 
-  ret = 1;
   if (expected_code != code)
   {
-    fprintf (stderr, "The response has wrong HTTP code: %ld\tExpected: %ld.\n",
+    fprintf (stderr, "### The response has wrong HTTP code: %ld\t"
+             "Expected: %ld.\n",
              code, expected_code);
-    ret = 0;
+    return 0;
   }
   else if (verbose)
-    printf ("The response has expected HTTP code: %ld\n", expected_code);
+    printf ("### The response has expected HTTP code: %ld\n", expected_code);
 
   if (pcbc->pos != MHD_STATICSTR_LEN_ (PAGE))
   {
@@ -1105,7 +1545,7 @@ check_result (CURLcode curl_code, CURL *c, long 
expected_code,
   fflush (stderr);
   fflush (stdout);
 
-  return ret;
+  return 1;
 }
 
 
@@ -1125,13 +1565,13 @@ testExternalPolling (void)
   if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
     port = 0;
   else
-    port = 1340 + oneone ? 0 : 1 + use_non_strict ? 0 : 2;
+    port = 1340 + oneone ? 0 : 6 + (uint16_t) (1 + strict_level);
 
   d = MHD_start_daemon (MHD_USE_ERROR_LOG,
                         port, NULL, NULL,
                         &ahcCheck, &ahc_param,
                         MHD_OPTION_STRICT_FOR_CLIENT,
-                        (int) (use_non_strict ? 0 : 1),
+                        (int) (strict_level),
                         MHD_OPTION_END);
   if (d == NULL)
     return 1;
@@ -1167,13 +1607,13 @@ testExternalPolling (void)
                       MHD_HTTP_OK, &cbc))
     {
       if (verbose)
-        printf ("Got expected response for the check at line %u.\n",
+        printf ("### Got expected response for the check at line %u.\n",
                 test_data[i].line_num);
       fflush (stdout);
     }
     else
     {
-      fprintf (stderr, "FAILED request for the check at line %u.\n",
+      fprintf (stderr, "### FAILED request for the check at line %u.\n",
                test_data[i].line_num);
       fflush (stderr);
       failed = 1;
@@ -1200,7 +1640,19 @@ main (int argc, char *const *argv)
                has_param (argc, argv, "-s") ||
                has_param (argc, argv, "--silent"));
   oneone = ! has_in_name (argv[0], "10");
-  use_non_strict = has_in_name (argv[0], "_nonstrict");
+  use_strict_n1 = has_in_name (argv[0], "_strict_n1");
+  use_strict_zero = has_in_name (argv[0], "_strict_zero");
+  use_strict_p1 = has_in_name (argv[0], "_strict_p1");
+  if (1 != ((use_strict_n1 ? 1 : 0) + (use_strict_zero ? 1 : 0)
+            + (use_strict_p1 ? 1 : 0)))
+    return 99;
+
+  if (use_strict_n1)
+    strict_level = -1;
+  else if (use_strict_zero)
+    strict_level = 0;
+  else if (use_strict_p1)
+    strict_level = 1;
 
   test_global_init ();
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]