formdata: cleanups

- use memchr() instead of for() loop
- add and use free_formlist() instead of duplicate code
- shorten some variable names
- reduce flag struct field from 'long' to 'unsigned char'
- pass in struct pointer, not individual fields, to addhttppost()

Closes #17370
This commit is contained in:
Daniel Stenberg 2025-05-16 23:18:34 +02:00
parent 30e40c1a11
commit c26da713e7
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 243 additions and 276 deletions

View File

@ -64,36 +64,31 @@ struct Curl_easy;
* *
***************************************************************************/ ***************************************************************************/
static struct curl_httppost * static struct curl_httppost *
AddHttpPost(char *name, size_t namelength, AddHttpPost(struct FormInfo *src,
char *value, curl_off_t contentslength,
char *buffer, size_t bufferlength,
char *contenttype,
long flags,
struct curl_slist *contentHeader,
char *showfilename, char *userp,
struct curl_httppost *parent_post, struct curl_httppost *parent_post,
struct curl_httppost **httppost, struct curl_httppost **httppost,
struct curl_httppost **last_post) struct curl_httppost **last_post)
{ {
struct curl_httppost *post; struct curl_httppost *post;
if(!namelength && name) size_t namelength = src->namelength;
namelength = strlen(name); if(!namelength && src->name)
if((bufferlength > LONG_MAX) || (namelength > LONG_MAX)) namelength = strlen(src->name);
if((src->bufferlength > LONG_MAX) || (namelength > LONG_MAX))
/* avoid overflow in typecasts below */ /* avoid overflow in typecasts below */
return NULL; return NULL;
post = calloc(1, sizeof(struct curl_httppost)); post = calloc(1, sizeof(struct curl_httppost));
if(post) { if(post) {
post->name = name; post->name = src->name;
post->namelength = (long)namelength; post->namelength = (long)namelength;
post->contents = value; post->contents = src->value;
post->contentlen = contentslength; post->contentlen = src->contentslength;
post->buffer = buffer; post->buffer = src->buffer;
post->bufferlength = (long)bufferlength; post->bufferlength = (long)src->bufferlength;
post->contenttype = contenttype; post->contenttype = src->contenttype;
post->contentheader = contentHeader; post->flags = src->flags | CURL_HTTPPOST_LARGE;
post->showfilename = showfilename; post->contentheader = src->contentheader;
post->userp = userp; post->showfilename = src->showfilename;
post->flags = flags | CURL_HTTPPOST_LARGE; post->userp = src->userp;
} }
else else
return NULL; return NULL;
@ -152,6 +147,28 @@ static struct FormInfo *AddFormInfo(char *value,
return form_info; 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() * FormAdd()
@ -206,12 +223,11 @@ static CURLFORMcode FormAddCheck(struct FormInfo *first_form,
struct curl_httppost **last_post) struct curl_httppost **last_post)
{ {
const char *prevtype = NULL; const char *prevtype = NULL;
CURLFORMcode return_value = CURL_FORMADD_OK;
struct FormInfo *form = NULL; struct FormInfo *form = NULL;
struct curl_httppost *post = NULL; struct curl_httppost *post = NULL;
/* go through the list, check for completeness and if everything is /* go through the list, check for completeness and if everything is
* alright add the HttpPost item otherwise set return_value accordingly */ * alright add the HttpPost item otherwise set retval accordingly */
for(form = first_form; for(form = first_form;
form != NULL; form != NULL;
@ -229,8 +245,7 @@ static CURLFORMcode FormAddCheck(struct FormInfo *first_form,
( (form->flags & HTTPPOST_READFILE) && ( (form->flags & HTTPPOST_READFILE) &&
(form->flags & HTTPPOST_PTRCONTENTS) ) (form->flags & HTTPPOST_PTRCONTENTS) )
) { ) {
return_value = CURL_FORMADD_INCOMPLETE; return CURL_FORMADD_INCOMPLETE;
break;
} }
if(((form->flags & HTTPPOST_FILENAME) || if(((form->flags & HTTPPOST_FILENAME) ||
(form->flags & HTTPPOST_BUFFER)) && (form->flags & HTTPPOST_BUFFER)) &&
@ -246,37 +261,26 @@ static CURLFORMcode FormAddCheck(struct FormInfo *first_form,
/* our contenttype is missing */ /* our contenttype is missing */
form->contenttype = strdup(type); form->contenttype = strdup(type);
if(!form->contenttype) { if(!form->contenttype)
return_value = CURL_FORMADD_MEMORY; return CURL_FORMADD_MEMORY;
break;
}
form->contenttype_alloc = TRUE; form->contenttype_alloc = TRUE;
} }
if(form->name && form->namelength) { if(form->name && form->namelength) {
/* Name should not contain nul bytes. */ if(memchr(form->name, 0, form->namelength))
size_t i; return CURL_FORMADD_NULL;
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) && if(!(form->flags & HTTPPOST_PTRNAME) && form->name) {
(form == first_form) ) { /* Note that there is small risk that form->name is NULL here if the app
/* Note that there is small risk that form->name is NULL here if the passed in a bad combo, so we check for that. */
app passed in a bad combo, so we better check for that first. */
if(form->name) { /* copy name (without strdup; possibly not null-terminated) */
/* copy name (without strdup; possibly not null-terminated) */ char *dupname = Curl_memdup0(form->name, form->namelength ?
form->name = Curl_memdup0(form->name, form->namelength ? form->namelength : strlen(form->name));
form->namelength : if(!dupname)
strlen(form->name)); return CURL_FORMADD_MEMORY;
}
if(!form->name) { form->name = dupname;
return_value = CURL_FORMADD_MEMORY;
break;
}
form->name_alloc = TRUE; form->name_alloc = TRUE;
} }
if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE | if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
@ -289,54 +293,21 @@ static CURLFORMcode FormAddCheck(struct FormInfo *first_form,
form->value = Curl_memdup(form->value, clen); form->value = Curl_memdup(form->value, clen);
if(!form->value) { if(!form->value)
return_value = CURL_FORMADD_MEMORY; return CURL_FORMADD_MEMORY;
break;
}
form->value_alloc = TRUE; form->value_alloc = TRUE;
} }
post = AddHttpPost(form->name, form->namelength, post = AddHttpPost(form, post, httppost, last_post);
form->value, form->contentslength,
form->buffer, form->bufferlength,
form->contenttype, form->flags,
form->contentheader, form->showfilename,
form->userp,
post, httppost,
last_post);
if(!post) { if(!post)
return_value = CURL_FORMADD_MEMORY; return CURL_FORMADD_MEMORY;
break;
}
if(form->contenttype) if(form->contenttype)
prevtype = form->contenttype; prevtype = form->contenttype;
} }
if(CURL_FORMADD_OK != return_value) {
/* On error, free allocated fields for nodes of the FormInfo linked return CURL_FORMADD_OK;
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;
}
}
}
return return_value;
} }
static static
@ -344,11 +315,13 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
struct curl_httppost **last_post, struct curl_httppost **last_post,
va_list params) va_list params)
{ {
struct FormInfo *first_form, *current_form, *form = NULL; struct FormInfo *first_form, *curr, *form = NULL;
CURLFORMcode return_value = CURL_FORMADD_OK; CURLFORMcode retval = CURL_FORMADD_OK;
CURLformoption option; CURLformoption option;
struct curl_forms *forms = NULL; 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 /* 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 array that we got passed to us. If FALSE we are parsing the input
@ -362,18 +335,18 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(!first_form) if(!first_form)
return CURL_FORMADD_MEMORY; 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. * 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 */ /* first see if we have more parts of the array param */
if(array_state && forms) { if(array_state && forms) {
/* get the upcoming option from the given array */ /* get the upcoming option from the given array */
option = forms->option; option = forms->option;
array_value = (char *)CURL_UNCONST(forms->value); avalue = (char *)CURL_UNCONST(forms->value);
forms++; /* advance this to next entry */ forms++; /* advance this to next entry */
if(CURLFORM_END == option) { if(CURLFORM_END == option) {
@ -395,13 +368,13 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
case CURLFORM_ARRAY: case CURLFORM_ARRAY:
if(array_state) if(array_state)
/* we do not support an array from within an array */ /* we do not support an array from within an array */
return_value = CURL_FORMADD_ILLEGAL_ARRAY; retval = CURL_FORMADD_ILLEGAL_ARRAY;
else { else {
forms = va_arg(params, struct curl_forms *); forms = va_arg(params, struct curl_forms *);
if(forms) if(forms)
array_state = TRUE; array_state = TRUE;
else else
return_value = CURL_FORMADD_NULL; retval = CURL_FORMADD_NULL;
} }
break; break;
@ -409,277 +382,253 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
* Set the Name property. * Set the Name property.
*/ */
case CURLFORM_PTRNAME: case CURLFORM_PTRNAME:
current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ curr->flags |= HTTPPOST_PTRNAME; /* fall through */
FALLTHROUGH(); FALLTHROUGH();
case CURLFORM_COPYNAME: case CURLFORM_COPYNAME:
if(current_form->name) if(curr->name)
return_value = CURL_FORMADD_OPTION_TWICE; retval = CURL_FORMADD_OPTION_TWICE;
else { else {
char *name = array_state ? if(!array_state)
array_value : va_arg(params, char *); avalue = va_arg(params, char *);
if(name) if(avalue)
current_form->name = name; /* store for the moment */ curr->name = avalue; /* store for the moment */
else else
return_value = CURL_FORMADD_NULL; retval = CURL_FORMADD_NULL;
} }
break; break;
case CURLFORM_NAMELENGTH: case CURLFORM_NAMELENGTH:
if(current_form->namelength) if(curr->namelength)
return_value = CURL_FORMADD_OPTION_TWICE; retval = CURL_FORMADD_OPTION_TWICE;
else else
current_form->namelength = curr->namelength =
array_state ? (size_t)array_value : (size_t)va_arg(params, long); array_state ? (size_t)avalue : (size_t)va_arg(params, long);
break; break;
/* /*
* Set the contents property. * Set the contents property.
*/ */
case CURLFORM_PTRCONTENTS: case CURLFORM_PTRCONTENTS:
current_form->flags |= HTTPPOST_PTRCONTENTS; curr->flags |= HTTPPOST_PTRCONTENTS;
FALLTHROUGH(); FALLTHROUGH();
case CURLFORM_COPYCONTENTS: case CURLFORM_COPYCONTENTS:
if(current_form->value) if(curr->value)
return_value = CURL_FORMADD_OPTION_TWICE; retval = CURL_FORMADD_OPTION_TWICE;
else { else {
char *value = if(!array_state)
array_state ? array_value : va_arg(params, char *); avalue = va_arg(params, char *);
if(value) if(avalue)
current_form->value = value; /* store for the moment */ curr->value = avalue; /* store for the moment */
else else
return_value = CURL_FORMADD_NULL; retval = CURL_FORMADD_NULL;
} }
break; break;
case CURLFORM_CONTENTSLENGTH: case CURLFORM_CONTENTSLENGTH:
current_form->contentslength = curr->contentslength =
array_state ? (size_t)array_value : (size_t)va_arg(params, long); array_state ? (size_t)avalue : (size_t)va_arg(params, long);
break; break;
case CURLFORM_CONTENTLEN: case CURLFORM_CONTENTLEN:
current_form->flags |= CURL_HTTPPOST_LARGE; curr->flags |= CURL_HTTPPOST_LARGE;
current_form->contentslength = curr->contentslength =
array_state ? (curl_off_t)(size_t)array_value : array_state ? (curl_off_t)(size_t)avalue :
va_arg(params, curl_off_t); va_arg(params, curl_off_t);
break; break;
/* Get contents from a given filename */ /* Get contents from a given filename */
case CURLFORM_FILECONTENT: case CURLFORM_FILECONTENT:
if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE)) if(curr->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
return_value = CURL_FORMADD_OPTION_TWICE; retval = CURL_FORMADD_OPTION_TWICE;
else { else {
const char *filename = array_state ? if(!array_state)
array_value : va_arg(params, char *); avalue = va_arg(params, char *);
if(filename) { if(avalue) {
current_form->value = strdup(filename); curr->value = strdup(avalue);
if(!current_form->value) if(!curr->value)
return_value = CURL_FORMADD_MEMORY; retval = CURL_FORMADD_MEMORY;
else { else {
current_form->flags |= HTTPPOST_READFILE; curr->flags |= HTTPPOST_READFILE;
current_form->value_alloc = TRUE; curr->value_alloc = TRUE;
} }
} }
else else
return_value = CURL_FORMADD_NULL; retval = CURL_FORMADD_NULL;
} }
break; break;
/* We upload a file */ /* We upload a file */
case CURLFORM_FILE: case CURLFORM_FILE:
{ if(!array_state)
const char *filename = array_state ? array_value : avalue = va_arg(params, char *);
va_arg(params, char *);
if(current_form->value) { if(curr->value) {
if(current_form->flags & HTTPPOST_FILENAME) { if(curr->flags & HTTPPOST_FILENAME) {
if(filename) { if(avalue) {
char *fname = strdup(filename); char *fname = strdup(avalue);
if(!fname) if(!fname)
return_value = CURL_FORMADD_MEMORY; retval = CURL_FORMADD_MEMORY;
else {
form = AddFormInfo(fname, NULL, curr);
if(!form) {
free(fname);
retval = CURL_FORMADD_MEMORY;
}
else { else {
form = AddFormInfo(fname, NULL, current_form); form->value_alloc = TRUE;
if(!form) { curr = form;
free(fname); form = NULL;
return_value = CURL_FORMADD_MEMORY;
}
else {
form->value_alloc = TRUE;
current_form = form;
form = NULL;
}
} }
} }
else
return_value = CURL_FORMADD_NULL;
} }
else else
return_value = CURL_FORMADD_OPTION_TWICE; retval = CURL_FORMADD_NULL;
} }
else { else
if(filename) { retval = CURL_FORMADD_OPTION_TWICE;
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
return_value = CURL_FORMADD_NULL;
}
break;
} }
else {
if(avalue) {
curr->value = strdup(avalue);
if(!curr->value)
retval = CURL_FORMADD_MEMORY;
else {
curr->flags |= HTTPPOST_FILENAME;
curr->value_alloc = TRUE;
}
}
else
retval = CURL_FORMADD_NULL;
}
break;
case CURLFORM_BUFFERPTR: case CURLFORM_BUFFERPTR:
current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER; curr->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
if(current_form->buffer) if(curr->buffer)
return_value = CURL_FORMADD_OPTION_TWICE; retval = CURL_FORMADD_OPTION_TWICE;
else { else {
char *buffer = if(!array_state)
array_state ? array_value : va_arg(params, char *); avalue = va_arg(params, char *);
if(buffer) { if(avalue) {
current_form->buffer = buffer; /* store for the moment */ curr->buffer = avalue; /* store for the moment */
current_form->value = buffer; /* make it non-NULL to be accepted curr->value = avalue; /* make it non-NULL to be accepted
as fine */ as fine */
} }
else else
return_value = CURL_FORMADD_NULL; retval = CURL_FORMADD_NULL;
} }
break; break;
case CURLFORM_BUFFERLENGTH: case CURLFORM_BUFFERLENGTH:
if(current_form->bufferlength) if(curr->bufferlength)
return_value = CURL_FORMADD_OPTION_TWICE; retval = CURL_FORMADD_OPTION_TWICE;
else else
current_form->bufferlength = curr->bufferlength =
array_state ? (size_t)array_value : (size_t)va_arg(params, long); array_state ? (size_t)avalue : (size_t)va_arg(params, long);
break; break;
case CURLFORM_STREAM: case CURLFORM_STREAM:
current_form->flags |= HTTPPOST_CALLBACK; curr->flags |= HTTPPOST_CALLBACK;
if(current_form->userp) if(curr->userp)
return_value = CURL_FORMADD_OPTION_TWICE; retval = CURL_FORMADD_OPTION_TWICE;
else { else {
char *userp = if(!array_state)
array_state ? array_value : va_arg(params, char *); avalue = va_arg(params, char *);
if(userp) { if(avalue) {
current_form->userp = userp; curr->userp = avalue;
current_form->value = userp; /* this is not strictly true but we curr->value = avalue; /* this is not strictly true but we derive a
derive a value from this later on value from this later on and we need this
and we need this non-NULL to be non-NULL to be accepted as a fine form
accepted as a fine form part */ part */
} }
else else
return_value = CURL_FORMADD_NULL; retval = CURL_FORMADD_NULL;
} }
break; break;
case CURLFORM_CONTENTTYPE: case CURLFORM_CONTENTTYPE:
{ if(!array_state)
const char *contenttype = avalue = va_arg(params, char *);
array_state ? array_value : va_arg(params, char *); if(curr->contenttype) {
if(current_form->contenttype) { if(curr->flags & HTTPPOST_FILENAME) {
if(current_form->flags & HTTPPOST_FILENAME) { if(avalue) {
if(contenttype) { char *type = strdup(avalue);
char *type = strdup(contenttype); if(!type)
if(!type) retval = CURL_FORMADD_MEMORY;
return_value = CURL_FORMADD_MEMORY; else {
form = AddFormInfo(NULL, type, curr);
if(!form) {
free(type);
retval = CURL_FORMADD_MEMORY;
}
else { else {
form = AddFormInfo(NULL, type, current_form); form->contenttype_alloc = TRUE;
if(!form) { curr = form;
free(type); form = NULL;
return_value = CURL_FORMADD_MEMORY;
}
else {
form->contenttype_alloc = TRUE;
current_form = form;
form = NULL;
}
} }
} }
else
return_value = CURL_FORMADD_NULL;
} }
else else
return_value = CURL_FORMADD_OPTION_TWICE; retval = CURL_FORMADD_NULL;
} }
else { else
if(contenttype) { retval = CURL_FORMADD_OPTION_TWICE;
current_form->contenttype = strdup(contenttype);
if(!current_form->contenttype)
return_value = CURL_FORMADD_MEMORY;
else
current_form->contenttype_alloc = TRUE;
}
else
return_value = CURL_FORMADD_NULL;
}
break;
} }
else {
if(avalue) {
curr->contenttype = strdup(avalue);
if(!curr->contenttype)
retval = CURL_FORMADD_MEMORY;
else
curr->contenttype_alloc = TRUE;
}
else
retval = CURL_FORMADD_NULL;
}
break;
case CURLFORM_CONTENTHEADER: case CURLFORM_CONTENTHEADER:
{ {
/* this "cast increases required alignment of target type" but /* this "cast increases required alignment of target type" but
we consider it OK anyway */ we consider it OK anyway */
struct curl_slist *list = array_state ? struct curl_slist *list = array_state ?
(struct curl_slist *)(void *)array_value : (struct curl_slist *)(void *)avalue :
va_arg(params, struct curl_slist *); va_arg(params, struct curl_slist *);
if(current_form->contentheader) if(curr->contentheader)
return_value = CURL_FORMADD_OPTION_TWICE; retval = CURL_FORMADD_OPTION_TWICE;
else else
current_form->contentheader = list; curr->contentheader = list;
break; break;
} }
case CURLFORM_FILENAME: case CURLFORM_FILENAME:
case CURLFORM_BUFFER: case CURLFORM_BUFFER:
{ if(!array_state)
const char *filename = array_state ? array_value : avalue = va_arg(params, char *);
va_arg(params, char *); if(curr->showfilename)
if(current_form->showfilename) retval = CURL_FORMADD_OPTION_TWICE;
return_value = CURL_FORMADD_OPTION_TWICE; else {
else { curr->showfilename = strdup(avalue);
current_form->showfilename = strdup(filename); if(!curr->showfilename)
if(!current_form->showfilename) retval = CURL_FORMADD_MEMORY;
return_value = CURL_FORMADD_MEMORY; else
else curr->showfilename_alloc = TRUE;
current_form->showfilename_alloc = TRUE;
}
break;
} }
break;
default: default:
return_value = CURL_FORMADD_UNKNOWN_OPTION; retval = CURL_FORMADD_UNKNOWN_OPTION;
break; 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 /* On error, free allocated fields for all nodes of the FormInfo linked
list without deallocating nodes. List nodes are deallocated later on */ list without deallocating nodes. List nodes are deallocated later on */
struct FormInfo *ptr; free_formlist(first_form);
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) {
return_value = FormAddCheck(first_form, httppost, last_post);
}
/* Always deallocate FormInfo linked list nodes without touching node /* Always deallocate FormInfo linked list nodes without touching node
fields given that these have either been deallocated or are owned fields given that these have either been deallocated or are owned
@ -690,7 +639,25 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
first_form = ptr; 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 {
/* remove the newly created chain */
while(newchain) {
struct curl_httppost *next = newchain->next;
free(newchain);
newchain = next;
}
}
return retval;
} }
/* /*

View File

@ -35,7 +35,6 @@ struct FormInfo {
char *value; char *value;
curl_off_t contentslength; curl_off_t contentslength;
char *contenttype; char *contenttype;
long flags;
char *buffer; /* pointer to existing buffer used for file upload */ char *buffer; /* pointer to existing buffer used for file upload */
size_t bufferlength; size_t bufferlength;
char *showfilename; /* The filename to show. If not set, the actual char *showfilename; /* The filename to show. If not set, the actual
@ -43,6 +42,7 @@ struct FormInfo {
char *userp; /* pointer for the read callback */ char *userp; /* pointer for the read callback */
struct curl_slist *contentheader; struct curl_slist *contentheader;
struct FormInfo *more; struct FormInfo *more;
unsigned char flags;
BIT(name_alloc); BIT(name_alloc);
BIT(value_alloc); BIT(value_alloc);
BIT(contenttype_alloc); BIT(contenttype_alloc);