aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPatrick Monnerat <patrick@monnerat.net>2017-09-22 01:08:29 +0100
committerPatrick Monnerat <patrick@monnerat.net>2017-09-22 01:08:29 +0100
commitee56fdb6910f6bf215eecede9e2e9bfc83cb5f29 (patch)
treebfdbf1f3f2f5cd9f051f6b8d0b2469c51b2660ef /lib
parentfa9482ab0907dfacd0fb619add2dbf41de2d8c9c (diff)
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).
Diffstat (limited to 'lib')
-rw-r--r--lib/formdata.c37
-rw-r--r--lib/mime.c44
-rw-r--r--lib/mime.h1
3 files changed, 45 insertions, 37 deletions
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. */