1
0
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:
Yang Tse 2011-12-21 15:38:47 +01:00
parent 1dd654644a
commit 1afbccc676

View File

@ -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;
} }