| @@ -0,0 +1,133 @@ |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * Project ___| | | | _ \| | |
| + | * / __| | | | |_) | | |
| + | * | (__| |_| | _ <| |___ |
| + | * \___|\___/|_| \_\_____| |
| + | * |
| + | * Copyright (C) Daniel Stenberg, <[email protected]>, et al. |
| + | * |
| + | * This software is licensed as described in the file COPYING, which |
| + | * you should have received as part of this distribution. The terms |
| + | * are also available at https://curl.se/docs/copyright.html. |
| + | * |
| + | * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
| + | * copies of the Software, and permit persons to whom the Software is |
| + | * furnished to do so, under the terms of the COPYING file. |
| + | * |
| + | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| + | * KIND, either express or implied. |
| + | * |
| + | * SPDX-License-Identifier: curl |
| + | * |
| + | ***************************************************************************/ |
| + | #include "unitcheck.h" |
| + | #include "urldata.h" |
| + | #include "mime.h" |
| + | |
| + | #if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) || \ |
| + | !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)) |
| + | |
| + | /* does any generated part header carry a raw CR or LF, i.e. a split line? */ |
| + | static bool headers_have_ctrl(const curl_mimepart *part) |
| + | { |
| + | const struct curl_slist *h; |
| + | for(h = part->curlheaders; h; h = h->next) |
| + | if(h->data[strcspn(h->data, "\r\n")]) |
| + | return TRUE; |
| + | return FALSE; |
| + | } |
| + | |
| + | static CURLcode t3227_setup(void) |
| + | { |
| + | CURLcode result = CURLE_OK; |
| + | global_init(CURL_GLOBAL_ALL); |
| + | return result; |
| + | } |
| + | |
| + | static void t3227_stop(CURL *easy, curl_mime *mime) |
| + | { |
| + | curl_mime_free(mime); |
| + | if(easy) |
| + | curl_easy_cleanup(easy); |
| + | curl_global_cleanup(); |
| + | } |
| + | |
| + | static CURLcode test_unit3227(const char *arg) |
| + | { |
| + | CURL *easy = NULL; |
| + | curl_mime *mime = NULL; |
| + | curl_mimepart *part; |
| + | |
| + | UNITTEST_BEGIN(t3227_setup()) |
| + | |
| + | easy = curl_easy_init(); |
| + | abort_unless(easy, "curl_easy_init()"); |
| + | mime = curl_mime_init(easy); |
| + | abort_unless(mime, "curl_mime_init()"); |
| + | |
| + | /* A CR or LF in the mail-part name or filename would split the generated |
| + | Content-Disposition header. The mail strategy must reject it. */ |
| + | |
| + | part = curl_mime_addpart(mime); |
| + | abort_unless(part, "curl_mime_addpart()"); |
| + | curl_mime_data(part, "x", 1); |
| + | curl_mime_filename(part, "a\r\nX-Injected: 1"); |
| + | fail_unless(Curl_mime_prepare_headers(easy, part, NULL, NULL, |
| + | MIMESTRATEGY_MAIL) == |
| + | CURLE_BAD_FUNCTION_ARGUMENT, |
| + | "CRLF filename accepted for mail"); |
| + | |
| + | part = curl_mime_addpart(mime); |
| + | abort_unless(part, "curl_mime_addpart()"); |
| + | curl_mime_data(part, "x", 1); |
| + | curl_mime_name(part, "a\nb"); |
| + | fail_unless(Curl_mime_prepare_headers(easy, part, NULL, NULL, |
| + | MIMESTRATEGY_MAIL) == |
| + | CURLE_BAD_FUNCTION_ARGUMENT, |
| + | "LF name accepted for mail"); |
| + | |
| + | part = curl_mime_addpart(mime); |
| + | abort_unless(part, "curl_mime_addpart()"); |
| + | curl_mime_data(part, "x", 1); |
| + | curl_mime_filename(part, "a\rb"); |
| + | fail_unless(Curl_mime_prepare_headers(easy, part, NULL, NULL, |
| + | MIMESTRATEGY_MAIL) == |
| + | CURLE_BAD_FUNCTION_ARGUMENT, |
| + | "CR filename accepted for mail"); |
| + | |
| + | /* A regular name and filename are accepted and produce a clean header. */ |
| + | part = curl_mime_addpart(mime); |
| + | abort_unless(part, "curl_mime_addpart()"); |
| + | curl_mime_data(part, "x", 1); |
| + | curl_mime_name(part, "field"); |
| + | curl_mime_filename(part, "readme.txt"); |
| + | fail_unless(Curl_mime_prepare_headers(easy, part, NULL, NULL, |
| + | MIMESTRATEGY_MAIL) == CURLE_OK, |
| + | "plain mail part rejected"); |
| + | fail_if(headers_have_ctrl(part), "clean mail header split"); |
| + | |
| + | /* The HTTP form strategy percent-encodes CR/LF, so it stays accepted and |
| + | produces no split line. */ |
| + | part = curl_mime_addpart(mime); |
| + | abort_unless(part, "curl_mime_addpart()"); |
| + | curl_mime_data(part, "x", 1); |
| + | curl_mime_filename(part, "a\r\nX-Injected: 1"); |
| + | fail_unless(Curl_mime_prepare_headers(easy, part, NULL, NULL, |
| + | MIMESTRATEGY_FORM) == CURLE_OK, |
| + | "CRLF filename rejected for form"); |
| + | fail_if(headers_have_ctrl(part), "form header split despite encoding"); |
| + | |
| + | UNITTEST_END(t3227_stop(easy, mime)) |
| + | } |
| + | |
| + | #else /* mime disabled */ |
| + | |
| + | static CURLcode test_unit3227(const char *arg) |
| + | { |
| + | UNITTEST_BEGIN_SIMPLE |
| + | puts("nothing to do when mime is disabled"); |
| + | UNITTEST_END_SIMPLE |
| + | } |
| + | |
| + | #endif |