mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
formdata.c: OOM handling fixes
This commit is contained in:
parent
1dd654644a
commit
1afbccc676
176
lib/formdata.c
176
lib/formdata.c
@ -156,8 +156,6 @@ static FormInfo * AddFormInfo(char *value,
|
|||||||
/* then move the original 'more' to point to ourselves */
|
/* then move the original 'more' to point to ourselves */
|
||||||
parent_form_info->more = form_info;
|
parent_form_info->more = form_info;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return form_info;
|
return form_info;
|
||||||
}
|
}
|
||||||
@ -458,9 +456,21 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
if(current_form->value) {
|
if(current_form->value) {
|
||||||
if(current_form->flags & HTTPPOST_FILENAME) {
|
if(current_form->flags & HTTPPOST_FILENAME) {
|
||||||
if(filename) {
|
if(filename) {
|
||||||
if((current_form = AddFormInfo(strdup(filename),
|
char *fname = strdup(filename);
|
||||||
NULL, current_form)) == NULL)
|
if(!fname)
|
||||||
return_value = CURL_FORMADD_MEMORY;
|
return_value = CURL_FORMADD_MEMORY;
|
||||||
|
else {
|
||||||
|
form = AddFormInfo(fname, NULL, current_form);
|
||||||
|
if(!form) {
|
||||||
|
Curl_safefree(fname);
|
||||||
|
return_value = CURL_FORMADD_MEMORY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
form->value_alloc = TRUE;
|
||||||
|
current_form = form;
|
||||||
|
form = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return_value = CURL_FORMADD_NULL;
|
return_value = CURL_FORMADD_NULL;
|
||||||
@ -535,10 +545,21 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
if(current_form->contenttype) {
|
if(current_form->contenttype) {
|
||||||
if(current_form->flags & HTTPPOST_FILENAME) {
|
if(current_form->flags & HTTPPOST_FILENAME) {
|
||||||
if(contenttype) {
|
if(contenttype) {
|
||||||
if((current_form = AddFormInfo(NULL,
|
char *type = strdup(contenttype);
|
||||||
strdup(contenttype),
|
if(!type)
|
||||||
current_form)) == NULL)
|
|
||||||
return_value = CURL_FORMADD_MEMORY;
|
return_value = CURL_FORMADD_MEMORY;
|
||||||
|
else {
|
||||||
|
form = AddFormInfo(NULL, type, current_form);
|
||||||
|
if(!form) {
|
||||||
|
Curl_safefree(type);
|
||||||
|
return_value = CURL_FORMADD_MEMORY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
form->contenttype_alloc = TRUE;
|
||||||
|
current_form = form;
|
||||||
|
form = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return_value = CURL_FORMADD_NULL;
|
return_value = CURL_FORMADD_NULL;
|
||||||
@ -596,6 +617,30 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(CURL_FORMADD_OK != return_value) {
|
||||||
|
/* On error, free allocated fields for all nodes of the FormInfo linked
|
||||||
|
list without deallocating nodes. List nodes are deallocated later on */
|
||||||
|
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) {
|
if(CURL_FORMADD_OK == return_value) {
|
||||||
/* 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 return_value accordingly */
|
||||||
@ -675,32 +720,39 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
prevtype = form->contenttype;
|
prevtype = form->contenttype;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if(CURL_FORMADD_OK != return_value) {
|
||||||
|
/* On error, free allocated fields for nodes of the FormInfo linked
|
||||||
if(return_value) {
|
list which are not already owned by the httppost linked list
|
||||||
/* we return on error, free possibly allocated fields */
|
without deallocating nodes. List nodes are deallocated later on */
|
||||||
if(!form)
|
FormInfo *ptr;
|
||||||
form = current_form;
|
for(ptr = form; ptr != NULL; ptr = ptr->more) {
|
||||||
if(form) {
|
if(ptr->name_alloc) {
|
||||||
if(form->name_alloc)
|
Curl_safefree(ptr->name);
|
||||||
free(form->name);
|
ptr->name_alloc = FALSE;
|
||||||
if(form->value_alloc)
|
}
|
||||||
free(form->value);
|
if(ptr->value_alloc) {
|
||||||
if(form->contenttype_alloc)
|
Curl_safefree(ptr->value);
|
||||||
free(form->contenttype);
|
ptr->value_alloc = FALSE;
|
||||||
if(form->showfilename_alloc)
|
}
|
||||||
free(form->showfilename);
|
if(ptr->contenttype_alloc) {
|
||||||
|
Curl_safefree(ptr->contenttype);
|
||||||
|
ptr->contenttype_alloc = FALSE;
|
||||||
|
}
|
||||||
|
if(ptr->showfilename_alloc) {
|
||||||
|
Curl_safefree(ptr->showfilename);
|
||||||
|
ptr->showfilename_alloc = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* always delete the allocated memory before returning */
|
/* Always deallocate FormInfo linked list nodes without touching node
|
||||||
form = first_form;
|
fields given that these have either been deallocated or are owned
|
||||||
while(form != NULL) {
|
now by the httppost linked list */
|
||||||
FormInfo *delete_form;
|
while(first_form) {
|
||||||
|
FormInfo *ptr = first_form->more;
|
||||||
delete_form = form;
|
Curl_safefree(first_form);
|
||||||
form = form->more;
|
first_form = ptr;
|
||||||
free (delete_form);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return return_value;
|
return return_value;
|
||||||
@ -996,12 +1048,12 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
struct curl_httppost *file;
|
struct curl_httppost *file;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
|
||||||
curl_off_t size=0; /* support potentially ENORMOUS formposts */
|
curl_off_t size = 0; /* support potentially ENORMOUS formposts */
|
||||||
char *boundary;
|
char *boundary;
|
||||||
char *fileboundary=NULL;
|
char *fileboundary = NULL;
|
||||||
struct curl_slist* curList;
|
struct curl_slist* curList;
|
||||||
|
|
||||||
*finalform=NULL; /* default form is empty */
|
*finalform = NULL; /* default form is empty */
|
||||||
|
|
||||||
if(!post)
|
if(!post)
|
||||||
return result; /* no input => no output! */
|
return result; /* no input => no output! */
|
||||||
@ -1018,7 +1070,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
boundary);
|
boundary);
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
free(boundary);
|
Curl_safefree(boundary);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/* we DO NOT include that line in the total size of the POST, since it'll be
|
/* we DO NOT include that line in the total size of the POST, since it'll be
|
||||||
@ -1061,7 +1113,12 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
/* If used, this is a link to more file names, we must then do
|
/* If used, this is a link to more file names, we must then do
|
||||||
the magic to include several files with the same field name */
|
the magic to include several files with the same field name */
|
||||||
|
|
||||||
|
Curl_safefree(fileboundary);
|
||||||
fileboundary = Curl_FormBoundary();
|
fileboundary = Curl_FormBoundary();
|
||||||
|
if(!fileboundary) {
|
||||||
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
result = AddFormDataf(&form, &size,
|
result = AddFormDataf(&form, &size,
|
||||||
"\r\nContent-Type: multipart/mixed,"
|
"\r\nContent-Type: multipart/mixed,"
|
||||||
@ -1081,13 +1138,12 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
|
|
||||||
if(post->more) {
|
if(post->more) {
|
||||||
/* if multiple-file */
|
/* if multiple-file */
|
||||||
char *filebasename= NULL;
|
char *filebasename = NULL;
|
||||||
if(!file->showfilename) {
|
if(!file->showfilename) {
|
||||||
filebasename = strippath(file->contents);
|
filebasename = strippath(file->contents);
|
||||||
if(!filebasename) {
|
if(!filebasename) {
|
||||||
Curl_formclean(&firstform);
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
free(boundary);
|
break;
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1097,8 +1153,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
fileboundary,
|
fileboundary,
|
||||||
(file->showfilename?file->showfilename:
|
(file->showfilename?file->showfilename:
|
||||||
filebasename));
|
filebasename));
|
||||||
if(filebasename)
|
Curl_safefree(filebasename);
|
||||||
free(filebasename);
|
|
||||||
if(result)
|
if(result)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1115,8 +1170,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
"; filename=\"%s\"",
|
"; filename=\"%s\"",
|
||||||
(post->showfilename?post->showfilename:
|
(post->showfilename?post->showfilename:
|
||||||
filebasename));
|
filebasename));
|
||||||
if(filebasename)
|
Curl_safefree(filebasename);
|
||||||
free(filebasename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
@ -1140,11 +1194,8 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
break;
|
break;
|
||||||
curList = curList->next;
|
curList = curList->next;
|
||||||
}
|
}
|
||||||
if(result) {
|
if(result)
|
||||||
Curl_formclean(&firstform);
|
break;
|
||||||
free(boundary);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = AddFormDataf(&form, &size, "\r\n\r\n");
|
result = AddFormDataf(&form, &size, "\r\n\r\n");
|
||||||
if(result)
|
if(result)
|
||||||
@ -1166,7 +1217,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
|
|
||||||
if(fileread) {
|
if(fileread) {
|
||||||
if(fileread != stdin) {
|
if(fileread != stdin) {
|
||||||
/* close the file again */
|
/* close the file */
|
||||||
fclose(fileread);
|
fclose(fileread);
|
||||||
/* add the file name only - for later reading from this */
|
/* add the file name only - for later reading from this */
|
||||||
result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
|
result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
|
||||||
@ -1210,11 +1261,8 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
file = file->more;
|
file = file->more;
|
||||||
} while(file && !result); /* for each specified file for this field */
|
} while(file && !result); /* for each specified file for this field */
|
||||||
|
|
||||||
if(result) {
|
if(result)
|
||||||
Curl_formclean(&firstform);
|
break;
|
||||||
free(boundary);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(post->more) {
|
if(post->more) {
|
||||||
/* this was a multiple-file inclusion, make a termination file
|
/* this was a multiple-file inclusion, make a termination file
|
||||||
@ -1222,33 +1270,31 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
result = AddFormDataf(&form, &size,
|
result = AddFormDataf(&form, &size,
|
||||||
"\r\n--%s--",
|
"\r\n--%s--",
|
||||||
fileboundary);
|
fileboundary);
|
||||||
free(fileboundary);
|
|
||||||
if(result)
|
if(result)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while((post = post->next) != NULL); /* for each field */
|
} while((post = post->next) != NULL); /* for each field */
|
||||||
if(result) {
|
|
||||||
Curl_formclean(&firstform);
|
|
||||||
free(boundary);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end-boundary for everything */
|
/* end-boundary for everything */
|
||||||
result = AddFormDataf(&form, &size,
|
if(CURLE_OK == result)
|
||||||
"\r\n--%s--\r\n",
|
result = AddFormDataf(&form, &size,
|
||||||
boundary);
|
"\r\n--%s--\r\n",
|
||||||
|
boundary);
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
Curl_formclean(&firstform);
|
Curl_formclean(&firstform);
|
||||||
free(boundary);
|
Curl_safefree(fileboundary);
|
||||||
|
Curl_safefree(boundary);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sizep = size;
|
*sizep = size;
|
||||||
|
|
||||||
free(boundary);
|
Curl_safefree(fileboundary);
|
||||||
|
Curl_safefree(boundary);
|
||||||
|
|
||||||
*finalform=firstform;
|
*finalform = firstform;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user