From c2a809cd265c37e7bbef55e64d70114d2f0d7189 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 29 Feb 2016 20:32:08 +0100 Subject: [PATCH] formpost: fix memory leaks in AddFormData error branches Reported-by: Dmitry-Me Fixes #688 --- lib/formdata.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/formdata.c b/lib/formdata.c index 5ccb9d8b7..454be7610 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -825,28 +825,34 @@ static CURLcode AddFormData(struct FormData **formp, curl_off_t length, curl_off_t *size) { - struct FormData *newform = malloc(sizeof(struct FormData)); + struct FormData *newform; + char *alloc2 = NULL; + CURLcode result = CURLE_OK; + if(length < 0 || (size && *size < 0)) + return CURLE_BAD_FUNCTION_ARGUMENT; + + newform = malloc(sizeof(struct FormData)); if(!newform) return CURLE_OUT_OF_MEMORY; newform->next = NULL; - if(length < 0 || (size && *size < 0)) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(type <= FORM_CONTENT) { /* we make it easier for plain strings: */ if(!length) length = strlen((char *)line); #if (SIZEOF_SIZE_T < CURL_SIZEOF_CURL_OFF_T) - else if(length >= (curl_off_t)(size_t)-1) - return CURLE_BAD_FUNCTION_ARGUMENT; + else if(length >= (curl_off_t)(size_t)-1) { + result = CURLE_BAD_FUNCTION_ARGUMENT; + goto error; + } #endif newform->line = malloc((size_t)length+1); if(!newform->line) { - free(newform); - return CURLE_OUT_OF_MEMORY; + result = CURLE_OUT_OF_MEMORY; + goto error; } + alloc2 = newform->line; memcpy(newform->line, line, (size_t)length); newform->length = (size_t)length; newform->line[(size_t)length]=0; /* zero terminate for easier debugging */ @@ -877,12 +883,20 @@ static CURLcode AddFormData(struct FormData **formp, struct_stat file; if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode)) *size += filesize(newform->line, file); - else - return CURLE_BAD_FUNCTION_ARGUMENT; + else { + result = CURLE_BAD_FUNCTION_ARGUMENT; + goto error; + } } } } return CURLE_OK; + error: + if(newform) + free(newform); + if(alloc2) + free(alloc2); + return result; } /*