mirror of
https://github.com/curl/curl.git
synced 2025-09-08 13:24:59 +03:00
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:
parent
30e40c1a11
commit
c26da713e7
517
lib/formdata.c
517
lib/formdata.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user