diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/easyoptions.c | 3 | ||||
-rw-r--r-- | lib/mime.c | 64 | ||||
-rw-r--r-- | lib/setopt.c | 7 | ||||
-rw-r--r-- | lib/urldata.h | 1 |
4 files changed, 54 insertions, 21 deletions
diff --git a/lib/easyoptions.c b/lib/easyoptions.c index b6131d432..04871ad1e 100644 --- a/lib/easyoptions.c +++ b/lib/easyoptions.c @@ -170,6 +170,7 @@ struct curl_easyoption Curl_easyopts[] = { {"MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE, CURLOT_OFF_T, 0}, {"MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE, CURLOT_OFF_T, 0}, {"MIMEPOST", CURLOPT_MIMEPOST, CURLOT_OBJECT, 0}, + {"MIME_OPTIONS", CURLOPT_MIME_OPTIONS, CURLOT_LONG, 0}, {"NETRC", CURLOPT_NETRC, CURLOT_VALUES, 0}, {"NETRC_FILE", CURLOPT_NETRC_FILE, CURLOT_STRING, 0}, {"NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS, CURLOT_LONG, 0}, @@ -359,6 +360,6 @@ struct curl_easyoption Curl_easyopts[] = { */ int Curl_easyopts_check(void) { - return ((CURLOPT_LASTENTRY%10000) != (314 + 1)); + return ((CURLOPT_LASTENTRY%10000) != (315 + 1)); } #endif diff --git a/lib/mime.c b/lib/mime.c index f40cc1a61..7783b8990 100644 --- a/lib/mime.c +++ b/lib/mime.c @@ -40,6 +40,7 @@ #include "rand.h" #include "slist.h" #include "strcase.h" +#include "dynbuf.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -279,29 +280,52 @@ static void mimesetstate(struct mime_state *state, /* Escape header string into allocated memory. */ -static char *escape_string(const char *src) -{ - size_t bytecount = 0; - size_t i; - char *dst; +static char *escape_string(struct Curl_easy *data, + const char *src, enum mimestrategy strategy) +{ + CURLcode result; + struct dynbuf db; + const char * const *table; + const char * const *p; + /* replace first character by rest of string. */ + static const char * const mimetable[] = { + "\\\\\\", + "\"\\\"", + NULL + }; + /* WHATWG HTML living standard 4.10.21.8 2 specifies: + For field names and filenames for file fields, the result of the + encoding in the previous bullet point must be escaped by replacing + any 0x0A (LF) bytes with the byte sequence `%0A`, 0x0D (CR) with `%0D` + and 0x22 (") with `%22`. + The user agent must not perform any other escapes. */ + static const char * const formtable[] = { + "\"%22", + "\r%0D", + "\n%0A", + NULL + }; - for(i = 0; src[i]; i++) - if(src[i] == '"' || src[i] == '\\') - bytecount++; + table = formtable; + /* data can be NULL when this function is called indirectly from + curl_formget(). */ + if(strategy == MIMESTRATEGY_MAIL || + (data && (data->set.mime_options & CURLMIMEOPT_FORMESCAPE))) + table = mimetable; - bytecount += i; - dst = malloc(bytecount + 1); - if(!dst) - return NULL; + Curl_dyn_init(&db, CURL_MAX_INPUT_LENGTH); - for(i = 0; *src; src++) { - if(*src == '"' || *src == '\\') - dst[i++] = '\\'; - dst[i++] = *src; + for(result = Curl_dyn_add(&db, ""); !result && *src; src++) { + for(p = table; *p && **p != *src; p++) + ; + + if(*p) + result = Curl_dyn_add(&db, *p + 1); + else + result = Curl_dyn_addn(&db, src, 1); } - dst[i] = '\0'; - return dst; + return Curl_dyn_ptr(&db); } /* Check if header matches. */ @@ -1866,12 +1890,12 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part, char *filename = NULL; if(part->name) { - name = escape_string(part->name); + name = escape_string(part->easy, part->name, strategy); if(!name) ret = CURLE_OUT_OF_MEMORY; } if(!ret && part->filename) { - filename = escape_string(part->filename); + filename = escape_string(part->easy, part->filename, strategy); if(!filename) ret = CURLE_OUT_OF_MEMORY; } diff --git a/lib/setopt.c b/lib/setopt.c index 56d9c4992..ddb010259 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -2609,6 +2609,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #endif +#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \ + !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP) + case CURLOPT_MIME_OPTIONS: + data->set.mime_options = va_arg(param, long); + break; +#endif + case CURLOPT_SASL_AUTHZID: /* Authorisation identity (identity to act as) */ result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID], diff --git a/lib/urldata.h b/lib/urldata.h index 22068882f..f12e99b8d 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1749,6 +1749,7 @@ struct UserDefined { unsigned int scope_id; /* Scope id for IPv6 */ long allowed_protocols; long redir_protocols; + long mime_options; /* Mime option flags. */ struct curl_slist *mail_rcpt; /* linked list of mail recipients */ /* Common RTSP header options */ Curl_RtspReq rtspreq; /* RTSP request type */ |