From ee56fdb6910f6bf215eecede9e2e9bfc83cb5f29 Mon Sep 17 00:00:00 2001 From: Patrick Monnerat Date: Fri, 22 Sep 2017 01:08:29 +0100 Subject: form/mime: field names are not allowed to contain zero-valued bytes. Also suppress length argument of curl_mime_name() (names are always zero-terminated). --- lib/formdata.c | 37 ++++++++++++++++++++++++++++++++----- lib/mime.c | 44 +++++++++++++------------------------------- lib/mime.h | 1 - 3 files changed, 45 insertions(+), 37 deletions(-) (limited to 'lib') diff --git a/lib/formdata.c b/lib/formdata.c index ed7b33482..3568ac579 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -636,12 +636,23 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } form->contenttype_alloc = TRUE; } + if(form->name && form->namelength) { + /* Name should not contain nul bytes. */ + size_t i; + for(i = 0; i < form->namelength; i++) + if(!form->name[i]) { + return_value = CURL_FORMADD_NULL; + break; + } + if(return_value != CURL_FORMADD_OK) + break; + } if(!(form->flags & HTTPPOST_PTRNAME) && (form == first_form) ) { /* Note that there's small risk that form->name is NULL here if the app passed in a bad combo, so we better check for that first. */ if(form->name) { - /* copy name (without strdup; possibly contains null characters) */ + /* copy name (without strdup; possibly not nul-terminated) */ form->name = Curl_memdup(form->name, form->namelength? form->namelength: strlen(form->name) + 1); @@ -814,6 +825,24 @@ void curl_formfree(struct curl_httppost *form) } +/* Set mime part name, taking care of non nul-terminated name string. */ +static CURLcode setname(curl_mimepart *part, const char *name, size_t len) +{ + char *zname; + CURLcode res; + + if(!name || !len) + return curl_mime_name(part, name); + zname = malloc(len + 1); + if(!zname) + return CURLE_OUT_OF_MEMORY; + memcpy(zname, name, len); + zname[len] = '\0'; + res = curl_mime_name(part, zname); + free(zname); + return res; +} + /* * Curl_getformdata() converts a linked list of "meta data" into a mime * structure. The input list is in 'post', while the output is stored in @@ -856,8 +885,7 @@ CURLcode Curl_getformdata(struct Curl_easy *data, if(!part) result = CURLE_OUT_OF_MEMORY; if(!result) - result = curl_mime_name(part, post->name, - post->namelength? post->namelength: -1); + result = setname(part, post->name, post->namelength); if(!result) { multipart = curl_mime_init(data); if(!multipart) @@ -884,8 +912,7 @@ CURLcode Curl_getformdata(struct Curl_easy *data, /* Set field name. */ if(!result && !post->more) - result = curl_mime_name(part, post->name, - post->namelength? post->namelength: -1); + result = setname(part, post->name, post->namelength); /* Process contents. */ if(!result) { diff --git a/lib/mime.c b/lib/mime.c index 03ccfc200..496f5e6fb 100644 --- a/lib/mime.c +++ b/lib/mime.c @@ -275,33 +275,25 @@ static void mimesetstate(mime_state *state, enum mimestate tok, void *ptr) /* Escape header string into allocated memory. */ -static char *escape_string(const char *src, size_t len) +static char *escape_string(const char *src) { - size_t bytecount; + size_t bytecount = 0; size_t i; char *dst; - if(len == CURL_ZERO_TERMINATED) - len = strlen(src); - - bytecount = len; - for(i = 0; i < len; i++) - if(src[i] == '"' || src[i] == '\\' || !src[i]) + for(i = 0; src[i]; i++) + if(src[i] == '"' || src[i] == '\\') bytecount++; + bytecount += i; dst = malloc(bytecount + 1); if(!dst) return NULL; - for(i = 0; len; len--) { - char c = *src++; - - if(c == '"' || c == '\\' || !c) { + for(i = 0; *src; src++) { + if(*src == '"' || *src == '\\') dst[i++] = '\\'; - if(!c) - c = '0'; - } - dst[i++] = c; + dst[i++] = *src; } dst[i] = '\0'; @@ -1199,26 +1191,18 @@ curl_mimepart *curl_mime_addpart(curl_mime *mime) } /* Set mime part name. */ -CURLcode curl_mime_name(curl_mimepart *part, - const char *name, size_t namesize) +CURLcode curl_mime_name(curl_mimepart *part, const char *name) { if(!part) return CURLE_BAD_FUNCTION_ARGUMENT; Curl_safefree(part->name); part->name = NULL; - part->namesize = 0; if(name) { - if(namesize == CURL_ZERO_TERMINATED) - namesize = strlen(name); - part->name = malloc(namesize + 1); + part->name = strdup(name); if(!part->name) return CURLE_OUT_OF_MEMORY; - if(namesize) - memcpy(part->name, name, namesize); - part->name[namesize] = '\0'; - part->namesize = namesize; } return CURLE_OK; @@ -1656,12 +1640,12 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part, char *filename = NULL; if(part->name) { - name = escape_string(part->name, part->namesize); + name = escape_string(part->name); if(!name) ret = CURLE_OUT_OF_MEMORY; } if(!ret && part->filename) { - filename = escape_string(part->filename, CURL_ZERO_TERMINATED); + filename = escape_string(part->filename); if(!filename) ret = CURLE_OUT_OF_MEMORY; } @@ -1745,12 +1729,10 @@ curl_mimepart *curl_mime_addpart(curl_mime *mime) return NULL; } -CURLcode curl_mime_name(curl_mimepart *part, - const char *name, size_t namesize) +CURLcode curl_mime_name(curl_mimepart *part, const char *name) { (void) part; (void) name; - (void) namesize; return CURLE_NOT_BUILT_IN; } diff --git a/lib/mime.h b/lib/mime.h index f22d01352..a14485707 100644 --- a/lib/mime.h +++ b/lib/mime.h @@ -111,7 +111,6 @@ struct curl_mimepart_s { char *mimetype; /* Part mime type. */ char *filename; /* Remote file name. */ char *name; /* Data name. */ - size_t namesize; /* Data name size. */ curl_off_t datasize; /* Expected data size. */ unsigned int flags; /* Flags. */ mime_state state; /* Current readback state. */ -- cgit v1.2.3