improved cleaning up in case of memory allocation failures

This commit is contained in:
Daniel Stenberg 2004-05-12 09:02:23 +00:00
parent d301d69fbf
commit 005042e973
2 changed files with 56 additions and 14 deletions

View File

@ -370,7 +370,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
struct curl_httppost **last_post, struct curl_httppost **last_post,
va_list params) va_list params)
{ {
FormInfo *first_form, *current_form, *form; FormInfo *first_form, *current_form, *form = NULL;
CURLFORMcode return_value = CURL_FORMADD_OK; CURLFORMcode return_value = CURL_FORMADD_OK;
const char *prevtype = NULL; const char *prevtype = NULL;
struct curl_httppost *post = NULL; struct curl_httppost *post = NULL;
@ -490,6 +490,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
array_value:va_arg(params, char *); array_value:va_arg(params, char *);
if (filename) { if (filename) {
current_form->value = strdup(filename); current_form->value = strdup(filename);
if(!current_form->value)
return_value = CURL_FORMADD_MEMORY;
else
current_form->flags |= HTTPPOST_READFILE; current_form->flags |= HTTPPOST_READFILE;
} }
else else
@ -517,11 +520,17 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
return_value = CURL_FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
} }
else { else {
if (filename) if (filename) {
current_form->value = strdup(filename); 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 else
return_value = CURL_FORMADD_NULL; return_value = CURL_FORMADD_NULL;
current_form->flags |= HTTPPOST_FILENAME;
} }
break; break;
} }
@ -545,8 +554,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
return_value = CURL_FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
} }
else { else {
if (filename) if (filename) {
current_form->value = strdup(filename); current_form->value = strdup(filename);
if(!current_form->value)
return_value = CURL_FORMADD_MEMORY;
}
else else
return_value = CURL_FORMADD_NULL; return_value = CURL_FORMADD_NULL;
current_form->flags |= HTTPPOST_BUFFER; current_form->flags |= HTTPPOST_BUFFER;
@ -595,8 +607,13 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
return_value = CURL_FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
} }
else { else {
if (contenttype) if (contenttype) {
current_form->contenttype = strdup(contenttype); current_form->contenttype = strdup(contenttype);
if(!current_form->contenttype)
return_value = CURL_FORMADD_MEMORY;
else
current_form->contenttype_alloc = TRUE;
}
else else
return_value = CURL_FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
@ -623,8 +640,13 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
va_arg(params, char *); va_arg(params, char *);
if( current_form->showfilename ) if( current_form->showfilename )
return_value = CURL_FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else else {
current_form->showfilename = strdup(filename); current_form->showfilename = strdup(filename);
if(!current_form->showfilename)
return_value = CURL_FORMADD_MEMORY;
else
current_form->showfilename_alloc = TRUE;
}
break; break;
} }
default: default:
@ -663,6 +685,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
/* our contenttype is missing */ /* our contenttype is missing */
form->contenttype form->contenttype
= strdup(ContentTypeForFilename(form->value, prevtype)); = strdup(ContentTypeForFilename(form->value, prevtype));
if(!form->contenttype) {
return_value = CURL_FORMADD_MEMORY;
break;
}
form->contenttype_alloc = TRUE;
} }
if ( !(form->flags & HTTPPOST_PTRNAME) && if ( !(form->flags & HTTPPOST_PTRNAME) &&
(form == first_form) ) { (form == first_form) ) {
@ -705,12 +732,20 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
} }
} }
if(return_value && form) { if(return_value) {
/* we return on error, free possibly allocated fields */ /* we return on error, free possibly allocated fields */
if(!form)
form = current_form;
if(form) {
if(form->name_alloc) if(form->name_alloc)
free(form->name); free(form->name);
if(form->value_alloc) if(form->value_alloc)
free(form->value); free(form->value);
if(form->contenttype_alloc)
free(form->contenttype);
if(form->showfilename_alloc)
free(form->showfilename);
}
} }
/* always delete the allocated memory before returning */ /* always delete the allocated memory before returning */
@ -840,6 +875,9 @@ void Curl_formclean(struct FormData *form)
{ {
struct FormData *next; struct FormData *next;
if(!form)
return;
do { do {
next=form->next; /* the following form line */ next=form->next; /* the following form line */
free(form->line); /* free the line */ free(form->line); /* free the line */
@ -907,6 +945,8 @@ CURLcode Curl_getFormData(struct FormData **finalform,
return result; /* no input => no output! */ return result; /* no input => no output! */
boundary = Curl_FormBoundary(); boundary = Curl_FormBoundary();
if(!boundary)
return CURLE_OUT_OF_MEMORY;
/* Make the first line of the output */ /* Make the first line of the output */
result = AddFormDataf(&form, NULL, result = AddFormDataf(&form, NULL,
@ -1054,14 +1094,14 @@ CURLcode Curl_getFormData(struct FormData **finalform,
if (result) if (result)
break; break;
} }
if(fileread != stdin)
fclose(fileread);
if (result) { if (result) {
Curl_formclean(firstform); Curl_formclean(firstform);
free(boundary); free(boundary);
return result; return result;
} }
if(fileread != stdin)
fclose(fileread);
} }
else { else {
Curl_formclean(firstform); Curl_formclean(firstform);

View File

@ -45,11 +45,13 @@ typedef struct FormInfo {
bool value_alloc; bool value_alloc;
size_t contentslength; size_t contentslength;
char *contenttype; char *contenttype;
bool contenttype_alloc;
long flags; 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 file name to show. If not set, the actual char *showfilename; /* The file name to show. If not set, the actual
file name will be used */ file name will be used */
bool showfilename_alloc;
struct curl_slist* contentheader; struct curl_slist* contentheader;
struct FormInfo *more; struct FormInfo *more;
} FormInfo; } FormInfo;