aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/formdata.c129
1 files changed, 102 insertions, 27 deletions
diff --git a/lib/formdata.c b/lib/formdata.c
index 160f51fbd..5d258a965 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -735,13 +735,18 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
/*
* AddFormData() adds a chunk of data to the FormData linked list.
+ *
+ * size is incremented by the chunk length, unless it is NULL
*/
-static size_t AddFormData(struct FormData **formp,
- const void *line,
- size_t length)
+static CURLcode AddFormData(struct FormData **formp,
+ const void *line,
+ size_t length,
+ size_t *size)
{
struct FormData *newform = (struct FormData *)
malloc(sizeof(struct FormData));
+ if (!newform)
+ return CURLE_OUT_OF_MEMORY;
newform->next = NULL;
/* we make it easier for plain strings: */
@@ -749,6 +754,10 @@ static size_t AddFormData(struct FormData **formp,
length = strlen((char *)line);
newform->line = (char *)malloc(length+1);
+ if (!newform->line) {
+ free(newform);
+ return CURLE_OUT_OF_MEMORY;
+ }
memcpy(newform->line, line, length);
newform->length = length;
newform->line[length]=0; /* zero terminate for easier debugging */
@@ -760,14 +769,17 @@ static size_t AddFormData(struct FormData **formp,
else
*formp = newform;
- return length;
+ if (size)
+ *size += length;
+ return CURLE_OK;
}
/*
* AddFormDataf() adds printf()-style formatted data to the formdata chain.
*/
-static size_t AddFormDataf(struct FormData **formp,
+static CURLcode AddFormDataf(struct FormData **formp,
+ size_t *size,
const char *fmt, ...)
{
char s[4096];
@@ -776,7 +788,7 @@ static size_t AddFormDataf(struct FormData **formp,
vsprintf(s, fmt, ap);
va_end(ap);
- return AddFormData(formp, s, 0);
+ return AddFormData(formp, s, 0, size);
}
/*
@@ -875,7 +887,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
struct curl_httppost *file;
CURLcode result = CURLE_OK;
- curl_off_t size =0;
+ size_t size =0;
char *boundary;
char *fileboundary=NULL;
struct curl_slist* curList;
@@ -888,28 +900,43 @@ CURLcode Curl_getFormData(struct FormData **finalform,
boundary = Curl_FormBoundary();
/* Make the first line of the output */
- AddFormDataf(&form,
+ result = AddFormDataf(&form, 0,
"Content-Type: multipart/form-data;"
" boundary=%s\r\n",
boundary);
+ if (result != CURLE_OK) {
+ free(boundary);
+ return result;
+ }
/* we DO NOT count that line since that'll be part of the header! */
firstform = form;
do {
- if(size)
- size += AddFormDataf(&form, "\r\n");
+ if(size) {
+ result = AddFormDataf(&form, &size, "\r\n");
+ if (result != CURLE_OK)
+ break;
+ }
/* boundary */
- size += AddFormDataf(&form, "--%s\r\n", boundary);
+ result = AddFormDataf(&form, &size, "--%s\r\n", boundary);
+ if (result != CURLE_OK)
+ break;
- size += AddFormData(&form,
- "Content-Disposition: form-data; name=\"", 0);
+ result = AddFormData(&form,
+ "Content-Disposition: form-data; name=\"", 0, &size);
+ if (result != CURLE_OK)
+ break;
- size += AddFormData(&form, post->name, post->namelength);
+ result = AddFormData(&form, post->name, post->namelength, &size);
+ if (result != CURLE_OK)
+ break;
- size += AddFormData(&form, "\"", 0);
+ size += AddFormData(&form, "\"", 0, &size);
+ if (result != CURLE_OK)
+ break;
if(post->more) {
/* If used, this is a link to more file names, we must then do
@@ -917,10 +944,12 @@ CURLcode Curl_getFormData(struct FormData **finalform,
fileboundary = Curl_FormBoundary();
- size += AddFormDataf(&form,
+ result = AddFormDataf(&form, &size,
"\r\nContent-Type: multipart/mixed,"
" boundary=%s\r\n",
fileboundary);
+ if (result != CURLE_OK)
+ break;
}
file = post;
@@ -933,35 +962,48 @@ CURLcode Curl_getFormData(struct FormData **finalform,
if(post->more) {
/* if multiple-file */
- size += AddFormDataf(&form,
+ result = AddFormDataf(&form, &size,
"\r\n--%s\r\nContent-Disposition: "
"attachment; filename=\"%s\"",
fileboundary,
(file->showfilename?file->showfilename:
file->contents));
+ if (result != CURLE_OK)
+ break;
}
else if((post->flags & HTTPPOST_FILENAME) ||
(post->flags & HTTPPOST_BUFFER)) {
- size += AddFormDataf(&form,
+ result = AddFormDataf(&form, &size,
"; filename=\"%s\"",
(post->showfilename?post->showfilename:
post->contents));
+ if (result != CURLE_OK)
+ break;
}
if(file->contenttype) {
/* we have a specified type */
- size += AddFormDataf(&form,
+ result = AddFormDataf(&form, &size,
"\r\nContent-Type: %s",
file->contenttype);
+ if (result != CURLE_OK)
+ break;
}
curList = file->contentheader;
while( curList ) {
/* Process the additional headers specified for this form */
- size += AddFormDataf( &form, "\r\n%s", curList->data );
+ result = AddFormDataf( &form, &size, "\r\n%s", curList->data );
+ if (result != CURLE_OK)
+ break;
curList = curList->next;
}
+ if (result != CURLE_OK) {
+ Curl_formclean(firstform);
+ free(boundary);
+ return result;
+ }
#if 0
/* The header Content-Transfer-Encoding: seems to confuse some receivers
@@ -977,7 +1019,9 @@ CURLcode Curl_getFormData(struct FormData **finalform,
}
#endif
- size += AddFormData(&form, "\r\n\r\n", 0);
+ result = AddFormData(&form, "\r\n\r\n", 0, &size);
+ if (result != CURLE_OK)
+ break;
if((post->flags & HTTPPOST_FILENAME) ||
(post->flags & HTTPPOST_READFILE)) {
@@ -995,8 +1039,16 @@ CURLcode Curl_getFormData(struct FormData **finalform,
*/
if(fileread) {
- while((nread = fread(buffer, 1, 1024, fileread)))
- size += AddFormData(&form, buffer, nread);
+ while((nread = fread(buffer, 1, 1024, fileread))) {
+ result = AddFormData(&form, buffer, nread, &size);
+ if (result != CURLE_OK)
+ break;
+ }
+ if (result != CURLE_OK) {
+ Curl_formclean(firstform);
+ free(boundary);
+ return result;
+ }
if(fileread != stdin)
fclose(fileread);
@@ -1011,30 +1063,53 @@ CURLcode Curl_getFormData(struct FormData **finalform,
}
else if (post->flags & HTTPPOST_BUFFER) {
/* include contents of buffer */
- size += AddFormData(&form, post->buffer, post->bufferlength);
+ result = AddFormData(&form, post->buffer, post->bufferlength,
+ &size);
+ if (result != CURLE_OK)
+ break;
}
else {
/* include the contents we got */
- size += AddFormData(&form, post->contents, post->contentslength);
+ result = AddFormData(&form, post->contents, post->contentslength,
+ &size);
+ if (result != CURLE_OK)
+ break;
}
} while((file = file->more)); /* for each specified file for this field */
+ if (result != CURLE_OK) {
+ Curl_formclean(firstform);
+ free(boundary);
+ return result;
+ }
if(post->more) {
/* this was a multiple-file inclusion, make a termination file
boundary: */
- size += AddFormDataf(&form,
+ result = AddFormDataf(&form, &size,
"\r\n--%s--",
fileboundary);
free(fileboundary);
+ if (result != CURLE_OK)
+ break;
}
} while((post=post->next)); /* for each field */
+ if (result != CURLE_OK) {
+ Curl_formclean(firstform);
+ free(boundary);
+ return result;
+ }
/* end-boundary for everything */
- size += AddFormDataf(&form,
+ result = AddFormDataf(&form, &size,
"\r\n--%s--\r\n",
boundary);
+ if (result != CURLE_OK) {
+ Curl_formclean(firstform);
+ free(boundary);
+ return result;
+ }
*sizep = size;