mirror of
https://github.com/curl/curl.git
synced 2026-07-24 13:57:16 +03:00
formdata: use struct bufref for maybe-dynamic fields.
Lengths are not stored in the structures, as they may be given before the data locations. Closes #19827
This commit is contained in:
parent
2cb868242d
commit
fe7703a0b3
2 changed files with 148 additions and 202 deletions
326
lib/formdata.c
326
lib/formdata.c
|
|
@ -37,6 +37,7 @@ struct Curl_easy;
|
|||
#include "sendf.h"
|
||||
#include "strdup.h"
|
||||
#include "rand.h"
|
||||
#include "bufref.h"
|
||||
#include "curlx/fopen.h"
|
||||
#include "curlx/warnless.h"
|
||||
|
||||
|
|
@ -66,23 +67,23 @@ static struct curl_httppost *AddHttpPost(struct FormInfo *src,
|
|||
{
|
||||
struct curl_httppost *post;
|
||||
size_t namelength = src->namelength;
|
||||
if(!namelength && src->name)
|
||||
namelength = strlen(src->name);
|
||||
if(!namelength && Curl_bufref_ptr(&src->name))
|
||||
namelength = strlen(Curl_bufref_ptr(&src->name));
|
||||
if((src->bufferlength > LONG_MAX) || (namelength > LONG_MAX))
|
||||
/* avoid overflow in typecasts below */
|
||||
return NULL;
|
||||
post = curlx_calloc(1, sizeof(struct curl_httppost));
|
||||
if(post) {
|
||||
post->name = src->name;
|
||||
post->name = CURL_UNCONST(Curl_bufref_ptr(&src->name));
|
||||
post->namelength = (long)namelength;
|
||||
post->contents = src->value;
|
||||
post->contents = CURL_UNCONST(Curl_bufref_ptr(&src->value));
|
||||
post->contentlen = src->contentslength;
|
||||
post->buffer = src->buffer;
|
||||
post->bufferlength = (long)src->bufferlength;
|
||||
post->contenttype = src->contenttype;
|
||||
post->contenttype = CURL_UNCONST(Curl_bufref_ptr(&src->contenttype));
|
||||
post->flags = src->flags | CURL_HTTPPOST_LARGE;
|
||||
post->contentheader = src->contentheader;
|
||||
post->showfilename = src->showfilename;
|
||||
post->showfilename = CURL_UNCONST(Curl_bufref_ptr(&src->showfilename));
|
||||
post->userp = src->userp;
|
||||
}
|
||||
else
|
||||
|
|
@ -107,60 +108,63 @@ static struct curl_httppost *AddHttpPost(struct FormInfo *src,
|
|||
return post;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* AddFormInfo()
|
||||
*
|
||||
* Adds a FormInfo structure to the list presented by parent_form_info.
|
||||
*
|
||||
* Returns newly allocated FormInfo on success and NULL if malloc failed/
|
||||
* parent_form_info is NULL.
|
||||
*
|
||||
***************************************************************************/
|
||||
static struct FormInfo *AddFormInfo(char *value,
|
||||
char *contenttype,
|
||||
struct FormInfo *parent_form_info)
|
||||
/* Allocate and initialize a new FormInfo structure. */
|
||||
static struct FormInfo *NewFormInfo(void)
|
||||
{
|
||||
struct FormInfo *form_info;
|
||||
form_info = curlx_calloc(1, sizeof(struct FormInfo));
|
||||
if(!form_info)
|
||||
return NULL;
|
||||
if(value)
|
||||
form_info->value = value;
|
||||
if(contenttype)
|
||||
form_info->contenttype = contenttype;
|
||||
form_info->flags = HTTPPOST_FILENAME;
|
||||
struct FormInfo *form_info = curlx_calloc(1, sizeof(struct FormInfo));
|
||||
|
||||
if(parent_form_info) {
|
||||
/* now, point our 'more' to the original 'more' */
|
||||
form_info->more = parent_form_info->more;
|
||||
|
||||
/* then move the original 'more' to point to ourselves */
|
||||
parent_form_info->more = form_info;
|
||||
if(form_info) {
|
||||
Curl_bufref_init(&form_info->name);
|
||||
Curl_bufref_init(&form_info->value);
|
||||
Curl_bufref_init(&form_info->contenttype);
|
||||
Curl_bufref_init(&form_info->showfilename);
|
||||
}
|
||||
|
||||
return form_info;
|
||||
}
|
||||
|
||||
/* Replace the target field data by a dynamic copy of it. */
|
||||
static CURLcode FormInfoCopyField(struct bufref *field, size_t len)
|
||||
{
|
||||
const char *value = Curl_bufref_ptr(field);
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(value) {
|
||||
if(!len)
|
||||
len = strlen(value);
|
||||
result = Curl_bufref_memdup(field, value, len);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* AddFormInfo()
|
||||
*
|
||||
* Adds a FormInfo structure to the list presented by parent.
|
||||
*
|
||||
***************************************************************************/
|
||||
static void AddFormInfo(struct FormInfo *form_info, struct FormInfo *parent)
|
||||
{
|
||||
form_info->flags |= HTTPPOST_FILENAME;
|
||||
|
||||
if(parent) {
|
||||
/* now, point our 'more' to the original 'more' */
|
||||
form_info->more = parent->more;
|
||||
|
||||
/* then move the original 'more' to point to ourselves */
|
||||
parent->more = 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;
|
||||
}
|
||||
Curl_bufref_free(&ptr->name);
|
||||
Curl_bufref_free(&ptr->value);
|
||||
Curl_bufref_free(&ptr->contenttype);
|
||||
Curl_bufref_free(&ptr->showfilename);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -227,7 +231,9 @@ static CURLFORMcode FormAddCheck(struct FormInfo *first_form,
|
|||
* alright add the HttpPost item otherwise set retval accordingly */
|
||||
|
||||
for(form = first_form; form != NULL; form = form->more) {
|
||||
if(((!form->name || !form->value) && !post) ||
|
||||
const char *name = Curl_bufref_ptr(&form->name);
|
||||
|
||||
if(((!name || !Curl_bufref_ptr(&form->value)) && !post) ||
|
||||
(form->contentslength &&
|
||||
(form->flags & HTTPPOST_FILENAME)) ||
|
||||
((form->flags & HTTPPOST_FILENAME) &&
|
||||
|
|
@ -244,62 +250,42 @@ static CURLFORMcode FormAddCheck(struct FormInfo *first_form,
|
|||
}
|
||||
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);
|
||||
!Curl_bufref_ptr(&form->contenttype)) {
|
||||
const char *f = Curl_bufref_ptr((form->flags & HTTPPOST_BUFFER) ?
|
||||
&form->showfilename : &form->value);
|
||||
const char *type = Curl_mime_contenttype(f);
|
||||
if(!type)
|
||||
type = prevtype;
|
||||
if(!type)
|
||||
type = FILE_CONTENTTYPE_DEFAULT;
|
||||
|
||||
/* our contenttype is missing */
|
||||
form->contenttype = curlx_strdup(type);
|
||||
if(!form->contenttype)
|
||||
if(Curl_bufref_memdup(&form->contenttype, type, strlen(type)))
|
||||
return CURL_FORMADD_MEMORY;
|
||||
|
||||
form->contenttype_alloc = TRUE;
|
||||
}
|
||||
if(form->name && form->namelength) {
|
||||
if(memchr(form->name, 0, form->namelength))
|
||||
if(name && form->namelength) {
|
||||
if(memchr(name, 0, form->namelength))
|
||||
return CURL_FORMADD_NULL;
|
||||
}
|
||||
if(!(form->flags & HTTPPOST_PTRNAME) && form->name) {
|
||||
if(!(form->flags & HTTPPOST_PTRNAME)) {
|
||||
/* 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)
|
||||
if(FormInfoCopyField(&form->name, form->namelength))
|
||||
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)
|
||||
HTTPPOST_CALLBACK))) {
|
||||
if(FormInfoCopyField(&form->value, (size_t) form->contentslength))
|
||||
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;
|
||||
if(Curl_bufref_ptr(&form->contenttype))
|
||||
prevtype = Curl_bufref_ptr(&form->contenttype);
|
||||
}
|
||||
|
||||
return CURL_FORMADD_OK;
|
||||
|
|
@ -329,15 +315,17 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
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
|
||||
va_list arguments. */
|
||||
bool array_state = FALSE;
|
||||
#define form_ptr_arg(t) (forms ? (t) (void *) avalue : va_arg(params, t))
|
||||
#ifdef HAVE_STDINT_H
|
||||
#define form_int_arg(t) (forms ? (t) (uintptr_t) avalue : va_arg(params, t))
|
||||
#else
|
||||
#define form_int_arg(t) (forms ? (t) (void *) avalue : va_arg(params, t))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We need to allocate the first struct to fill in.
|
||||
*/
|
||||
first_form = curlx_calloc(1, sizeof(struct FormInfo));
|
||||
first_form = NewFormInfo();
|
||||
if(!first_form)
|
||||
return CURL_FORMADD_MEMORY;
|
||||
|
||||
|
|
@ -349,7 +337,7 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
while(retval == CURL_FORMADD_OK) {
|
||||
|
||||
/* first see if we have more parts of the array param */
|
||||
if(array_state && forms) {
|
||||
if(forms) {
|
||||
/* get the upcoming option from the given array */
|
||||
option = forms->option;
|
||||
avalue = (char *)CURL_UNCONST(forms->value);
|
||||
|
|
@ -357,7 +345,7 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
forms++; /* advance this to next entry */
|
||||
if(CURLFORM_END == option) {
|
||||
/* end of array state */
|
||||
array_state = FALSE;
|
||||
forms = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -372,14 +360,12 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
|
||||
switch(option) {
|
||||
case CURLFORM_ARRAY:
|
||||
if(array_state)
|
||||
if(forms)
|
||||
/* we do not support an array from within an array */
|
||||
retval = CURL_FORMADD_ILLEGAL_ARRAY;
|
||||
else {
|
||||
forms = va_arg(params, struct curl_forms *);
|
||||
if(forms)
|
||||
array_state = TRUE;
|
||||
else
|
||||
if(!forms)
|
||||
retval = CURL_FORMADD_NULL;
|
||||
}
|
||||
break;
|
||||
|
|
@ -388,17 +374,15 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
* Set the Name property.
|
||||
*/
|
||||
case CURLFORM_PTRNAME:
|
||||
curr->flags |= HTTPPOST_PTRNAME; /* fall through */
|
||||
|
||||
curr->flags |= HTTPPOST_PTRNAME;
|
||||
FALLTHROUGH();
|
||||
case CURLFORM_COPYNAME:
|
||||
if(curr->name)
|
||||
if(Curl_bufref_ptr(&curr->name))
|
||||
retval = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
if(!array_state)
|
||||
avalue = va_arg(params, char *);
|
||||
avalue = form_ptr_arg(char *);
|
||||
if(avalue)
|
||||
curr->name = avalue; /* store for the moment */
|
||||
Curl_bufref_set(&curr->name, avalue, 0, NULL); /* No copy yet. */
|
||||
else
|
||||
retval = CURL_FORMADD_NULL;
|
||||
}
|
||||
|
|
@ -407,8 +391,7 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
if(curr->namelength)
|
||||
retval = CURL_FORMADD_OPTION_TWICE;
|
||||
else
|
||||
curr->namelength =
|
||||
array_state ? (size_t)avalue : (size_t)va_arg(params, long);
|
||||
curr->namelength = (size_t) form_int_arg(long);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
|
@ -418,26 +401,23 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
curr->flags |= HTTPPOST_PTRCONTENTS;
|
||||
FALLTHROUGH();
|
||||
case CURLFORM_COPYCONTENTS:
|
||||
if(curr->value)
|
||||
if(Curl_bufref_ptr(&curr->value))
|
||||
retval = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
if(!array_state)
|
||||
avalue = va_arg(params, char *);
|
||||
avalue = form_ptr_arg(char *);
|
||||
if(avalue)
|
||||
curr->value = avalue; /* store for the moment */
|
||||
Curl_bufref_set(&curr->value, avalue, 0, NULL); /* No copy yet. */
|
||||
else
|
||||
retval = CURL_FORMADD_NULL;
|
||||
}
|
||||
break;
|
||||
case CURLFORM_CONTENTSLENGTH:
|
||||
curr->contentslength =
|
||||
array_state ? (size_t)avalue : (size_t)va_arg(params, long);
|
||||
curr->contentslength = (curl_off_t)(size_t) form_int_arg(long);
|
||||
break;
|
||||
|
||||
case CURLFORM_CONTENTLEN:
|
||||
curr->flags |= CURL_HTTPPOST_LARGE;
|
||||
curr->contentslength =
|
||||
array_state ? (curl_off_t)(size_t)avalue : va_arg(params, curl_off_t);
|
||||
curr->contentslength = form_int_arg(curl_off_t);
|
||||
break;
|
||||
|
||||
/* Get contents from a given filename */
|
||||
|
|
@ -445,16 +425,12 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
if(curr->flags & (HTTPPOST_PTRCONTENTS | HTTPPOST_READFILE))
|
||||
retval = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
if(!array_state)
|
||||
avalue = va_arg(params, char *);
|
||||
avalue = form_ptr_arg(char *);
|
||||
if(avalue) {
|
||||
curr->value = curlx_strdup(avalue);
|
||||
if(!curr->value)
|
||||
if(Curl_bufref_memdup(&curr->value, avalue, strlen(avalue)))
|
||||
retval = CURL_FORMADD_MEMORY;
|
||||
else {
|
||||
else
|
||||
curr->flags |= HTTPPOST_READFILE;
|
||||
curr->value_alloc = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
retval = CURL_FORMADD_NULL;
|
||||
|
|
@ -463,26 +439,20 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
|
||||
/* We upload a file */
|
||||
case CURLFORM_FILE:
|
||||
if(!array_state)
|
||||
avalue = va_arg(params, char *);
|
||||
|
||||
if(curr->value) {
|
||||
avalue = form_ptr_arg(char *);
|
||||
if(Curl_bufref_ptr(&curr->value)) {
|
||||
if(curr->flags & HTTPPOST_FILENAME) {
|
||||
if(avalue) {
|
||||
char *fname = curlx_strdup(avalue);
|
||||
if(!fname)
|
||||
form = NewFormInfo();
|
||||
if(!form ||
|
||||
Curl_bufref_memdup(&form->value, avalue, strlen(avalue))) {
|
||||
curlx_free(form);
|
||||
retval = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else {
|
||||
form = AddFormInfo(fname, NULL, curr);
|
||||
if(!form) {
|
||||
curlx_free(fname);
|
||||
retval = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else {
|
||||
form->value_alloc = TRUE;
|
||||
curr = form;
|
||||
form = NULL;
|
||||
}
|
||||
AddFormInfo(form, curr);
|
||||
curr = form;
|
||||
form = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -493,13 +463,10 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
}
|
||||
else {
|
||||
if(avalue) {
|
||||
curr->value = curlx_strdup(avalue);
|
||||
if(!curr->value)
|
||||
if(Curl_bufref_memdup(&curr->value, avalue, strlen(avalue)))
|
||||
retval = CURL_FORMADD_MEMORY;
|
||||
else {
|
||||
else
|
||||
curr->flags |= HTTPPOST_FILENAME;
|
||||
curr->value_alloc = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
retval = CURL_FORMADD_NULL;
|
||||
|
|
@ -511,12 +478,11 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
if(curr->buffer)
|
||||
retval = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
if(!array_state)
|
||||
avalue = va_arg(params, char *);
|
||||
avalue = form_ptr_arg(char *);
|
||||
if(avalue) {
|
||||
curr->buffer = avalue; /* store for the moment */
|
||||
curr->value = avalue; /* make it non-NULL to be accepted
|
||||
as fine */
|
||||
/* Make value non-NULL to be accepted as fine */
|
||||
Curl_bufref_set(&curr->value, avalue, 0, NULL);
|
||||
}
|
||||
else
|
||||
retval = CURL_FORMADD_NULL;
|
||||
|
|
@ -527,8 +493,7 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
if(curr->bufferlength)
|
||||
retval = CURL_FORMADD_OPTION_TWICE;
|
||||
else
|
||||
curr->bufferlength =
|
||||
array_state ? (size_t)avalue : (size_t)va_arg(params, long);
|
||||
curr->bufferlength = (size_t) form_int_arg(long);
|
||||
break;
|
||||
|
||||
case CURLFORM_STREAM:
|
||||
|
|
@ -536,14 +501,13 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
if(curr->userp)
|
||||
retval = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
if(!array_state)
|
||||
avalue = va_arg(params, char *);
|
||||
avalue = form_ptr_arg(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 */
|
||||
/* The following line 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 */
|
||||
Curl_bufref_set(&curr->value, avalue, 0, NULL);
|
||||
}
|
||||
else
|
||||
retval = CURL_FORMADD_NULL;
|
||||
|
|
@ -551,25 +515,20 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
break;
|
||||
|
||||
case CURLFORM_CONTENTTYPE:
|
||||
if(!array_state)
|
||||
avalue = va_arg(params, char *);
|
||||
if(curr->contenttype) {
|
||||
avalue = form_ptr_arg(char *);
|
||||
if(Curl_bufref_ptr(&curr->contenttype)) {
|
||||
if(curr->flags & HTTPPOST_FILENAME) {
|
||||
if(avalue) {
|
||||
char *type = curlx_strdup(avalue);
|
||||
if(!type)
|
||||
form = NewFormInfo();
|
||||
if(!form || Curl_bufref_memdup(&form->contenttype, avalue,
|
||||
strlen(avalue))) {
|
||||
curlx_free(form);
|
||||
retval = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else {
|
||||
form = AddFormInfo(NULL, type, curr);
|
||||
if(!form) {
|
||||
curlx_free(type);
|
||||
retval = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else {
|
||||
form->contenttype_alloc = TRUE;
|
||||
curr = form;
|
||||
form = NULL;
|
||||
}
|
||||
AddFormInfo(form, curr);
|
||||
curr = form;
|
||||
form = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -578,25 +537,18 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
else
|
||||
retval = CURL_FORMADD_OPTION_TWICE;
|
||||
}
|
||||
else {
|
||||
if(avalue) {
|
||||
curr->contenttype = curlx_strdup(avalue);
|
||||
if(!curr->contenttype)
|
||||
retval = CURL_FORMADD_MEMORY;
|
||||
else
|
||||
curr->contenttype_alloc = TRUE;
|
||||
}
|
||||
else
|
||||
retval = CURL_FORMADD_NULL;
|
||||
else if(avalue) {
|
||||
if(Curl_bufref_memdup(&curr->contenttype, avalue, strlen(avalue)))
|
||||
retval = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
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 *)avalue :
|
||||
va_arg(params, struct curl_slist *);
|
||||
struct curl_slist *list = form_ptr_arg(struct curl_slist *);
|
||||
|
||||
if(curr->contentheader)
|
||||
retval = CURL_FORMADD_OPTION_TWICE;
|
||||
|
|
@ -607,17 +559,11 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
}
|
||||
case CURLFORM_FILENAME:
|
||||
case CURLFORM_BUFFER:
|
||||
if(!array_state)
|
||||
avalue = va_arg(params, char *);
|
||||
if(curr->showfilename)
|
||||
avalue = form_ptr_arg(char *);
|
||||
if(Curl_bufref_ptr(&curr->showfilename))
|
||||
retval = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
curr->showfilename = curlx_strdup(avalue);
|
||||
if(!curr->showfilename)
|
||||
retval = CURL_FORMADD_MEMORY;
|
||||
else
|
||||
curr->showfilename_alloc = TRUE;
|
||||
}
|
||||
else if(Curl_bufref_memdup(&curr->showfilename, avalue, strlen(avalue)))
|
||||
retval = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -656,6 +602,8 @@ static CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||
free_chain(newchain);
|
||||
|
||||
return retval;
|
||||
#undef form_ptr_arg
|
||||
#undef form_int_arg
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -28,25 +28,23 @@
|
|||
|
||||
#ifndef CURL_DISABLE_FORM_API
|
||||
|
||||
#include "bufref.h"
|
||||
|
||||
/* used by FormAdd for temporary storage */
|
||||
struct FormInfo {
|
||||
char *name;
|
||||
size_t namelength;
|
||||
char *value;
|
||||
curl_off_t contentslength;
|
||||
char *contenttype;
|
||||
struct bufref name;
|
||||
struct bufref value;
|
||||
struct bufref contenttype;
|
||||
struct bufref showfilename; /* The filename to show. If not set, the actual
|
||||
filename will be used */
|
||||
char *buffer; /* pointer to existing buffer used for file upload */
|
||||
size_t bufferlength;
|
||||
char *showfilename; /* The filename to show. If not set, the actual
|
||||
filename will be used */
|
||||
char *userp; /* pointer for the read callback */
|
||||
struct curl_slist *contentheader;
|
||||
struct FormInfo *more;
|
||||
struct curl_slist *contentheader;
|
||||
curl_off_t contentslength;
|
||||
size_t namelength;
|
||||
size_t bufferlength;
|
||||
unsigned char flags;
|
||||
BIT(name_alloc);
|
||||
BIT(value_alloc);
|
||||
BIT(contenttype_alloc);
|
||||
BIT(showfilename_alloc);
|
||||
};
|
||||
|
||||
CURLcode Curl_getformdata(CURL *data,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue