diff options
Diffstat (limited to 'src/microhttpd/response.c')
-rw-r--r-- | src/microhttpd/response.c | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c index 47e28046..0a70c0f7 100644 --- a/src/microhttpd/response.c +++ b/src/microhttpd/response.c | |||
@@ -213,11 +213,11 @@ add_response_header_connection (struct MHD_Response *response, | |||
213 | /** the length of the "Connection" key */ | 213 | /** the length of the "Connection" key */ |
214 | static const size_t key_len = | 214 | static const size_t key_len = |
215 | MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_CONNECTION); | 215 | MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_CONNECTION); |
216 | size_t value_len; /**< the length of the @a value */ | 216 | size_t value_len; /**< the length of the @a value */ |
217 | size_t old_value_len; /**< the length of the existing "Connection" value */ | 217 | size_t old_value_len; /**< the length of the existing "Connection" value */ |
218 | size_t buf_size; /**< the size of the buffer */ | 218 | size_t buf_size; /**< the size of the buffer */ |
219 | ssize_t norm_len; /**< the length of the normalised value */ | 219 | size_t norm_len; /**< the length of the normalised value */ |
220 | char *buf; /**< the temporal buffer */ | 220 | char *buf; /**< the temporal buffer */ |
221 | struct MHD_HTTP_Res_Header *hdr; /**< existing "Connection" header */ | 221 | struct MHD_HTTP_Res_Header *hdr; /**< existing "Connection" header */ |
222 | bool value_has_close; /**< the @a value has "close" token */ | 222 | bool value_has_close; /**< the @a value has "close" token */ |
223 | bool already_has_close; /**< existing "Connection" header has "close" token */ | 223 | bool already_has_close; /**< existing "Connection" header has "close" token */ |
@@ -253,19 +253,27 @@ add_response_header_connection (struct MHD_Response *response, | |||
253 | value_len = strlen (value); | 253 | value_len = strlen (value); |
254 | if (value_len >= SSIZE_MAX) | 254 | if (value_len >= SSIZE_MAX) |
255 | return MHD_NO; | 255 | return MHD_NO; |
256 | /* Additional space for normalisation and zero-termination*/ | 256 | /* Additional space for normalisation and zero-termination */ |
257 | norm_len = (ssize_t) (value_len + value_len / 2 + 1); | 257 | norm_len = value_len + value_len / 2 + 1; |
258 | buf_size = old_value_len + (size_t) norm_len; | 258 | buf_size = old_value_len + (size_t) norm_len; |
259 | 259 | ||
260 | buf = malloc (buf_size); | 260 | buf = malloc (buf_size); |
261 | if (NULL == buf) | 261 | if (NULL == buf) |
262 | return MHD_NO; | 262 | return MHD_NO; |
263 | /* Remove "close" token (if any), it will be moved to the front */ | 263 | if (1) |
264 | value_has_close = MHD_str_remove_token_caseless_ (value, value_len, "close", | 264 | { /* local scope */ |
265 | MHD_STATICSTR_LEN_ ( \ | 265 | ssize_t norm_len_s = (ssize_t) norm_len; |
266 | "close"), | 266 | /* Remove "close" token (if any), it will be moved to the front */ |
267 | buf + old_value_len, | 267 | value_has_close = MHD_str_remove_token_caseless_ (value, value_len, "close", |
268 | &norm_len); | 268 | MHD_STATICSTR_LEN_ ( \ |
269 | "close"), | ||
270 | buf + old_value_len, | ||
271 | &norm_len_s); | ||
272 | mhd_assert (0 <= norm_len_s); | ||
273 | if (0 > norm_len_s) | ||
274 | norm_len = 0; /* Must never happen */ | ||
275 | norm_len = (size_t) norm_len; | ||
276 | } | ||
269 | #ifdef UPGRADE_SUPPORT | 277 | #ifdef UPGRADE_SUPPORT |
270 | if ( (NULL != response->upgrade_handler) && value_has_close) | 278 | if ( (NULL != response->upgrade_handler) && value_has_close) |
271 | { /* The "close" token cannot be used with connection "upgrade" */ | 279 | { /* The "close" token cannot be used with connection "upgrade" */ |
@@ -273,17 +281,10 @@ add_response_header_connection (struct MHD_Response *response, | |||
273 | return MHD_NO; | 281 | return MHD_NO; |
274 | } | 282 | } |
275 | #endif /* UPGRADE_SUPPORT */ | 283 | #endif /* UPGRADE_SUPPORT */ |
276 | mhd_assert (0 <= norm_len); | ||
277 | if (0 > norm_len) | ||
278 | norm_len = 0; /* Must never happen */ | ||
279 | if (0 != norm_len) | 284 | if (0 != norm_len) |
280 | { | 285 | MHD_str_remove_tokens_caseless_ (buf + old_value_len, &norm_len, |
281 | size_t len = norm_len; | ||
282 | MHD_str_remove_tokens_caseless_ (buf + old_value_len, &len, | ||
283 | "keep-alive", | 286 | "keep-alive", |
284 | MHD_STATICSTR_LEN_ ("keep-alive")); | 287 | MHD_STATICSTR_LEN_ ("keep-alive")); |
285 | norm_len = (ssize_t) len; | ||
286 | } | ||
287 | if (0 == norm_len) | 288 | if (0 == norm_len) |
288 | { /* New value is empty after normalisation */ | 289 | { /* New value is empty after normalisation */ |
289 | if (! value_has_close) | 290 | if (! value_has_close) |
@@ -301,7 +302,7 @@ add_response_header_connection (struct MHD_Response *response, | |||
301 | if (value_has_close && ! already_has_close) | 302 | if (value_has_close && ! already_has_close) |
302 | { | 303 | { |
303 | /* Need to insert "close" token at the first position */ | 304 | /* Need to insert "close" token at the first position */ |
304 | mhd_assert (buf_size >= old_value_len + (size_t) norm_len \ | 305 | mhd_assert (buf_size >= old_value_len + norm_len \ |
305 | + MHD_STATICSTR_LEN_ ("close, ") + 1); | 306 | + MHD_STATICSTR_LEN_ ("close, ") + 1); |
306 | if (0 != norm_len) | 307 | if (0 != norm_len) |
307 | memmove (buf + MHD_STATICSTR_LEN_ ("close, ") + old_value_len, | 308 | memmove (buf + MHD_STATICSTR_LEN_ ("close, ") + old_value_len, |
@@ -333,7 +334,7 @@ add_response_header_connection (struct MHD_Response *response, | |||
333 | mhd_assert ((value_has_close && ! already_has_close) ? \ | 334 | mhd_assert ((value_has_close && ! already_has_close) ? \ |
334 | (MHD_STATICSTR_LEN_ ("close, ") + old_value_len == pos) : \ | 335 | (MHD_STATICSTR_LEN_ ("close, ") + old_value_len == pos) : \ |
335 | (old_value_len == pos)); | 336 | (old_value_len == pos)); |
336 | pos += (size_t) norm_len; | 337 | pos += norm_len; |
337 | } | 338 | } |
338 | mhd_assert (buf_size > pos); | 339 | mhd_assert (buf_size > pos); |
339 | buf[pos] = 0; /* Null terminate the result */ | 340 | buf[pos] = 0; /* Null terminate the result */ |
@@ -1118,7 +1119,7 @@ MHD_create_response_from_fd_at_offset (size_t size, | |||
1118 | { | 1119 | { |
1119 | return MHD_create_response_from_fd_at_offset64 (size, | 1120 | return MHD_create_response_from_fd_at_offset64 (size, |
1120 | fd, | 1121 | fd, |
1121 | offset); | 1122 | (uint64_t) offset); |
1122 | } | 1123 | } |
1123 | 1124 | ||
1124 | 1125 | ||
@@ -1631,7 +1632,7 @@ MHD_create_response_from_iovec (const struct MHD_IoVec *iov, | |||
1631 | MHD_iovec_ *iov_copy; | 1632 | MHD_iovec_ *iov_copy; |
1632 | int num_copy_elements = i_cp; | 1633 | int num_copy_elements = i_cp; |
1633 | 1634 | ||
1634 | iov_copy = MHD_calloc_ (num_copy_elements, | 1635 | iov_copy = MHD_calloc_ ((size_t) num_copy_elements, \ |
1635 | sizeof(MHD_iovec_)); | 1636 | sizeof(MHD_iovec_)); |
1636 | if (NULL == iov_copy) | 1637 | if (NULL == iov_copy) |
1637 | { | 1638 | { |
@@ -1662,8 +1663,9 @@ MHD_create_response_from_iovec (const struct MHD_IoVec *iov, | |||
1662 | i_cp++; | 1663 | i_cp++; |
1663 | } | 1664 | } |
1664 | mhd_assert (num_copy_elements == i_cp); | 1665 | mhd_assert (num_copy_elements == i_cp); |
1666 | mhd_assert (0 <= i_cp); | ||
1665 | response->data_iov = iov_copy; | 1667 | response->data_iov = iov_copy; |
1666 | response->data_iovcnt = i_cp; | 1668 | response->data_iovcnt = (unsigned int) i_cp; |
1667 | } | 1669 | } |
1668 | return response; | 1670 | return response; |
1669 | } | 1671 | } |