diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-12-06 23:40:21 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-12-19 18:13:44 +0300 |
commit | 1e7ad3010da7d2be1afe219da0ba84dd129f9c4e (patch) | |
tree | 3c44eee03a349aac2c862ed666bbfcb2497e3221 | |
parent | 38b46a2fd1cf24270e6deab2bb64c381938b95a9 (diff) | |
download | libmicrohttpd-1e7ad3010da7d2be1afe219da0ba84dd129f9c4e.tar.gz libmicrohttpd-1e7ad3010da7d2be1afe219da0ba84dd129f9c4e.zip |
Refactored cookies parsing.
The new code is more compact as duplicated code was removed.
Added testing for various cookies parsing strictness levels.
-rw-r--r-- | src/microhttpd/connection.c | 299 | ||||
-rw-r--r-- | src/testcurl/Makefile.am | 14 | ||||
-rw-r--r-- | 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 | |||
@@ -2829,146 +2829,6 @@ enum _MHD_ParseCookie | |||
2829 | /** | 2829 | /** |
2830 | * Parse the cookies string (see RFC 6265). | 2830 | * Parse the cookies string (see RFC 6265). |
2831 | * | 2831 | * |
2832 | * Parsing may fail if the string is not formed strictly as defined by RFC 6265. | ||
2833 | * | ||
2834 | * @param str the string to parse, without leading whitespaces | ||
2835 | * @param str_len the size of the @a str, not including mandatory | ||
2836 | * zero-termination | ||
2837 | * @param connection the connection to add parsed cookies | ||
2838 | * @return #MHD_PARSE_COOKIE_OK for success, error code otherwise | ||
2839 | */ | ||
2840 | static enum _MHD_ParseCookie | ||
2841 | parse_cookies_string_strict (char *str, | ||
2842 | size_t str_len, | ||
2843 | struct MHD_Connection *connection) | ||
2844 | { | ||
2845 | size_t i; | ||
2846 | |||
2847 | i = 0; | ||
2848 | while (i < str_len) | ||
2849 | { | ||
2850 | size_t name_start; | ||
2851 | size_t name_len; | ||
2852 | size_t value_start; | ||
2853 | size_t value_len; | ||
2854 | bool val_quoted; | ||
2855 | /* 'i' must point to the first char of cookie-name */ | ||
2856 | name_start = i; | ||
2857 | /* Find the end of the cookie-name */ | ||
2858 | do | ||
2859 | { | ||
2860 | const char l = str[i]; | ||
2861 | if (('=' == l) || (' ' == l) || ('\t' == l) || ('"' == l) || (',' == l) || | ||
2862 | (';' == l) || (0 == l)) | ||
2863 | break; | ||
2864 | } while (str_len > ++i); | ||
2865 | if ((str_len == i) || ('=' != str[i]) || (name_start == i)) | ||
2866 | return MHD_PARSE_COOKIE_MALFORMED; /* Incomplete cookie name */ | ||
2867 | name_len = i - name_start; | ||
2868 | /* 'i' must point to the '=' char */ | ||
2869 | mhd_assert ('=' == str[i]); | ||
2870 | i++; | ||
2871 | /* 'i' must point to the first char of cookie-value */ | ||
2872 | if (str_len == i) | ||
2873 | { | ||
2874 | value_start = 0; | ||
2875 | value_len = 0; | ||
2876 | #ifdef _DEBUG | ||
2877 | val_quoted = false; /* This assignment used in assert */ | ||
2878 | #endif | ||
2879 | } | ||
2880 | else | ||
2881 | { | ||
2882 | bool valid_cookie; | ||
2883 | val_quoted = ('"' == str[i]); | ||
2884 | if (val_quoted) | ||
2885 | i++; | ||
2886 | value_start = i; | ||
2887 | /* Find the end of the cookie-value */ | ||
2888 | while (str_len > i) | ||
2889 | { | ||
2890 | const char l = str[i]; | ||
2891 | if ((';' == l) || ('"' == l) || (' ' == l) || ('\t' == l) | ||
2892 | || (',' == l) || ('\\' == l) || (0 == l)) | ||
2893 | break; | ||
2894 | i++; | ||
2895 | } | ||
2896 | value_len = i - value_start; | ||
2897 | if (val_quoted) | ||
2898 | { | ||
2899 | if ((str_len == i) || ('"' != str[i])) | ||
2900 | return MHD_PARSE_COOKIE_MALFORMED; /* Incomplete cookie value, no closing quote */ | ||
2901 | i++; | ||
2902 | } | ||
2903 | if (str_len == i) | ||
2904 | valid_cookie = true; | ||
2905 | else if (';' == str[i]) | ||
2906 | valid_cookie = true; | ||
2907 | else if ((' ' == str[i]) || ('\t' == str[i])) | ||
2908 | { /* Optional whitespace at the end of the string? */ | ||
2909 | while (str_len > ++i) | ||
2910 | { | ||
2911 | if ((' ' != str[i]) && ('\t' != str[i])) | ||
2912 | break; | ||
2913 | } | ||
2914 | if (str_len == i) | ||
2915 | valid_cookie = true; | ||
2916 | else | ||
2917 | valid_cookie = false; | ||
2918 | } | ||
2919 | else | ||
2920 | valid_cookie = false; | ||
2921 | |||
2922 | if (! valid_cookie) | ||
2923 | return MHD_PARSE_COOKIE_MALFORMED; /* Garbage at the end of the cookie value */ | ||
2924 | } | ||
2925 | mhd_assert (0 != name_len); | ||
2926 | str[name_start + name_len] = 0; /* Zero-terminate the name */ | ||
2927 | if (0 != value_len) | ||
2928 | { | ||
2929 | mhd_assert (0 == str[i] || ';' == str[i]); | ||
2930 | mhd_assert (! val_quoted || ';' == str[i]); | ||
2931 | str[value_start + value_len] = 0; /* Zero-terminate the value */ | ||
2932 | if (MHD_NO == | ||
2933 | MHD_set_connection_value_n_nocheck_ (connection, | ||
2934 | MHD_COOKIE_KIND, | ||
2935 | str + name_start, | ||
2936 | name_len, | ||
2937 | str + value_start, | ||
2938 | value_len)) | ||
2939 | return MHD_PARSE_COOKIE_NO_MEMORY; | ||
2940 | } | ||
2941 | else | ||
2942 | { | ||
2943 | if (MHD_NO == | ||
2944 | MHD_set_connection_value_n_nocheck_ (connection, | ||
2945 | MHD_COOKIE_KIND, | ||
2946 | str + name_start, | ||
2947 | name_len, | ||
2948 | "", | ||
2949 | 0)) | ||
2950 | return MHD_PARSE_COOKIE_NO_MEMORY; | ||
2951 | } | ||
2952 | if (str_len > i) | ||
2953 | { | ||
2954 | mhd_assert (0 == str[i] || ';' == str[i]); | ||
2955 | mhd_assert (! val_quoted || ';' == str[i]); | ||
2956 | mhd_assert (';' != str[i] || val_quoted || 0 == value_len); | ||
2957 | i++; | ||
2958 | if (str_len == i) | ||
2959 | return MHD_PARSE_COOKIE_MALFORMED; /* No cookie name after semicolon */ | ||
2960 | if (' ' != str[i]) | ||
2961 | return MHD_PARSE_COOKIE_MALFORMED; /* No space after semicolon */ | ||
2962 | i++; | ||
2963 | } | ||
2964 | } | ||
2965 | return MHD_PARSE_COOKIE_OK; | ||
2966 | } | ||
2967 | |||
2968 | |||
2969 | /** | ||
2970 | * Parse the cookies string (see RFC 6265). | ||
2971 | * | ||
2972 | * Try to parse the cookies string even if it is not strictly formed | 2832 | * Try to parse the cookies string even if it is not strictly formed |
2973 | * as specified by RFC 6265. | 2833 | * as specified by RFC 6265. |
2974 | * | 2834 | * |
@@ -2979,12 +2839,22 @@ parse_cookies_string_strict (char *str, | |||
2979 | * @return #MHD_PARSE_COOKIE_OK for success, error code otherwise | 2839 | * @return #MHD_PARSE_COOKIE_OK for success, error code otherwise |
2980 | */ | 2840 | */ |
2981 | static enum _MHD_ParseCookie | 2841 | static enum _MHD_ParseCookie |
2982 | parse_cookies_string_lenient (char *str, | 2842 | parse_cookies_string (char *str, |
2983 | size_t str_len, | 2843 | const size_t str_len, |
2984 | struct MHD_Connection *connection) | 2844 | struct MHD_Connection *connection) |
2985 | { | 2845 | { |
2986 | size_t i; | 2846 | size_t i; |
2987 | bool non_strict; | 2847 | bool non_strict; |
2848 | /* Skip extra whitespaces and empty cookies */ | ||
2849 | const bool allow_wsp_empty = (0 >= connection->daemon->strict_for_client); | ||
2850 | /* Allow whitespaces around '=' character */ | ||
2851 | const bool wsp_around_eq = (0 > connection->daemon->strict_for_client); | ||
2852 | /* Allow whitespaces in quoted cookie value */ | ||
2853 | const bool wsp_in_quoted = (0 >= connection->daemon->strict_for_client); | ||
2854 | /* Allow tab as space after semicolon between cookies */ | ||
2855 | const bool tab_as_sp = (0 >= connection->daemon->strict_for_client); | ||
2856 | /* Allow no space after semicolon between cookies */ | ||
2857 | const bool allow_no_space = (0 >= connection->daemon->strict_for_client); | ||
2988 | 2858 | ||
2989 | non_strict = false; | 2859 | non_strict = false; |
2990 | i = 0; | 2860 | i = 0; |
@@ -2998,6 +2868,8 @@ parse_cookies_string_lenient (char *str, | |||
2998 | /* Skip any whitespaces and empty cookies */ | 2868 | /* Skip any whitespaces and empty cookies */ |
2999 | while (' ' == str[i] || '\t' == str[i] || ';' == str[i]) | 2869 | while (' ' == str[i] || '\t' == str[i] || ';' == str[i]) |
3000 | { | 2870 | { |
2871 | if (! allow_wsp_empty) | ||
2872 | return MHD_PARSE_COOKIE_MALFORMED; | ||
3001 | non_strict = true; | 2873 | non_strict = true; |
3002 | i++; | 2874 | i++; |
3003 | if (i == str_len) | 2875 | if (i == str_len) |
@@ -3017,6 +2889,8 @@ parse_cookies_string_lenient (char *str, | |||
3017 | /* Skip any whitespaces */ | 2889 | /* Skip any whitespaces */ |
3018 | while (str_len > i && (' ' == str[i] || '\t' == str[i])) | 2890 | while (str_len > i && (' ' == str[i] || '\t' == str[i])) |
3019 | { | 2891 | { |
2892 | if (! wsp_around_eq) | ||
2893 | return MHD_PARSE_COOKIE_MALFORMED; | ||
3020 | non_strict = true; | 2894 | non_strict = true; |
3021 | i++; | 2895 | i++; |
3022 | } | 2896 | } |
@@ -3028,6 +2902,8 @@ parse_cookies_string_lenient (char *str, | |||
3028 | /* Skip any whitespaces */ | 2902 | /* Skip any whitespaces */ |
3029 | while (str_len > i && (' ' == str[i] || '\t' == str[i])) | 2903 | while (str_len > i && (' ' == str[i] || '\t' == str[i])) |
3030 | { | 2904 | { |
2905 | if (! wsp_around_eq) | ||
2906 | return MHD_PARSE_COOKIE_MALFORMED; | ||
3031 | non_strict = true; | 2907 | non_strict = true; |
3032 | i++; | 2908 | i++; |
3033 | } | 2909 | } |
@@ -3058,6 +2934,8 @@ parse_cookies_string_lenient (char *str, | |||
3058 | { | 2934 | { |
3059 | if (! val_quoted) | 2935 | if (! val_quoted) |
3060 | break; | 2936 | break; |
2937 | if (! wsp_in_quoted) | ||
2938 | return MHD_PARSE_COOKIE_MALFORMED; | ||
3061 | non_strict = true; | 2939 | non_strict = true; |
3062 | } | 2940 | } |
3063 | i++; | 2941 | i++; |
@@ -3070,10 +2948,19 @@ parse_cookies_string_lenient (char *str, | |||
3070 | i++; | 2948 | i++; |
3071 | } | 2949 | } |
3072 | /* Skip any whitespaces */ | 2950 | /* Skip any whitespaces */ |
3073 | while (str_len > i && (' ' == str[i] || '\t' == str[i])) | 2951 | if ((str_len > i) && ((' ' == str[i]) || ('\t' == str[i]))) |
3074 | { | 2952 | { |
3075 | non_strict = true; | 2953 | do |
3076 | i++; | 2954 | { |
2955 | i++; | ||
2956 | } while (str_len > i && (' ' == str[i] || '\t' == str[i])); | ||
2957 | /* Whitespace at the end? */ | ||
2958 | if (str_len > i) | ||
2959 | { | ||
2960 | if (! allow_wsp_empty) | ||
2961 | return MHD_PARSE_COOKIE_MALFORMED; | ||
2962 | non_strict = true; | ||
2963 | } | ||
3077 | } | 2964 | } |
3078 | if (str_len == i) | 2965 | if (str_len == i) |
3079 | valid_cookie = true; | 2966 | valid_cookie = true; |
@@ -3118,11 +3005,29 @@ parse_cookies_string_lenient (char *str, | |||
3118 | mhd_assert (';' != str[i] || val_quoted || non_strict || 0 == value_len); | 3005 | mhd_assert (';' != str[i] || val_quoted || non_strict || 0 == value_len); |
3119 | i++; | 3006 | i++; |
3120 | if (str_len == i) | 3007 | if (str_len == i) |
3121 | non_strict = true; /* No cookie name after semicolon */ | 3008 | { /* No next cookie after semicolon */ |
3009 | if (! allow_wsp_empty) | ||
3010 | return MHD_PARSE_COOKIE_MALFORMED; | ||
3011 | non_strict = true; | ||
3012 | } | ||
3122 | else if (' ' != str[i]) | 3013 | else if (' ' != str[i]) |
3123 | non_strict = true; /* No space after semicolon */ | 3014 | {/* No space after semicolon */ |
3015 | if (('\t' == str[i]) && tab_as_sp) | ||
3016 | i++; | ||
3017 | else if (! allow_no_space) | ||
3018 | return MHD_PARSE_COOKIE_MALFORMED; | ||
3019 | non_strict = true; | ||
3020 | } | ||
3124 | else | 3021 | else |
3022 | { | ||
3125 | i++; | 3023 | i++; |
3024 | if (str_len == i) | ||
3025 | { | ||
3026 | if (! allow_wsp_empty) | ||
3027 | return MHD_PARSE_COOKIE_MALFORMED; | ||
3028 | non_strict = true; | ||
3029 | } | ||
3030 | } | ||
3126 | } | 3031 | } |
3127 | } | 3032 | } |
3128 | return non_strict? MHD_PARSE_COOKIE_OK_LAX : MHD_PARSE_COOKIE_OK; | 3033 | return non_strict? MHD_PARSE_COOKIE_OK_LAX : MHD_PARSE_COOKIE_OK; |
@@ -3141,8 +3046,10 @@ parse_cookie_header (struct MHD_Connection *connection) | |||
3141 | const char *hdr; | 3046 | const char *hdr; |
3142 | size_t hdr_len; | 3047 | size_t hdr_len; |
3143 | char *cpy; | 3048 | char *cpy; |
3144 | bool strict_parsing; | ||
3145 | size_t i; | 3049 | size_t i; |
3050 | enum _MHD_ParseCookie parse_res; | ||
3051 | const struct MHD_HTTP_Req_Header *const saved_tail = | ||
3052 | connection->rq.headers_received_tail; | ||
3146 | 3053 | ||
3147 | if (MHD_NO == | 3054 | if (MHD_NO == |
3148 | MHD_lookup_connection_value_n (connection, | 3055 | MHD_lookup_connection_value_n (connection, |
@@ -3159,25 +3066,61 @@ parse_cookie_header (struct MHD_Connection *connection) | |||
3159 | cpy = MHD_connection_alloc_memory_ (connection, | 3066 | cpy = MHD_connection_alloc_memory_ (connection, |
3160 | hdr_len + 1); | 3067 | hdr_len + 1); |
3161 | if (NULL == cpy) | 3068 | if (NULL == cpy) |
3162 | return MHD_PARSE_COOKIE_NO_MEMORY; | 3069 | parse_res = MHD_PARSE_COOKIE_NO_MEMORY; |
3163 | 3070 | else | |
3164 | memcpy (cpy, | 3071 | { |
3165 | hdr, | 3072 | memcpy (cpy, |
3166 | hdr_len); | 3073 | hdr, |
3167 | cpy[hdr_len] = '\0'; | 3074 | hdr_len); |
3075 | cpy[hdr_len] = '\0'; | ||
3076 | |||
3077 | i = 0; | ||
3078 | /* Skip all initial whitespaces */ | ||
3079 | while (i < hdr_len && (' ' == cpy[i] || '\t' == cpy[i])) | ||
3080 | i++; | ||
3168 | 3081 | ||
3169 | /* TODO: add individual configuration */ | 3082 | parse_res = parse_cookies_string (cpy + i, hdr_len - i, connection); |
3170 | strict_parsing = (0 < connection->daemon->strict_for_client); | 3083 | } |
3171 | i = 0; | ||
3172 | /* Skip all initial whitespaces */ | ||
3173 | while (i < hdr_len && (' ' == cpy[i] || '\t' == cpy[i])) | ||
3174 | i++; | ||
3175 | 3084 | ||
3176 | /* 'i' points to the first non-whitespace char or to the end of the string */ | 3085 | switch (parse_res) |
3177 | if (strict_parsing) | 3086 | { |
3178 | return parse_cookies_string_strict (cpy + i, hdr_len - i, connection); | 3087 | case MHD_PARSE_COOKIE_OK: |
3088 | break; | ||
3089 | case MHD_PARSE_COOKIE_OK_LAX: | ||
3090 | #ifdef HAVE_MESSAGES | ||
3091 | if (saved_tail != connection->rq.headers_received_tail) | ||
3092 | MHD_DLOG (connection->daemon, | ||
3093 | _ ("The Cookie header has been parsed, but it is not fully " | ||
3094 | "compliant with the standard.\n")); | ||
3095 | #endif /* HAVE_MESSAGES */ | ||
3096 | break; | ||
3097 | case MHD_PARSE_COOKIE_MALFORMED: | ||
3098 | #ifdef HAVE_MESSAGES | ||
3099 | if (saved_tail != connection->rq.headers_received_tail) | ||
3100 | MHD_DLOG (connection->daemon, | ||
3101 | _ ("The Cookie header has been only partially parsed as it " | ||
3102 | "contains malformed data.\n")); | ||
3103 | else | ||
3104 | MHD_DLOG (connection->daemon, | ||
3105 | _ ("The Cookie header has malformed data.\n")); | ||
3106 | #endif /* HAVE_MESSAGES */ | ||
3107 | break; | ||
3108 | case MHD_PARSE_COOKIE_NO_MEMORY: | ||
3109 | #ifdef HAVE_MESSAGES | ||
3110 | MHD_DLOG (connection->daemon, | ||
3111 | _ ("Not enough memory in the connection pool to " | ||
3112 | "parse client cookies!\n")); | ||
3113 | #endif /* HAVE_MESSAGES */ | ||
3114 | break; | ||
3115 | default: | ||
3116 | mhd_assert (0); | ||
3117 | break; | ||
3118 | } | ||
3119 | #ifndef HAVE_MESSAGES | ||
3120 | (void) saved_tail; /* Mute compiler warning */ | ||
3121 | #endif /* ! HAVE_MESSAGES */ | ||
3179 | 3122 | ||
3180 | return parse_cookies_string_lenient (cpy + i, hdr_len - i, connection); | 3123 | return parse_res; |
3181 | } | 3124 | } |
3182 | 3125 | ||
3183 | 3126 | ||
@@ -3946,37 +3889,13 @@ parse_connection_headers (struct MHD_Connection *connection) | |||
3946 | size_t val_len; | 3889 | size_t val_len; |
3947 | 3890 | ||
3948 | #ifdef COOKIE_SUPPORT | 3891 | #ifdef COOKIE_SUPPORT |
3949 | enum _MHD_ParseCookie cookie_res; | 3892 | if (MHD_PARSE_COOKIE_NO_MEMORY == parse_cookie_header (connection)) |
3950 | |||
3951 | cookie_res = parse_cookie_header (connection); | ||
3952 | if (MHD_PARSE_COOKIE_NO_MEMORY == cookie_res) | ||
3953 | { | 3893 | { |
3954 | #ifdef HAVE_MESSAGES | ||
3955 | MHD_DLOG (connection->daemon, | ||
3956 | _ ("Not enough memory in pool to parse cookies!\n")); | ||
3957 | #endif | ||
3958 | transmit_error_response_static (connection, | 3894 | transmit_error_response_static (connection, |
3959 | MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, | 3895 | MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, |
3960 | REQUEST_TOO_BIG); | 3896 | REQUEST_TOO_BIG); |
3961 | return; | 3897 | return; |
3962 | } | 3898 | } |
3963 | else if (MHD_PARSE_COOKIE_OK_LAX == cookie_res) | ||
3964 | { | ||
3965 | #ifdef HAVE_MESSAGES | ||
3966 | MHD_DLOG (connection->daemon, | ||
3967 | _ ("The Cookie header has been parsed, but is not fully " | ||
3968 | "compliant with the standard.\n")); | ||
3969 | #endif | ||
3970 | (void) 0; /* Mute compiler warning */ | ||
3971 | } | ||
3972 | else if (MHD_PARSE_COOKIE_MALFORMED == cookie_res) | ||
3973 | { | ||
3974 | #ifdef HAVE_MESSAGES | ||
3975 | MHD_DLOG (connection->daemon, | ||
3976 | _ ("The Cookie header has malformed data.\n")); | ||
3977 | #endif | ||
3978 | (void) 0; /* Mute compiler warning */ | ||
3979 | } | ||
3980 | #endif /* COOKIE_SUPPORT */ | 3899 | #endif /* COOKIE_SUPPORT */ |
3981 | if ( (1 <= connection->daemon->strict_for_client) && | 3900 | if ( (1 <= connection->daemon->strict_for_client) && |
3982 | (MHD_IS_HTTP_VER_1_1_COMPAT (connection->rq.http_ver)) && | 3901 | (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 = \ | |||
144 | 144 | ||
145 | if ENABLE_COOKIE | 145 | if ENABLE_COOKIE |
146 | check_PROGRAMS += \ | 146 | check_PROGRAMS += \ |
147 | test_parse_cookies \ | 147 | test_parse_cookies_strict_p1 \ |
148 | test_parse_cookies_nonstrict | 148 | test_parse_cookies_strict_zero \ |
149 | test_parse_cookies_strict_n1 | ||
149 | endif | 150 | endif |
150 | 151 | ||
151 | if HEAVY_TESTS | 152 | if HEAVY_TESTS |
@@ -467,11 +468,14 @@ test_post_SOURCES = \ | |||
467 | test_process_headers_SOURCES = \ | 468 | test_process_headers_SOURCES = \ |
468 | test_process_headers.c mhd_has_in_name.h | 469 | test_process_headers.c mhd_has_in_name.h |
469 | 470 | ||
470 | test_parse_cookies_SOURCES = \ | 471 | test_parse_cookies_strict_zero_SOURCES = \ |
471 | test_parse_cookies.c mhd_has_in_name.h mhd_has_param.h | 472 | test_parse_cookies.c mhd_has_in_name.h mhd_has_param.h |
472 | 473 | ||
473 | test_parse_cookies_nonstrict_SOURCES = \ | 474 | test_parse_cookies_strict_p1_SOURCES = \ |
474 | $(test_parse_cookies_SOURCES) | 475 | $(test_parse_cookies_strict_zero_SOURCES) |
476 | |||
477 | test_parse_cookies_strict_n1_SOURCES = \ | ||
478 | $(test_parse_cookies_strict_zero_SOURCES) | ||
475 | 479 | ||
476 | test_process_arguments_SOURCES = \ | 480 | test_process_arguments_SOURCES = \ |
477 | test_process_arguments.c mhd_has_in_name.h | 481 | 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) | |||
189 | 189 | ||
190 | 190 | ||
191 | /* Could be increased to facilitate debugging */ | 191 | /* Could be increased to facilitate debugging */ |
192 | #define TIMEOUTS_VAL 5 | 192 | #define TIMEOUTS_VAL 500000 |
193 | 193 | ||
194 | #define EXPECTED_URI_BASE_PATH "/" | 194 | #define EXPECTED_URI_BASE_PATH "/" |
195 | 195 | ||
@@ -203,6 +203,9 @@ _mhdErrorExit_func (const char *errDesc, const char *funcName, int lineNum) | |||
203 | "<html><head><title>libmicrohttpd test page</title></head>" \ | 203 | "<html><head><title>libmicrohttpd test page</title></head>" \ |
204 | "<body>Success!</body></html>" | 204 | "<body>Success!</body></html>" |
205 | 205 | ||
206 | #define PAGE_ERROR \ | ||
207 | "<html><body>Cookies parsing error</body></html>" | ||
208 | |||
206 | 209 | ||
207 | #ifndef MHD_STATICSTR_LEN_ | 210 | #ifndef MHD_STATICSTR_LEN_ |
208 | /** | 211 | /** |
@@ -234,19 +237,293 @@ struct strct_test_data | |||
234 | { | 237 | { |
235 | unsigned int line_num; | 238 | unsigned int line_num; |
236 | const char *header_str; | 239 | const char *header_str; |
237 | unsigned int num_cookies_non_strict; | 240 | unsigned int num_cookies_strict_p2; /* Reserved */ |
238 | unsigned int num_cookies_strict; | 241 | unsigned int num_cookies_strict_p1; |
242 | unsigned int num_cookies_strict_zero; | ||
243 | unsigned int num_cookies_strict_n1; | ||
239 | struct strct_cookie cookies[5]; | 244 | struct strct_cookie cookies[5]; |
240 | }; | 245 | }; |
241 | 246 | ||
242 | static const struct strct_test_data test_data[] = { | 247 | static const struct strct_test_data test_data[] = { |
243 | { | 248 | { |
244 | __LINE__, | 249 | __LINE__, |
250 | "name1=value1", | ||
251 | 1, | ||
252 | 1, | ||
253 | 1, | ||
254 | 1, | ||
255 | { | ||
256 | COOKIE_ ("name1", "value1"), | ||
257 | COOKIE_NULL, | ||
258 | COOKIE_NULL, | ||
259 | COOKIE_NULL, | ||
260 | COOKIE_NULL | ||
261 | } | ||
262 | }, | ||
263 | { | ||
264 | __LINE__, | ||
265 | "name1=value1;", | ||
266 | 1, | ||
267 | 1, | ||
268 | 1, | ||
269 | 1, | ||
270 | { | ||
271 | COOKIE_ ("name1", "value1"), | ||
272 | COOKIE_NULL, | ||
273 | COOKIE_NULL, | ||
274 | COOKIE_NULL, | ||
275 | COOKIE_NULL | ||
276 | } | ||
277 | }, | ||
278 | { | ||
279 | __LINE__, | ||
280 | "name1=value1; ", | ||
281 | 0, | ||
282 | 1, | ||
283 | 1, | ||
284 | 1, | ||
285 | { | ||
286 | COOKIE_ ("name1", "value1"), | ||
287 | COOKIE_NULL, | ||
288 | COOKIE_NULL, | ||
289 | COOKIE_NULL, | ||
290 | COOKIE_NULL | ||
291 | } | ||
292 | }, | ||
293 | { | ||
294 | __LINE__, | ||
295 | "; name1=value1", | ||
296 | 0, | ||
297 | 0, | ||
298 | 1, | ||
299 | 1, | ||
300 | { | ||
301 | COOKIE_ ("name1", "value1"), | ||
302 | COOKIE_NULL, | ||
303 | COOKIE_NULL, | ||
304 | COOKIE_NULL, | ||
305 | COOKIE_NULL | ||
306 | } | ||
307 | }, | ||
308 | { | ||
309 | __LINE__, | ||
310 | ";name1=value1", | ||
311 | 0, | ||
312 | 0, | ||
313 | 1, | ||
314 | 1, | ||
315 | { | ||
316 | COOKIE_ ("name1", "value1"), | ||
317 | COOKIE_NULL, | ||
318 | COOKIE_NULL, | ||
319 | COOKIE_NULL, | ||
320 | COOKIE_NULL | ||
321 | } | ||
322 | }, | ||
323 | { | ||
324 | __LINE__, | ||
325 | "name1=value1 ", | ||
326 | 1, | ||
327 | 1, | ||
328 | 1, | ||
329 | 1, | ||
330 | { | ||
331 | COOKIE_ ("name1", "value1"), | ||
332 | COOKIE_NULL, | ||
333 | COOKIE_NULL, | ||
334 | COOKIE_NULL, | ||
335 | COOKIE_NULL | ||
336 | } | ||
337 | }, | ||
338 | { | ||
339 | __LINE__, | ||
340 | "name1=value1 ;", | ||
341 | 0, | ||
342 | 0, | ||
343 | 1, | ||
344 | 1, | ||
345 | { | ||
346 | COOKIE_ ("name1", "value1"), | ||
347 | COOKIE_NULL, | ||
348 | COOKIE_NULL, | ||
349 | COOKIE_NULL, | ||
350 | COOKIE_NULL | ||
351 | } | ||
352 | }, | ||
353 | { | ||
354 | __LINE__, | ||
355 | "name1=value1 ; ", | ||
356 | 0, | ||
357 | 0, | ||
358 | 1, | ||
359 | 1, | ||
360 | { | ||
361 | COOKIE_ ("name1", "value1"), | ||
362 | COOKIE_NULL, | ||
363 | COOKIE_NULL, | ||
364 | COOKIE_NULL, | ||
365 | COOKIE_NULL | ||
366 | } | ||
367 | }, | ||
368 | { | ||
369 | __LINE__, | ||
370 | "name2=\"value 2\"", | ||
371 | 0, | ||
372 | 0, | ||
373 | 1, | ||
374 | 1, | ||
375 | { | ||
376 | COOKIE_ ("name2", "value 2"), | ||
377 | COOKIE_NULL, | ||
378 | COOKIE_NULL, | ||
379 | COOKIE_NULL, | ||
380 | COOKIE_NULL | ||
381 | } | ||
382 | }, | ||
383 | { | ||
384 | __LINE__, | ||
385 | "name1=value1;\tname2=value2", | ||
386 | 0, | ||
387 | 1, | ||
388 | 2, | ||
389 | 2, | ||
390 | { | ||
391 | COOKIE_ ("name1", "value1"), | ||
392 | COOKIE_ ("name2", "value2"), | ||
393 | COOKIE_NULL, | ||
394 | COOKIE_NULL, | ||
395 | COOKIE_NULL | ||
396 | } | ||
397 | }, | ||
398 | { | ||
399 | __LINE__, | ||
400 | "name1=value1; name1=value1", | ||
401 | 2, | ||
402 | 2, | ||
403 | 2, | ||
404 | 2, | ||
405 | { | ||
406 | COOKIE_ ("name1", "value1"), | ||
407 | COOKIE_ ("name1", "value1"), | ||
408 | COOKIE_NULL, | ||
409 | COOKIE_NULL, | ||
410 | COOKIE_NULL | ||
411 | } | ||
412 | }, | ||
413 | { | ||
414 | __LINE__, | ||
415 | "name1=value1; name2=value2", | ||
416 | 2, | ||
417 | 2, | ||
418 | 2, | ||
419 | 2, | ||
420 | { | ||
421 | COOKIE_ ("name1", "value1"), | ||
422 | COOKIE_ ("name2", "value2"), | ||
423 | COOKIE_NULL, | ||
424 | COOKIE_NULL, | ||
425 | COOKIE_NULL | ||
426 | } | ||
427 | }, | ||
428 | { | ||
429 | __LINE__, | ||
430 | "name1=value1; name2=value2", | ||
431 | 2, | ||
432 | 2, | ||
433 | 2, | ||
434 | 2, | ||
435 | { | ||
436 | COOKIE_ ("name1", "value1"), | ||
437 | COOKIE_ ("name2", "value2"), | ||
438 | COOKIE_NULL, | ||
439 | COOKIE_NULL, | ||
440 | COOKIE_NULL | ||
441 | } | ||
442 | }, | ||
443 | { | ||
444 | __LINE__, | ||
445 | "name1=value1; name2=value2", | ||
446 | 2, | ||
447 | 2, | ||
448 | 2, | ||
449 | 2, | ||
450 | { | ||
451 | COOKIE_ ("name1", "value1"), | ||
452 | COOKIE_ ("name2", "value2"), | ||
453 | COOKIE_NULL, | ||
454 | COOKIE_NULL, | ||
455 | COOKIE_NULL | ||
456 | } | ||
457 | }, | ||
458 | { | ||
459 | __LINE__, | ||
460 | "name1=value1; name2=value2", | ||
461 | 2, | ||
462 | 2, | ||
463 | 2, | ||
464 | 2, | ||
465 | { | ||
466 | COOKIE_ ("name1", "value1"), | ||
467 | COOKIE_ ("name2", "value2"), | ||
468 | COOKIE_NULL, | ||
469 | COOKIE_NULL, | ||
470 | COOKIE_NULL | ||
471 | } | ||
472 | }, | ||
473 | { | ||
474 | __LINE__, | ||
475 | "name1=value1; name2=value2", | ||
476 | 2, | ||
477 | 2, | ||
478 | 2, | ||
479 | 2, | ||
480 | { | ||
481 | COOKIE_ ("name1", "value1"), | ||
482 | COOKIE_ ("name2", "value2"), | ||
483 | COOKIE_NULL, | ||
484 | COOKIE_NULL, | ||
485 | COOKIE_NULL | ||
486 | } | ||
487 | }, | ||
488 | { | ||
489 | __LINE__, | ||
490 | "name1=value1; name2=value2", | ||
491 | 2, | ||
492 | 2, | ||
493 | 2, | ||
494 | 2, | ||
495 | { | ||
496 | COOKIE_ ("name1", "value1"), | ||
497 | COOKIE_ ("name2", "value2"), | ||
498 | COOKIE_NULL, | ||
499 | COOKIE_NULL, | ||
500 | COOKIE_NULL | ||
501 | } | ||
502 | }, | ||
503 | { | ||
504 | __LINE__, | ||
505 | "name1=value1; name2=value2", | ||
506 | 2, | ||
507 | 2, | ||
508 | 2, | ||
509 | 2, | ||
510 | { | ||
511 | COOKIE_ ("name1", "value1"), | ||
512 | COOKIE_ ("name2", "value2"), | ||
513 | COOKIE_NULL, | ||
514 | COOKIE_NULL, | ||
515 | COOKIE_NULL | ||
516 | } | ||
517 | }, | ||
518 | { | ||
519 | __LINE__, | ||
245 | "name1=var1; name2=var2; name3=; " \ | 520 | "name1=var1; name2=var2; name3=; " \ |
246 | "name4=\"var4 with spaces\"; " \ | 521 | "name4=\"var4 with spaces\"; " \ |
247 | "name5=var_with_=_char", | 522 | "name5=var_with_=_char", |
248 | 5, | ||
249 | 0, | 523 | 0, |
524 | 3, | ||
525 | 5, | ||
526 | 5, | ||
250 | { | 527 | { |
251 | COOKIE_ ("name1", "var1"), | 528 | COOKIE_ ("name1", "var1"), |
252 | COOKIE_ ("name2", "var2"), | 529 | COOKIE_ ("name2", "var2"), |
@@ -260,8 +537,10 @@ static const struct strct_test_data test_data[] = { | |||
260 | "name1=var1;name2=var2;name3=;" \ | 537 | "name1=var1;name2=var2;name3=;" \ |
261 | "name4=\"var4 with spaces\";" \ | 538 | "name4=\"var4 with spaces\";" \ |
262 | "name5=var_with_=_char", | 539 | "name5=var_with_=_char", |
263 | 5, | ||
264 | 0, | 540 | 0, |
541 | 1, | ||
542 | 5, | ||
543 | 5, | ||
265 | { | 544 | { |
266 | COOKIE_ ("name1", "var1"), | 545 | COOKIE_ ("name1", "var1"), |
267 | COOKIE_ ("name2", "var2"), | 546 | COOKIE_ ("name2", "var2"), |
@@ -275,8 +554,10 @@ static const struct strct_test_data test_data[] = { | |||
275 | "name1=var1; name2=var2; name3=; " \ | 554 | "name1=var1; name2=var2; name3=; " \ |
276 | "name4=\"var4 with spaces\"; " \ | 555 | "name4=\"var4 with spaces\"; " \ |
277 | "name5=var_with_=_char\t \t", | 556 | "name5=var_with_=_char\t \t", |
278 | 5, | ||
279 | 0, | 557 | 0, |
558 | 1, | ||
559 | 5, | ||
560 | 5, | ||
280 | { | 561 | { |
281 | COOKIE_ ("name1", "var1"), | 562 | COOKIE_ ("name1", "var1"), |
282 | COOKIE_ ("name2", "var2"), | 563 | COOKIE_ ("name2", "var2"), |
@@ -290,8 +571,10 @@ static const struct strct_test_data test_data[] = { | |||
290 | "name1=var1;;name2=var2;;name3=;;" \ | 571 | "name1=var1;;name2=var2;;name3=;;" \ |
291 | "name4=\"var4 with spaces\";;" \ | 572 | "name4=\"var4 with spaces\";;" \ |
292 | "name5=var_with_=_char;\t \t", | 573 | "name5=var_with_=_char;\t \t", |
293 | 5, | ||
294 | 0, | 574 | 0, |
575 | 1, | ||
576 | 5, | ||
577 | 5, | ||
295 | { | 578 | { |
296 | COOKIE_ ("name1", "var1"), | 579 | COOKIE_ ("name1", "var1"), |
297 | COOKIE_ ("name2", "var2"), | 580 | COOKIE_ ("name2", "var2"), |
@@ -305,14 +588,16 @@ static const struct strct_test_data test_data[] = { | |||
305 | "name3=; name1=var1; name2=var2; " \ | 588 | "name3=; name1=var1; name2=var2; " \ |
306 | "name5=var_with_=_char;" \ | 589 | "name5=var_with_=_char;" \ |
307 | "name4=\"var4 with spaces\"", | 590 | "name4=\"var4 with spaces\"", |
308 | 5, | ||
309 | 0, | 591 | 0, |
592 | 4, | ||
593 | 5, | ||
594 | 5, | ||
310 | { | 595 | { |
311 | COOKIE_ ("name1", "var1"), | 596 | COOKIE_ ("name1", "var1"), |
312 | COOKIE_ ("name2", "var2"), | 597 | COOKIE_ ("name2", "var2"), |
313 | COOKIE_ ("name3", ""), | 598 | COOKIE_ ("name3", ""), |
314 | COOKIE_ ("name4", "var4 with spaces"), | 599 | COOKIE_ ("name5", "var_with_=_char"), |
315 | COOKIE_ ("name5", "var_with_=_char") | 600 | COOKIE_ ("name4", "var4 with spaces") |
316 | } | 601 | } |
317 | }, | 602 | }, |
318 | { | 603 | { |
@@ -320,14 +605,16 @@ static const struct strct_test_data test_data[] = { | |||
320 | "name2=var2; name1=var1; " \ | 605 | "name2=var2; name1=var1; " \ |
321 | "name5=var_with_=_char; name3=; " \ | 606 | "name5=var_with_=_char; name3=; " \ |
322 | "name4=\"var4 with spaces\";", | 607 | "name4=\"var4 with spaces\";", |
323 | 5, | ||
324 | 0, | 608 | 0, |
609 | 4, | ||
610 | 5, | ||
611 | 5, | ||
325 | { | 612 | { |
326 | COOKIE_ ("name1", "var1"), | 613 | COOKIE_ ("name1", "var1"), |
327 | COOKIE_ ("name2", "var2"), | 614 | COOKIE_ ("name2", "var2"), |
328 | COOKIE_ ("name3", ""), | 615 | COOKIE_ ("name3", ""), |
329 | COOKIE_ ("name4", "var4 with spaces"), | 616 | COOKIE_ ("name5", "var_with_=_char"), |
330 | COOKIE_ ("name5", "var_with_=_char") | 617 | COOKIE_ ("name4", "var4 with spaces") |
331 | } | 618 | } |
332 | }, | 619 | }, |
333 | { | 620 | { |
@@ -335,14 +622,16 @@ static const struct strct_test_data test_data[] = { | |||
335 | "name2=var2; name1=var1; " \ | 622 | "name2=var2; name1=var1; " \ |
336 | "name5=var_with_=_char; " \ | 623 | "name5=var_with_=_char; " \ |
337 | "name4=\"var4 with spaces\"; name3=", | 624 | "name4=\"var4 with spaces\"; name3=", |
338 | 5, | ||
339 | 0, | 625 | 0, |
626 | 3, | ||
627 | 5, | ||
628 | 5, | ||
340 | { | 629 | { |
341 | COOKIE_ ("name1", "var1"), | 630 | COOKIE_ ("name1", "var1"), |
342 | COOKIE_ ("name2", "var2"), | 631 | COOKIE_ ("name2", "var2"), |
632 | COOKIE_ ("name5", "var_with_=_char"), | ||
343 | COOKIE_ ("name3", ""), | 633 | COOKIE_ ("name3", ""), |
344 | COOKIE_ ("name4", "var4 with spaces"), | 634 | COOKIE_ ("name4", "var4 with spaces") |
345 | COOKIE_ ("name5", "var_with_=_char") | ||
346 | } | 635 | } |
347 | }, | 636 | }, |
348 | { | 637 | { |
@@ -350,8 +639,10 @@ static const struct strct_test_data test_data[] = { | |||
350 | "name2=var2; name1=var1; " \ | 639 | "name2=var2; name1=var1; " \ |
351 | "name4=\"var4 with spaces\"; " \ | 640 | "name4=\"var4 with spaces\"; " \ |
352 | "name5=var_with_=_char; name3=;", | 641 | "name5=var_with_=_char; name3=;", |
353 | 5, | ||
354 | 0, | 642 | 0, |
643 | 2, | ||
644 | 5, | ||
645 | 5, | ||
355 | { | 646 | { |
356 | COOKIE_ ("name1", "var1"), | 647 | COOKIE_ ("name1", "var1"), |
357 | COOKIE_ ("name2", "var2"), | 648 | COOKIE_ ("name2", "var2"), |
@@ -365,8 +656,10 @@ static const struct strct_test_data test_data[] = { | |||
365 | ";;;;;;;;name1=var1; name2=var2; name3=; " \ | 656 | ";;;;;;;;name1=var1; name2=var2; name3=; " \ |
366 | "name4=\"var4 with spaces\"; " \ | 657 | "name4=\"var4 with spaces\"; " \ |
367 | "name5=var_with_=_char", | 658 | "name5=var_with_=_char", |
368 | 5, | ||
369 | 0, | 659 | 0, |
660 | 0, | ||
661 | 5, | ||
662 | 5, | ||
370 | { | 663 | { |
371 | COOKIE_ ("name1", "var1"), | 664 | COOKIE_ ("name1", "var1"), |
372 | COOKIE_ ("name2", "var2"), | 665 | COOKIE_ ("name2", "var2"), |
@@ -380,8 +673,10 @@ static const struct strct_test_data test_data[] = { | |||
380 | "name1=var1; name2=var2; name3=; " \ | 673 | "name1=var1; name2=var2; name3=; " \ |
381 | "name4=\"var4 with spaces\"; ; ; ; ; " \ | 674 | "name4=\"var4 with spaces\"; ; ; ; ; " \ |
382 | "name5=var_with_=_char", | 675 | "name5=var_with_=_char", |
383 | 5, | ||
384 | 0, | 676 | 0, |
677 | 3, | ||
678 | 5, | ||
679 | 5, | ||
385 | { | 680 | { |
386 | COOKIE_ ("name1", "var1"), | 681 | COOKIE_ ("name1", "var1"), |
387 | COOKIE_ ("name2", "var2"), | 682 | COOKIE_ ("name2", "var2"), |
@@ -395,8 +690,10 @@ static const struct strct_test_data test_data[] = { | |||
395 | "name1=var1; name2=var2; name3=; " \ | 690 | "name1=var1; name2=var2; name3=; " \ |
396 | "name4=\"var4 with spaces\"; " \ | 691 | "name4=\"var4 with spaces\"; " \ |
397 | "name5=var_with_=_char;;;;;;;;", | 692 | "name5=var_with_=_char;;;;;;;;", |
398 | 5, | ||
399 | 0, | 693 | 0, |
694 | 3, | ||
695 | 5, | ||
696 | 5, | ||
400 | { | 697 | { |
401 | COOKIE_ ("name1", "var1"), | 698 | COOKIE_ ("name1", "var1"), |
402 | COOKIE_ ("name2", "var2"), | 699 | COOKIE_ ("name2", "var2"), |
@@ -408,16 +705,18 @@ static const struct strct_test_data test_data[] = { | |||
408 | { | 705 | { |
409 | __LINE__, | 706 | __LINE__, |
410 | "name1=var1; name2=var2; " \ | 707 | "name1=var1; name2=var2; " \ |
411 | "name4=\"var4 with spaces\"" \ | 708 | "name4=\"var4 with spaces\";" \ |
412 | "name5=var_with_=_char; ; ; ; ; name3=", | 709 | "name5=var_with_=_char; ; ; ; ; name3=", |
413 | 5, | ||
414 | 0, | 710 | 0, |
711 | 2, | ||
712 | 5, | ||
713 | 5, | ||
415 | { | 714 | { |
416 | COOKIE_ ("name1", "var1"), | 715 | COOKIE_ ("name1", "var1"), |
417 | COOKIE_ ("name2", "var2"), | 716 | COOKIE_ ("name2", "var2"), |
717 | COOKIE_ ("name5", "var_with_=_char"), | ||
418 | COOKIE_ ("name3", ""), | 718 | COOKIE_ ("name3", ""), |
419 | COOKIE_ ("name4", "var4 with spaces"), | 719 | COOKIE_ ("name4", "var4 with spaces") |
420 | COOKIE_ ("name5", "var_with_=_char") | ||
421 | } | 720 | } |
422 | }, | 721 | }, |
423 | { | 722 | { |
@@ -425,8 +724,10 @@ static const struct strct_test_data test_data[] = { | |||
425 | "name5=var_with_=_char ;" \ | 724 | "name5=var_with_=_char ;" \ |
426 | "name1=var1; name2=var2; name3=; " \ | 725 | "name1=var1; name2=var2; name3=; " \ |
427 | "name4=\"var4 with spaces\" ", | 726 | "name4=\"var4 with spaces\" ", |
428 | 5, | ||
429 | 0, | 727 | 0, |
728 | 0, | ||
729 | 5, | ||
730 | 5, | ||
430 | { | 731 | { |
431 | COOKIE_ ("name1", "var1"), | 732 | COOKIE_ ("name1", "var1"), |
432 | COOKIE_ ("name2", "var2"), | 733 | COOKIE_ ("name2", "var2"), |
@@ -439,14 +740,106 @@ static const struct strct_test_data test_data[] = { | |||
439 | __LINE__, | 740 | __LINE__, |
440 | "name5=var_with_=_char; name4=\"var4 with spaces\";" \ | 741 | "name5=var_with_=_char; name4=\"var4 with spaces\";" \ |
441 | "name1=var1; name2=var2; name3=", | 742 | "name1=var1; name2=var2; name3=", |
442 | 5, | ||
443 | 0, | 743 | 0, |
744 | 1, | ||
745 | 5, | ||
746 | 5, | ||
444 | { | 747 | { |
748 | COOKIE_ ("name5", "var_with_=_char"), | ||
445 | COOKIE_ ("name1", "var1"), | 749 | COOKIE_ ("name1", "var1"), |
446 | COOKIE_ ("name2", "var2"), | 750 | COOKIE_ ("name2", "var2"), |
447 | COOKIE_ ("name3", ""), | 751 | COOKIE_ ("name3", ""), |
448 | COOKIE_ ("name4", "var4 with spaces"), | 752 | COOKIE_ ("name4", "var4 with spaces") |
449 | COOKIE_ ("name5", "var_with_=_char") | 753 | } |
754 | }, | ||
755 | { | ||
756 | __LINE__, | ||
757 | "name1 = value1", | ||
758 | 0, | ||
759 | 0, | ||
760 | 0, | ||
761 | 1, | ||
762 | { | ||
763 | COOKIE_ ("name1", "value1"), | ||
764 | COOKIE_NULL, | ||
765 | COOKIE_NULL, | ||
766 | COOKIE_NULL, | ||
767 | COOKIE_NULL | ||
768 | } | ||
769 | }, | ||
770 | { | ||
771 | __LINE__, | ||
772 | "name1\t=\tvalue1", | ||
773 | 0, | ||
774 | 0, | ||
775 | 0, | ||
776 | 1, | ||
777 | { | ||
778 | COOKIE_ ("name1", "value1"), | ||
779 | COOKIE_NULL, | ||
780 | COOKIE_NULL, | ||
781 | COOKIE_NULL, | ||
782 | COOKIE_NULL | ||
783 | } | ||
784 | }, | ||
785 | { | ||
786 | __LINE__, | ||
787 | "name1\t = \tvalue1", | ||
788 | 0, | ||
789 | 0, | ||
790 | 0, | ||
791 | 1, | ||
792 | { | ||
793 | COOKIE_ ("name1", "value1"), | ||
794 | COOKIE_NULL, | ||
795 | COOKIE_NULL, | ||
796 | COOKIE_NULL, | ||
797 | COOKIE_NULL | ||
798 | } | ||
799 | }, | ||
800 | { | ||
801 | __LINE__, | ||
802 | "name1 = value1; name2 =\tvalue2", | ||
803 | 0, | ||
804 | 0, | ||
805 | 0, | ||
806 | 2, | ||
807 | { | ||
808 | COOKIE_ ("name1", "value1"), | ||
809 | COOKIE_ ("name2", "value2"), | ||
810 | COOKIE_NULL, | ||
811 | COOKIE_NULL, | ||
812 | COOKIE_NULL | ||
813 | } | ||
814 | }, | ||
815 | { | ||
816 | __LINE__, | ||
817 | "name1=value1; name2 =\tvalue2", | ||
818 | 0, | ||
819 | 1, | ||
820 | 1, | ||
821 | 2, | ||
822 | { | ||
823 | COOKIE_ ("name1", "value1"), | ||
824 | COOKIE_ ("name2", "value2"), | ||
825 | COOKIE_NULL, | ||
826 | COOKIE_NULL, | ||
827 | COOKIE_NULL | ||
828 | } | ||
829 | }, | ||
830 | { | ||
831 | __LINE__, | ||
832 | "name1 = value1; name2=value2", | ||
833 | 0, | ||
834 | 0, | ||
835 | 0, | ||
836 | 2, | ||
837 | { | ||
838 | COOKIE_ ("name1", "value1"), | ||
839 | COOKIE_ ("name2", "value2"), | ||
840 | COOKIE_NULL, | ||
841 | COOKIE_NULL, | ||
842 | COOKIE_NULL | ||
450 | } | 843 | } |
451 | }, | 844 | }, |
452 | { | 845 | { |
@@ -454,6 +847,8 @@ static const struct strct_test_data test_data[] = { | |||
454 | "", | 847 | "", |
455 | 0, | 848 | 0, |
456 | 0, | 849 | 0, |
850 | 0, | ||
851 | 0, | ||
457 | { | 852 | { |
458 | COOKIE_NULL, | 853 | COOKIE_NULL, |
459 | COOKIE_NULL, | 854 | COOKIE_NULL, |
@@ -467,6 +862,8 @@ static const struct strct_test_data test_data[] = { | |||
467 | " ", | 862 | " ", |
468 | 0, | 863 | 0, |
469 | 0, | 864 | 0, |
865 | 0, | ||
866 | 0, | ||
470 | { | 867 | { |
471 | COOKIE_NULL, | 868 | COOKIE_NULL, |
472 | COOKIE_NULL, | 869 | COOKIE_NULL, |
@@ -480,6 +877,8 @@ static const struct strct_test_data test_data[] = { | |||
480 | "\t", | 877 | "\t", |
481 | 0, | 878 | 0, |
482 | 0, | 879 | 0, |
880 | 0, | ||
881 | 0, | ||
483 | { | 882 | { |
484 | COOKIE_NULL, | 883 | COOKIE_NULL, |
485 | COOKIE_NULL, | 884 | COOKIE_NULL, |
@@ -493,6 +892,8 @@ static const struct strct_test_data test_data[] = { | |||
493 | "var=,", | 892 | "var=,", |
494 | 0, | 893 | 0, |
495 | 0, | 894 | 0, |
895 | 0, | ||
896 | 0, | ||
496 | { | 897 | { |
497 | COOKIE_NULL, | 898 | COOKIE_NULL, |
498 | COOKIE_NULL, | 899 | COOKIE_NULL, |
@@ -506,6 +907,8 @@ static const struct strct_test_data test_data[] = { | |||
506 | "var=\"\\ \"", | 907 | "var=\"\\ \"", |
507 | 0, | 908 | 0, |
508 | 0, | 909 | 0, |
910 | 0, | ||
911 | 0, | ||
509 | { | 912 | { |
510 | COOKIE_NULL, | 913 | COOKIE_NULL, |
511 | COOKIE_NULL, | 914 | COOKIE_NULL, |
@@ -519,6 +922,8 @@ static const struct strct_test_data test_data[] = { | |||
519 | "var=value space", | 922 | "var=value space", |
520 | 0, | 923 | 0, |
521 | 0, | 924 | 0, |
925 | 0, | ||
926 | 0, | ||
522 | { | 927 | { |
523 | COOKIE_NULL, | 928 | COOKIE_NULL, |
524 | COOKIE_NULL, | 929 | COOKIE_NULL, |
@@ -532,6 +937,8 @@ static const struct strct_test_data test_data[] = { | |||
532 | "var=value\ttab", | 937 | "var=value\ttab", |
533 | 0, | 938 | 0, |
534 | 0, | 939 | 0, |
940 | 0, | ||
941 | 0, | ||
535 | { | 942 | { |
536 | COOKIE_NULL, | 943 | COOKIE_NULL, |
537 | COOKIE_NULL, | 944 | COOKIE_NULL, |
@@ -545,6 +952,8 @@ static const struct strct_test_data test_data[] = { | |||
545 | "=", | 952 | "=", |
546 | 0, | 953 | 0, |
547 | 0, | 954 | 0, |
955 | 0, | ||
956 | 0, | ||
548 | { | 957 | { |
549 | COOKIE_NULL, | 958 | COOKIE_NULL, |
550 | COOKIE_NULL, | 959 | COOKIE_NULL, |
@@ -558,6 +967,8 @@ static const struct strct_test_data test_data[] = { | |||
558 | "====", | 967 | "====", |
559 | 0, | 968 | 0, |
560 | 0, | 969 | 0, |
970 | 0, | ||
971 | 0, | ||
561 | { | 972 | { |
562 | COOKIE_NULL, | 973 | COOKIE_NULL, |
563 | COOKIE_NULL, | 974 | COOKIE_NULL, |
@@ -571,6 +982,8 @@ static const struct strct_test_data test_data[] = { | |||
571 | ";=", | 982 | ";=", |
572 | 0, | 983 | 0, |
573 | 0, | 984 | 0, |
985 | 0, | ||
986 | 0, | ||
574 | { | 987 | { |
575 | COOKIE_NULL, | 988 | COOKIE_NULL, |
576 | COOKIE_NULL, | 989 | COOKIE_NULL, |
@@ -584,6 +997,8 @@ static const struct strct_test_data test_data[] = { | |||
584 | "var", | 997 | "var", |
585 | 0, | 998 | 0, |
586 | 0, | 999 | 0, |
1000 | 0, | ||
1001 | 0, | ||
587 | { | 1002 | { |
588 | COOKIE_NULL, | 1003 | COOKIE_NULL, |
589 | COOKIE_NULL, | 1004 | COOKIE_NULL, |
@@ -597,6 +1012,8 @@ static const struct strct_test_data test_data[] = { | |||
597 | "=;", | 1012 | "=;", |
598 | 0, | 1013 | 0, |
599 | 0, | 1014 | 0, |
1015 | 0, | ||
1016 | 0, | ||
600 | { | 1017 | { |
601 | COOKIE_NULL, | 1018 | COOKIE_NULL, |
602 | COOKIE_NULL, | 1019 | COOKIE_NULL, |
@@ -610,6 +1027,8 @@ static const struct strct_test_data test_data[] = { | |||
610 | "= ;", | 1027 | "= ;", |
611 | 0, | 1028 | 0, |
612 | 0, | 1029 | 0, |
1030 | 0, | ||
1031 | 0, | ||
613 | { | 1032 | { |
614 | COOKIE_NULL, | 1033 | COOKIE_NULL, |
615 | COOKIE_NULL, | 1034 | COOKIE_NULL, |
@@ -623,6 +1042,8 @@ static const struct strct_test_data test_data[] = { | |||
623 | ";= ;", | 1042 | ";= ;", |
624 | 0, | 1043 | 0, |
625 | 0, | 1044 | 0, |
1045 | 0, | ||
1046 | 0, | ||
626 | { | 1047 | { |
627 | COOKIE_NULL, | 1048 | COOKIE_NULL, |
628 | COOKIE_NULL, | 1049 | COOKIE_NULL, |
@@ -636,7 +1057,10 @@ static const struct strct_test_data test_data[] = { | |||
636 | /* Global parameters */ | 1057 | /* Global parameters */ |
637 | static int verbose; | 1058 | static int verbose; |
638 | static int oneone; /**< If false use HTTP/1.0 for requests*/ | 1059 | static int oneone; /**< If false use HTTP/1.0 for requests*/ |
639 | static int use_non_strict; | 1060 | static int use_strict_n1; |
1061 | static int use_strict_zero; | ||
1062 | static int use_strict_p1; | ||
1063 | static int strict_level; | ||
640 | 1064 | ||
641 | static void | 1065 | static void |
642 | test_global_init (void) | 1066 | test_global_init (void) |
@@ -700,12 +1124,19 @@ ahcCheck (void *cls, | |||
700 | struct MHD_Response *response; | 1124 | struct MHD_Response *response; |
701 | enum MHD_Result ret; | 1125 | enum MHD_Result ret; |
702 | struct ahc_cls_type *const param = (struct ahc_cls_type *) cls; | 1126 | struct ahc_cls_type *const param = (struct ahc_cls_type *) cls; |
703 | const unsigned int expected_num_cookies = | 1127 | unsigned int expected_num_cookies; |
704 | use_non_strict ? param->check->num_cookies_non_strict : | ||
705 | param->check->num_cookies_strict; | ||
706 | unsigned int i; | 1128 | unsigned int i; |
707 | int cookie_failed; | 1129 | int cookie_failed; |
708 | 1130 | ||
1131 | if (use_strict_p1) | ||
1132 | expected_num_cookies = param->check->num_cookies_strict_p1; | ||
1133 | else if (use_strict_zero) | ||
1134 | expected_num_cookies = param->check->num_cookies_strict_zero; | ||
1135 | else if (use_strict_n1) | ||
1136 | expected_num_cookies = param->check->num_cookies_strict_n1; | ||
1137 | else | ||
1138 | externalErrorExit (); | ||
1139 | |||
709 | if (NULL == param) | 1140 | if (NULL == param) |
710 | mhdErrorExitDesc ("cls parameter is NULL"); | 1141 | mhdErrorExitDesc ("cls parameter is NULL"); |
711 | 1142 | ||
@@ -813,7 +1244,17 @@ ahcCheck (void *cls, | |||
813 | cookie_failed = 1; | 1244 | cookie_failed = 1; |
814 | } | 1245 | } |
815 | if (cookie_failed) | 1246 | if (cookie_failed) |
816 | return MHD_NO; /* Break connection */ | 1247 | { |
1248 | response = | ||
1249 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (PAGE_ERROR), | ||
1250 | PAGE_ERROR); | ||
1251 | ret = MHD_queue_response (connection, | ||
1252 | MHD_HTTP_BAD_REQUEST, | ||
1253 | response); | ||
1254 | MHD_destroy_response (response); | ||
1255 | |||
1256 | return ret; | ||
1257 | } | ||
817 | 1258 | ||
818 | if (&marker != *req_cls) | 1259 | if (&marker != *req_cls) |
819 | { | 1260 | { |
@@ -1057,7 +1498,6 @@ check_result (CURLcode curl_code, CURL *c, long expected_code, | |||
1057 | struct CBC *pcbc) | 1498 | struct CBC *pcbc) |
1058 | { | 1499 | { |
1059 | long code; | 1500 | long code; |
1060 | unsigned int ret; | ||
1061 | 1501 | ||
1062 | if (CURLE_OK != curl_code) | 1502 | if (CURLE_OK != curl_code) |
1063 | { | 1503 | { |
@@ -1079,15 +1519,15 @@ check_result (CURLcode curl_code, CURL *c, long expected_code, | |||
1079 | if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code)) | 1519 | if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code)) |
1080 | libcurlErrorExit (); | 1520 | libcurlErrorExit (); |
1081 | 1521 | ||
1082 | ret = 1; | ||
1083 | if (expected_code != code) | 1522 | if (expected_code != code) |
1084 | { | 1523 | { |
1085 | fprintf (stderr, "The response has wrong HTTP code: %ld\tExpected: %ld.\n", | 1524 | fprintf (stderr, "### The response has wrong HTTP code: %ld\t" |
1525 | "Expected: %ld.\n", | ||
1086 | code, expected_code); | 1526 | code, expected_code); |
1087 | ret = 0; | 1527 | return 0; |
1088 | } | 1528 | } |
1089 | else if (verbose) | 1529 | else if (verbose) |
1090 | printf ("The response has expected HTTP code: %ld\n", expected_code); | 1530 | printf ("### The response has expected HTTP code: %ld\n", expected_code); |
1091 | 1531 | ||
1092 | if (pcbc->pos != MHD_STATICSTR_LEN_ (PAGE)) | 1532 | if (pcbc->pos != MHD_STATICSTR_LEN_ (PAGE)) |
1093 | { | 1533 | { |
@@ -1105,7 +1545,7 @@ check_result (CURLcode curl_code, CURL *c, long expected_code, | |||
1105 | fflush (stderr); | 1545 | fflush (stderr); |
1106 | fflush (stdout); | 1546 | fflush (stdout); |
1107 | 1547 | ||
1108 | return ret; | 1548 | return 1; |
1109 | } | 1549 | } |
1110 | 1550 | ||
1111 | 1551 | ||
@@ -1125,13 +1565,13 @@ testExternalPolling (void) | |||
1125 | if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) | 1565 | if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) |
1126 | port = 0; | 1566 | port = 0; |
1127 | else | 1567 | else |
1128 | port = 1340 + oneone ? 0 : 1 + use_non_strict ? 0 : 2; | 1568 | port = 1340 + oneone ? 0 : 6 + (uint16_t) (1 + strict_level); |
1129 | 1569 | ||
1130 | d = MHD_start_daemon (MHD_USE_ERROR_LOG, | 1570 | d = MHD_start_daemon (MHD_USE_ERROR_LOG, |
1131 | port, NULL, NULL, | 1571 | port, NULL, NULL, |
1132 | &ahcCheck, &ahc_param, | 1572 | &ahcCheck, &ahc_param, |
1133 | MHD_OPTION_STRICT_FOR_CLIENT, | 1573 | MHD_OPTION_STRICT_FOR_CLIENT, |
1134 | (int) (use_non_strict ? 0 : 1), | 1574 | (int) (strict_level), |
1135 | MHD_OPTION_END); | 1575 | MHD_OPTION_END); |
1136 | if (d == NULL) | 1576 | if (d == NULL) |
1137 | return 1; | 1577 | return 1; |
@@ -1167,13 +1607,13 @@ testExternalPolling (void) | |||
1167 | MHD_HTTP_OK, &cbc)) | 1607 | MHD_HTTP_OK, &cbc)) |
1168 | { | 1608 | { |
1169 | if (verbose) | 1609 | if (verbose) |
1170 | printf ("Got expected response for the check at line %u.\n", | 1610 | printf ("### Got expected response for the check at line %u.\n", |
1171 | test_data[i].line_num); | 1611 | test_data[i].line_num); |
1172 | fflush (stdout); | 1612 | fflush (stdout); |
1173 | } | 1613 | } |
1174 | else | 1614 | else |
1175 | { | 1615 | { |
1176 | fprintf (stderr, "FAILED request for the check at line %u.\n", | 1616 | fprintf (stderr, "### FAILED request for the check at line %u.\n", |
1177 | test_data[i].line_num); | 1617 | test_data[i].line_num); |
1178 | fflush (stderr); | 1618 | fflush (stderr); |
1179 | failed = 1; | 1619 | failed = 1; |
@@ -1200,7 +1640,19 @@ main (int argc, char *const *argv) | |||
1200 | has_param (argc, argv, "-s") || | 1640 | has_param (argc, argv, "-s") || |
1201 | has_param (argc, argv, "--silent")); | 1641 | has_param (argc, argv, "--silent")); |
1202 | oneone = ! has_in_name (argv[0], "10"); | 1642 | oneone = ! has_in_name (argv[0], "10"); |
1203 | use_non_strict = has_in_name (argv[0], "_nonstrict"); | 1643 | use_strict_n1 = has_in_name (argv[0], "_strict_n1"); |
1644 | use_strict_zero = has_in_name (argv[0], "_strict_zero"); | ||
1645 | use_strict_p1 = has_in_name (argv[0], "_strict_p1"); | ||
1646 | if (1 != ((use_strict_n1 ? 1 : 0) + (use_strict_zero ? 1 : 0) | ||
1647 | + (use_strict_p1 ? 1 : 0))) | ||
1648 | return 99; | ||
1649 | |||
1650 | if (use_strict_n1) | ||
1651 | strict_level = -1; | ||
1652 | else if (use_strict_zero) | ||
1653 | strict_level = 0; | ||
1654 | else if (use_strict_p1) | ||
1655 | strict_level = 1; | ||
1204 | 1656 | ||
1205 | test_global_init (); | 1657 | test_global_init (); |
1206 | 1658 | ||