summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/easyoptions.c3
-rw-r--r--lib/mime.c64
-rw-r--r--lib/setopt.c7
-rw-r--r--lib/urldata.h1
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 */