summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/formdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/formdata.c')
-rw-r--r--libs/libcurl/src/formdata.c648
1 files changed, 314 insertions, 334 deletions
diff --git a/libs/libcurl/src/formdata.c b/libs/libcurl/src/formdata.c
index 2f45376413..1105bba8e2 100644
--- a/libs/libcurl/src/formdata.c
+++ b/libs/libcurl/src/formdata.c
@@ -31,10 +31,6 @@ struct Curl_easy;
#include "formdata.h"
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_FORM_API)
-#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
-#include <libgen.h>
-#endif
-
#include "urldata.h" /* for struct Curl_easy */
#include "mime.h"
#include "vtls/vtls.h"
@@ -42,7 +38,7 @@ struct Curl_easy;
#include "sendf.h"
#include "strdup.h"
#include "rand.h"
-#include "warnless.h"
+#include "curlx/warnless.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -68,36 +64,31 @@ struct Curl_easy;
*
***************************************************************************/
static struct curl_httppost *
-AddHttpPost(char *name, size_t namelength,
- char *value, curl_off_t contentslength,
- char *buffer, size_t bufferlength,
- char *contenttype,
- long flags,
- struct curl_slist *contentHeader,
- char *showfilename, char *userp,
+AddHttpPost(struct FormInfo *src,
struct curl_httppost *parent_post,
struct curl_httppost **httppost,
struct curl_httppost **last_post)
{
struct curl_httppost *post;
- if(!namelength && name)
- namelength = strlen(name);
- if((bufferlength > LONG_MAX) || (namelength > LONG_MAX))
+ size_t namelength = src->namelength;
+ if(!namelength && src->name)
+ namelength = strlen(src->name);
+ if((src->bufferlength > LONG_MAX) || (namelength > LONG_MAX))
/* avoid overflow in typecasts below */
return NULL;
post = calloc(1, sizeof(struct curl_httppost));
if(post) {
- post->name = name;
+ post->name = src->name;
post->namelength = (long)namelength;
- post->contents = value;
- post->contentlen = contentslength;
- post->buffer = buffer;
- post->bufferlength = (long)bufferlength;
- post->contenttype = contenttype;
- post->contentheader = contentHeader;
- post->showfilename = showfilename;
- post->userp = userp;
- post->flags = flags | CURL_HTTPPOST_LARGE;
+ post->contents = src->value;
+ post->contentlen = src->contentslength;
+ post->buffer = src->buffer;
+ post->bufferlength = (long)src->bufferlength;
+ post->contenttype = src->contenttype;
+ post->flags = src->flags | CURL_HTTPPOST_LARGE;
+ post->contentheader = src->contentheader;
+ post->showfilename = src->showfilename;
+ post->userp = src->userp;
}
else
return NULL;
@@ -156,6 +147,28 @@ static struct FormInfo *AddFormInfo(char *value,
return form_info;
}
+static void free_formlist(struct FormInfo *ptr)
+{
+ for(; ptr != NULL; ptr = ptr->more) {
+ if(ptr->name_alloc) {
+ Curl_safefree(ptr->name);
+ ptr->name_alloc = FALSE;
+ }
+ if(ptr->value_alloc) {
+ Curl_safefree(ptr->value);
+ ptr->value_alloc = FALSE;
+ }
+ if(ptr->contenttype_alloc) {
+ Curl_safefree(ptr->contenttype);
+ ptr->contenttype_alloc = FALSE;
+ }
+ if(ptr->showfilename_alloc) {
+ Curl_safefree(ptr->showfilename);
+ ptr->showfilename_alloc = FALSE;
+ }
+ }
+}
+
/***************************************************************************
*
* FormAdd()
@@ -205,18 +218,123 @@ static struct FormInfo *AddFormInfo(char *value,
*
***************************************************************************/
+static CURLFORMcode FormAddCheck(struct FormInfo *first_form,
+ struct curl_httppost **httppost,
+ struct curl_httppost **last_post)
+{
+ const char *prevtype = NULL;
+ struct FormInfo *form = NULL;
+ struct curl_httppost *post = NULL;
+
+ /* go through the list, check for completeness and if everything is
+ * alright add the HttpPost item otherwise set retval accordingly */
+
+ for(form = first_form;
+ form != NULL;
+ form = form->more) {
+ if(((!form->name || !form->value) && !post) ||
+ ( (form->contentslength) &&
+ (form->flags & HTTPPOST_FILENAME) ) ||
+ ( (form->flags & HTTPPOST_FILENAME) &&
+ (form->flags & HTTPPOST_PTRCONTENTS) ) ||
+
+ ( (!form->buffer) &&
+ (form->flags & HTTPPOST_BUFFER) &&
+ (form->flags & HTTPPOST_PTRBUFFER) ) ||
+
+ ( (form->flags & HTTPPOST_READFILE) &&
+ (form->flags & HTTPPOST_PTRCONTENTS) )
+ ) {
+ return CURL_FORMADD_INCOMPLETE;
+ }
+ if(((form->flags & HTTPPOST_FILENAME) ||
+ (form->flags & HTTPPOST_BUFFER)) &&
+ !form->contenttype) {
+ char *f = (form->flags & HTTPPOST_BUFFER) ?
+ form->showfilename : form->value;
+ char const *type;
+ type = Curl_mime_contenttype(f);
+ if(!type)
+ type = prevtype;
+ if(!type)
+ type = FILE_CONTENTTYPE_DEFAULT;
+
+ /* our contenttype is missing */
+ form->contenttype = strdup(type);
+ if(!form->contenttype)
+ return CURL_FORMADD_MEMORY;
+
+ form->contenttype_alloc = TRUE;
+ }
+ if(form->name && form->namelength) {
+ if(memchr(form->name, 0, form->namelength))
+ return CURL_FORMADD_NULL;
+ }
+ if(!(form->flags & HTTPPOST_PTRNAME) && form->name) {
+ /* Note that there is small risk that form->name is NULL here if the app
+ passed in a bad combo, so we check for that. */
+
+ /* copy name (without strdup; possibly not null-terminated) */
+ char *dupname = Curl_memdup0(form->name, form->namelength ?
+ form->namelength : strlen(form->name));
+ if(!dupname)
+ return CURL_FORMADD_MEMORY;
+
+ form->name = dupname;
+ form->name_alloc = TRUE;
+ }
+ if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
+ HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
+ HTTPPOST_CALLBACK)) && form->value) {
+ /* copy value (without strdup; possibly contains null characters) */
+ size_t clen = (size_t) form->contentslength;
+ if(!clen)
+ clen = strlen(form->value) + 1;
+
+ form->value = Curl_memdup(form->value, clen);
+
+ if(!form->value)
+ return CURL_FORMADD_MEMORY;
+
+ form->value_alloc = TRUE;
+ }
+ post = AddHttpPost(form, post, httppost, last_post);
+
+ if(!post)
+ return CURL_FORMADD_MEMORY;
+
+ if(form->contenttype)
+ prevtype = form->contenttype;
+ }
+
+ return CURL_FORMADD_OK;
+}
+
+/* Shallow cleanup. Remove the newly created chain, the structs only and not
+ the content they point to */
+static void free_chain(struct curl_httppost *c)
+{
+ while(c) {
+ struct curl_httppost *next = c->next;
+ if(c->more)
+ free_chain(c->more);
+ free(c);
+ c = next;
+ }
+}
+
static
CURLFORMcode FormAdd(struct curl_httppost **httppost,
struct curl_httppost **last_post,
va_list params)
{
- struct FormInfo *first_form, *current_form, *form = NULL;
- CURLFORMcode return_value = CURL_FORMADD_OK;
- const char *prevtype = NULL;
- struct curl_httppost *post = NULL;
+ struct FormInfo *first_form, *curr, *form = NULL;
+ CURLFORMcode retval = CURL_FORMADD_OK;
CURLformoption option;
struct curl_forms *forms = NULL;
- char *array_value = NULL; /* value read from an array */
+ char *avalue = NULL;
+ struct curl_httppost *newchain = NULL;
+ struct curl_httppost *lastnode = NULL;
/* This is a state variable, that if TRUE means that we are parsing an
array that we got passed to us. If FALSE we are parsing the input
@@ -230,18 +348,18 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(!first_form)
return CURL_FORMADD_MEMORY;
- current_form = first_form;
+ curr = first_form;
/*
* Loop through all the options set. Break if we have an error to report.
*/
- while(return_value == CURL_FORMADD_OK) {
+ while(retval == CURL_FORMADD_OK) {
/* first see if we have more parts of the array param */
if(array_state && forms) {
/* get the upcoming option from the given array */
option = forms->option;
- array_value = (char *)forms->value;
+ avalue = (char *)CURL_UNCONST(forms->value);
forms++; /* advance this to next entry */
if(CURLFORM_END == option) {
@@ -263,13 +381,13 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
case CURLFORM_ARRAY:
if(array_state)
/* we do not support an array from within an array */
- return_value = CURL_FORMADD_ILLEGAL_ARRAY;
+ retval = CURL_FORMADD_ILLEGAL_ARRAY;
else {
forms = va_arg(params, struct curl_forms *);
if(forms)
array_state = TRUE;
else
- return_value = CURL_FORMADD_NULL;
+ retval = CURL_FORMADD_NULL;
}
break;
@@ -277,403 +395,253 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
* Set the Name property.
*/
case CURLFORM_PTRNAME:
- current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
+ curr->flags |= HTTPPOST_PTRNAME; /* fall through */
FALLTHROUGH();
case CURLFORM_COPYNAME:
- if(current_form->name)
- return_value = CURL_FORMADD_OPTION_TWICE;
+ if(curr->name)
+ retval = CURL_FORMADD_OPTION_TWICE;
else {
- char *name = array_state ?
- array_value : va_arg(params, char *);
- if(name)
- current_form->name = name; /* store for the moment */
+ if(!array_state)
+ avalue = va_arg(params, char *);
+ if(avalue)
+ curr->name = avalue; /* store for the moment */
else
- return_value = CURL_FORMADD_NULL;
+ retval = CURL_FORMADD_NULL;
}
break;
case CURLFORM_NAMELENGTH:
- if(current_form->namelength)
- return_value = CURL_FORMADD_OPTION_TWICE;
+ if(curr->namelength)
+ retval = CURL_FORMADD_OPTION_TWICE;
else
- current_form->namelength =
- array_state ? (size_t)array_value : (size_t)va_arg(params, long);
+ curr->namelength =
+ array_state ? (size_t)avalue : (size_t)va_arg(params, long);
break;
/*
* Set the contents property.
*/
case CURLFORM_PTRCONTENTS:
- current_form->flags |= HTTPPOST_PTRCONTENTS;
+ curr->flags |= HTTPPOST_PTRCONTENTS;
FALLTHROUGH();
case CURLFORM_COPYCONTENTS:
- if(current_form->value)
- return_value = CURL_FORMADD_OPTION_TWICE;
+ if(curr->value)
+ retval = CURL_FORMADD_OPTION_TWICE;
else {
- char *value =
- array_state ? array_value : va_arg(params, char *);
- if(value)
- current_form->value = value; /* store for the moment */
+ if(!array_state)
+ avalue = va_arg(params, char *);
+ if(avalue)
+ curr->value = avalue; /* store for the moment */
else
- return_value = CURL_FORMADD_NULL;
+ retval = CURL_FORMADD_NULL;
}
break;
case CURLFORM_CONTENTSLENGTH:
- current_form->contentslength =
- array_state ? (size_t)array_value : (size_t)va_arg(params, long);
+ curr->contentslength =
+ array_state ? (size_t)avalue : (size_t)va_arg(params, long);
break;
case CURLFORM_CONTENTLEN:
- current_form->flags |= CURL_HTTPPOST_LARGE;
- current_form->contentslength =
- array_state ? (curl_off_t)(size_t)array_value :
+ curr->flags |= CURL_HTTPPOST_LARGE;
+ curr->contentslength =
+ array_state ? (curl_off_t)(size_t)avalue :
va_arg(params, curl_off_t);
break;
/* Get contents from a given filename */
case CURLFORM_FILECONTENT:
- if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
- return_value = CURL_FORMADD_OPTION_TWICE;
+ if(curr->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
+ retval = CURL_FORMADD_OPTION_TWICE;
else {
- const char *filename = array_state ?
- array_value : va_arg(params, char *);
- if(filename) {
- current_form->value = strdup(filename);
- if(!current_form->value)
- return_value = CURL_FORMADD_MEMORY;
+ if(!array_state)
+ avalue = va_arg(params, char *);
+ if(avalue) {
+ curr->value = strdup(avalue);
+ if(!curr->value)
+ retval = CURL_FORMADD_MEMORY;
else {
- current_form->flags |= HTTPPOST_READFILE;
- current_form->value_alloc = TRUE;
+ curr->flags |= HTTPPOST_READFILE;
+ curr->value_alloc = TRUE;
}
}
else
- return_value = CURL_FORMADD_NULL;
+ retval = CURL_FORMADD_NULL;
}
break;
/* We upload a file */
case CURLFORM_FILE:
- {
- const char *filename = array_state ? array_value :
- va_arg(params, char *);
-
- if(current_form->value) {
- if(current_form->flags & HTTPPOST_FILENAME) {
- if(filename) {
- char *fname = strdup(filename);
- if(!fname)
- return_value = CURL_FORMADD_MEMORY;
+ if(!array_state)
+ avalue = va_arg(params, char *);
+
+ if(curr->value) {
+ if(curr->flags & HTTPPOST_FILENAME) {
+ if(avalue) {
+ char *fname = strdup(avalue);
+ if(!fname)
+ retval = CURL_FORMADD_MEMORY;
+ else {
+ form = AddFormInfo(fname, NULL, curr);
+ if(!form) {
+ free(fname);
+ retval = CURL_FORMADD_MEMORY;
+ }
else {
- form = AddFormInfo(fname, NULL, current_form);
- if(!form) {
- free(fname);
- return_value = CURL_FORMADD_MEMORY;
- }
- else {
- form->value_alloc = TRUE;
- current_form = form;
- form = NULL;
- }
+ form->value_alloc = TRUE;
+ curr = form;
+ form = NULL;
}
}
- else
- return_value = CURL_FORMADD_NULL;
}
else
- return_value = CURL_FORMADD_OPTION_TWICE;
+ retval = CURL_FORMADD_NULL;
}
- else {
- if(filename) {
- current_form->value = strdup(filename);
- if(!current_form->value)
- return_value = CURL_FORMADD_MEMORY;
- else {
- current_form->flags |= HTTPPOST_FILENAME;
- current_form->value_alloc = TRUE;
- }
+ else
+ retval = CURL_FORMADD_OPTION_TWICE;
+ }
+ else {
+ if(avalue) {
+ curr->value = strdup(avalue);
+ if(!curr->value)
+ retval = CURL_FORMADD_MEMORY;
+ else {
+ curr->flags |= HTTPPOST_FILENAME;
+ curr->value_alloc = TRUE;
}
- else
- return_value = CURL_FORMADD_NULL;
}
- break;
+ else
+ retval = CURL_FORMADD_NULL;
}
+ break;
case CURLFORM_BUFFERPTR:
- current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
- if(current_form->buffer)
- return_value = CURL_FORMADD_OPTION_TWICE;
+ curr->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
+ if(curr->buffer)
+ retval = CURL_FORMADD_OPTION_TWICE;
else {
- char *buffer =
- array_state ? array_value : va_arg(params, char *);
- if(buffer) {
- current_form->buffer = buffer; /* store for the moment */
- current_form->value = buffer; /* make it non-NULL to be accepted
+ if(!array_state)
+ avalue = va_arg(params, char *);
+ if(avalue) {
+ curr->buffer = avalue; /* store for the moment */
+ curr->value = avalue; /* make it non-NULL to be accepted
as fine */
}
else
- return_value = CURL_FORMADD_NULL;
+ retval = CURL_FORMADD_NULL;
}
break;
case CURLFORM_BUFFERLENGTH:
- if(current_form->bufferlength)
- return_value = CURL_FORMADD_OPTION_TWICE;
+ if(curr->bufferlength)
+ retval = CURL_FORMADD_OPTION_TWICE;
else
- current_form->bufferlength =
- array_state ? (size_t)array_value : (size_t)va_arg(params, long);
+ curr->bufferlength =
+ array_state ? (size_t)avalue : (size_t)va_arg(params, long);
break;
case CURLFORM_STREAM:
- current_form->flags |= HTTPPOST_CALLBACK;
- if(current_form->userp)
- return_value = CURL_FORMADD_OPTION_TWICE;
+ curr->flags |= HTTPPOST_CALLBACK;
+ if(curr->userp)
+ retval = CURL_FORMADD_OPTION_TWICE;
else {
- char *userp =
- array_state ? array_value : va_arg(params, char *);
- if(userp) {
- current_form->userp = userp;
- current_form->value = userp; /* this is not strictly true but we
- derive a value from this later on
- and we need this non-NULL to be
- accepted as a fine form part */
+ if(!array_state)
+ avalue = va_arg(params, char *);
+ if(avalue) {
+ curr->userp = avalue;
+ curr->value = avalue; /* this is not strictly true but we derive a
+ value from this later on and we need this
+ non-NULL to be accepted as a fine form
+ part */
}
else
- return_value = CURL_FORMADD_NULL;
+ retval = CURL_FORMADD_NULL;
}
break;
case CURLFORM_CONTENTTYPE:
- {
- const char *contenttype =
- array_state ? array_value : va_arg(params, char *);
- if(current_form->contenttype) {
- if(current_form->flags & HTTPPOST_FILENAME) {
- if(contenttype) {
- char *type = strdup(contenttype);
- if(!type)
- return_value = CURL_FORMADD_MEMORY;
+ if(!array_state)
+ avalue = va_arg(params, char *);
+ if(curr->contenttype) {
+ if(curr->flags & HTTPPOST_FILENAME) {
+ if(avalue) {
+ char *type = strdup(avalue);
+ if(!type)
+ retval = CURL_FORMADD_MEMORY;
+ else {
+ form = AddFormInfo(NULL, type, curr);
+ if(!form) {
+ free(type);
+ retval = CURL_FORMADD_MEMORY;
+ }
else {
- form = AddFormInfo(NULL, type, current_form);
- if(!form) {
- free(type);
- return_value = CURL_FORMADD_MEMORY;
- }
- else {
- form->contenttype_alloc = TRUE;
- current_form = form;
- form = NULL;
- }
+ form->contenttype_alloc = TRUE;
+ curr = form;
+ form = NULL;
}
}
- else
- return_value = CURL_FORMADD_NULL;
}
else
- return_value = CURL_FORMADD_OPTION_TWICE;
+ retval = CURL_FORMADD_NULL;
}
- else {
- if(contenttype) {
- current_form->contenttype = strdup(contenttype);
- if(!current_form->contenttype)
- return_value = CURL_FORMADD_MEMORY;
- else
- current_form->contenttype_alloc = TRUE;
- }
+ else
+ retval = CURL_FORMADD_OPTION_TWICE;
+ }
+ else {
+ if(avalue) {
+ curr->contenttype = strdup(avalue);
+ if(!curr->contenttype)
+ retval = CURL_FORMADD_MEMORY;
else
- return_value = CURL_FORMADD_NULL;
+ curr->contenttype_alloc = TRUE;
}
- break;
+ else
+ retval = CURL_FORMADD_NULL;
}
+ break;
+
case CURLFORM_CONTENTHEADER:
{
/* this "cast increases required alignment of target type" but
we consider it OK anyway */
struct curl_slist *list = array_state ?
- (struct curl_slist *)(void *)array_value :
+ (struct curl_slist *)(void *)avalue :
va_arg(params, struct curl_slist *);
- if(current_form->contentheader)
- return_value = CURL_FORMADD_OPTION_TWICE;
+ if(curr->contentheader)
+ retval = CURL_FORMADD_OPTION_TWICE;
else
- current_form->contentheader = list;
+ curr->contentheader = list;
break;
}
case CURLFORM_FILENAME:
case CURLFORM_BUFFER:
- {
- const char *filename = array_state ? array_value :
- va_arg(params, char *);
- if(current_form->showfilename)
- return_value = CURL_FORMADD_OPTION_TWICE;
- else {
- current_form->showfilename = strdup(filename);
- if(!current_form->showfilename)
- return_value = CURL_FORMADD_MEMORY;
- else
- current_form->showfilename_alloc = TRUE;
- }
- break;
+ if(!array_state)
+ avalue = va_arg(params, char *);
+ if(curr->showfilename)
+ retval = CURL_FORMADD_OPTION_TWICE;
+ else {
+ curr->showfilename = strdup(avalue);
+ if(!curr->showfilename)
+ retval = CURL_FORMADD_MEMORY;
+ else
+ curr->showfilename_alloc = TRUE;
}
+ break;
+
default:
- return_value = CURL_FORMADD_UNKNOWN_OPTION;
+ retval = CURL_FORMADD_UNKNOWN_OPTION;
break;
}
}
- if(CURL_FORMADD_OK != return_value) {
+ if(!retval)
+ retval = FormAddCheck(first_form, &newchain, &lastnode);
+
+ if(retval)
/* On error, free allocated fields for all nodes of the FormInfo linked
list without deallocating nodes. List nodes are deallocated later on */
- struct FormInfo *ptr;
- for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
- if(ptr->name_alloc) {
- Curl_safefree(ptr->name);
- ptr->name_alloc = FALSE;
- }
- if(ptr->value_alloc) {
- Curl_safefree(ptr->value);
- ptr->value_alloc = FALSE;
- }
- if(ptr->contenttype_alloc) {
- Curl_safefree(ptr->contenttype);
- ptr->contenttype_alloc = FALSE;
- }
- if(ptr->showfilename_alloc) {
- Curl_safefree(ptr->showfilename);
- ptr->showfilename_alloc = FALSE;
- }
- }
- }
-
- if(CURL_FORMADD_OK == return_value) {
- /* go through the list, check for completeness and if everything is
- * alright add the HttpPost item otherwise set return_value accordingly */
-
- post = NULL;
- for(form = first_form;
- form != NULL;
- form = form->more) {
- if(((!form->name || !form->value) && !post) ||
- ( (form->contentslength) &&
- (form->flags & HTTPPOST_FILENAME) ) ||
- ( (form->flags & HTTPPOST_FILENAME) &&
- (form->flags & HTTPPOST_PTRCONTENTS) ) ||
-
- ( (!form->buffer) &&
- (form->flags & HTTPPOST_BUFFER) &&
- (form->flags & HTTPPOST_PTRBUFFER) ) ||
-
- ( (form->flags & HTTPPOST_READFILE) &&
- (form->flags & HTTPPOST_PTRCONTENTS) )
- ) {
- return_value = CURL_FORMADD_INCOMPLETE;
- break;
- }
- if(((form->flags & HTTPPOST_FILENAME) ||
- (form->flags & HTTPPOST_BUFFER)) &&
- !form->contenttype) {
- char *f = (form->flags & HTTPPOST_BUFFER) ?
- form->showfilename : form->value;
- char const *type;
- type = Curl_mime_contenttype(f);
- if(!type)
- type = prevtype;
- if(!type)
- type = FILE_CONTENTTYPE_DEFAULT;
-
- /* our contenttype is missing */
- form->contenttype = strdup(type);
- if(!form->contenttype) {
- return_value = CURL_FORMADD_MEMORY;
- break;
- }
- 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 is 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 not null-terminated) */
- form->name = Curl_memdup0(form->name, form->namelength ?
- form->namelength :
- strlen(form->name));
- }
- if(!form->name) {
- return_value = CURL_FORMADD_MEMORY;
- break;
- }
- form->name_alloc = TRUE;
- }
- if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
- HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
- HTTPPOST_CALLBACK)) && form->value) {
- /* copy value (without strdup; possibly contains null characters) */
- size_t clen = (size_t) form->contentslength;
- if(!clen)
- clen = strlen(form->value) + 1;
-
- form->value = Curl_memdup(form->value, clen);
-
- if(!form->value) {
- return_value = CURL_FORMADD_MEMORY;
- break;
- }
- form->value_alloc = TRUE;
- }
- post = AddHttpPost(form->name, form->namelength,
- form->value, form->contentslength,
- form->buffer, form->bufferlength,
- form->contenttype, form->flags,
- form->contentheader, form->showfilename,
- form->userp,
- post, httppost,
- last_post);
-
- if(!post) {
- return_value = CURL_FORMADD_MEMORY;
- break;
- }
-
- if(form->contenttype)
- prevtype = form->contenttype;
- }
- if(CURL_FORMADD_OK != return_value) {
- /* On error, free allocated fields for nodes of the FormInfo linked
- list which are not already owned by the httppost linked list
- without deallocating nodes. List nodes are deallocated later on */
- struct FormInfo *ptr;
- for(ptr = form; ptr != NULL; ptr = ptr->more) {
- if(ptr->name_alloc) {
- Curl_safefree(ptr->name);
- ptr->name_alloc = FALSE;
- }
- if(ptr->value_alloc) {
- Curl_safefree(ptr->value);
- ptr->value_alloc = FALSE;
- }
- if(ptr->contenttype_alloc) {
- Curl_safefree(ptr->contenttype);
- ptr->contenttype_alloc = FALSE;
- }
- if(ptr->showfilename_alloc) {
- Curl_safefree(ptr->showfilename);
- ptr->showfilename_alloc = FALSE;
- }
- }
- }
- }
+ free_formlist(first_form);
/* Always deallocate FormInfo linked list nodes without touching node
fields given that these have either been deallocated or are owned
@@ -684,7 +652,19 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
first_form = ptr;
}
- return return_value;
+ if(!retval) {
+ /* Only if all is fine, link the new chain into the provided list */
+ if(*last_post)
+ (*last_post)->next = newchain;
+ else
+ (*httppost) = newchain;
+
+ (*last_post) = lastnode;
+ }
+ else
+ free_chain(newchain);
+
+ return retval;
}
/*
@@ -793,7 +773,7 @@ static CURLcode setname(curl_mimepart *part, const char *name, size_t len)
/* wrap call to fseeko so it matches the calling convention of callback */
static int fseeko_wrapper(void *stream, curl_off_t offset, int whence)
{
-#if defined(HAVE__FSEEKI64)
+#if defined(_WIN32) && defined(USE_WIN32_LARGE_FILES)
return _fseeki64(stream, (__int64)offset, whence);
#elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO)
return fseeko(stream, (off_t)offset, whence);