#include "memdebug.h" /* keep this as LAST include */
-/* Macros to free const pointers. */
-#define CONST_FREE(x) free((void *) (x))
-#define CONST_SAFEFREE(x) Curl_safefree(*((void **) &(x)))
-
/* tool_mime functions. */
static struct tool_mime *tool_mime_new(struct tool_mime *parent,
toolmimekind kind)
}
static struct tool_mime *tool_mime_new_data(struct tool_mime *parent,
- const char *data)
+ char *data)
{
struct tool_mime *m = NULL;
if(data) {
m = tool_mime_new(parent, TOOLMIME_DATA);
if(!m)
- CONST_FREE(data);
+ free(data);
else
m->data = data;
}
*errcode = CURLE_OUT_OF_MEMORY;
if(strcmp(filename, "-")) {
/* This is a normal file. */
- filename = strdup(filename);
- if(filename) {
+ char *filedup = strdup(filename);
+ if(filedup) {
m = tool_mime_new(parent, TOOLMIME_FILE);
if(!m)
- CONST_FREE(filename);
+ free(filedup);
else {
- m->data = filename;
+ m->data = filedup;
if(!isremotefile)
m->kind = TOOLMIME_FILEDATA;
*errcode = CURLE_OK;
tool_mime_free(mime->subparts);
if(mime->prev)
tool_mime_free(mime->prev);
- CONST_SAFEFREE(mime->name);
- CONST_SAFEFREE(mime->filename);
- CONST_SAFEFREE(mime->type);
- CONST_SAFEFREE(mime->encoder);
- CONST_SAFEFREE(mime->data);
+ Curl_safefree(mime->name);
+ Curl_safefree(mime->filename);
+ Curl_safefree(mime->type);
+ Curl_safefree(mime->encoder);
+ Curl_safefree(mime->data);
curl_slist_free_all(mime->headers);
free(mime);
}
*
***************************************************************************/
-/* Convenience macros for null pointer check. */
-#define NULL_CHECK(ptr, init, retcode) \
+#define SET_TOOL_MIME_PTR(m, field) \
do { \
- (ptr) = (init); \
- if(!(ptr)) { \
- warnf(config->global, "out of memory!\n"); \
- curl_slist_free_all(headers); \
- Curl_safefree(contents); \
- return retcode; \
+ if(field) { \
+ (m)->field = strdup(field); \
+ if(!(m)->field) \
+ goto fail; \
} \
} while(0)
-#define SET_TOOL_MIME_PTR(m, field, retcode) \
- do { \
- if(field) \
- NULL_CHECK((m)->field, strdup(field), retcode); \
- } while(0)
-
int formparse(struct OperationConfig *config,
const char *input,
struct tool_mime **mimeroot,
struct curl_slist *headers = NULL;
struct tool_mime *part = NULL;
CURLcode res;
+ int err = 1;
/* Allocate the main mime structure if needed. */
if(!*mimecurrent) {
- NULL_CHECK(*mimeroot, tool_mime_new_parts(NULL), 1);
+ *mimeroot = tool_mime_new_parts(NULL);
+ if(!*mimeroot)
+ goto fail;
*mimecurrent = *mimeroot;
}
/* Make a copy we can overwrite. */
- NULL_CHECK(contents, strdup(input), 2);
+ contents = strdup(input);
+ if(!contents)
+ goto fail;
/* Scan for the end of the name. */
contp = strchr(contents, '=');
/* Starting a multipart. */
sep = get_param_part(config, '\0',
&contp, &data, &type, NULL, NULL, &headers);
- if(sep < 0) {
- Curl_safefree(contents);
- return 3;
- }
- NULL_CHECK(part, tool_mime_new_parts(*mimecurrent), 4);
+ if(sep < 0)
+ goto fail;
+ part = tool_mime_new_parts(*mimecurrent);
+ if(!part)
+ goto fail;
*mimecurrent = part;
part->headers = headers;
headers = NULL;
- SET_TOOL_MIME_PTR(part, type, 5);
+ SET_TOOL_MIME_PTR(part, type);
}
else if(!name && !strcmp(contp, ")") && !literal_value) {
/* Ending a multipart. */
if(*mimecurrent == *mimeroot) {
warnf(config->global, "no multipart to terminate!\n");
- Curl_safefree(contents);
- return 6;
- }
+ goto fail;
+ }
*mimecurrent = (*mimecurrent)->parent;
}
else if('@' == contp[0] && !literal_value) {
sep = get_param_part(config, ',', &contp,
&data, &type, &filename, &encoder, &headers);
if(sep < 0) {
- Curl_safefree(contents);
- return 7;
+ goto fail;
}
/* now contp point to comma or string end.
if(!subparts) {
if(sep != ',') /* If there is a single file. */
subparts = *mimecurrent;
- else
- NULL_CHECK(subparts, tool_mime_new_parts(*mimecurrent), 8);
+ else {
+ subparts = tool_mime_new_parts(*mimecurrent);
+ if(!subparts)
+ goto fail;
+ }
}
/* Store that file in a part. */
- NULL_CHECK(part,
- tool_mime_new_filedata(subparts, data, TRUE, &res), 9);
+ part = tool_mime_new_filedata(subparts, data, TRUE, &res);
+ if(!part)
+ goto fail;
part->headers = headers;
headers = NULL;
part->config = config->global;
if(part->size > 0) {
warnf(config->global,
"error while reading standard input\n");
- Curl_safefree(contents);
- return 10;
+ goto fail;
}
- CONST_SAFEFREE(part->data);
+ Curl_safefree(part->data);
part->data = NULL;
part->size = -1;
res = CURLE_OK;
}
- SET_TOOL_MIME_PTR(part, filename, 11);
- SET_TOOL_MIME_PTR(part, type, 12);
- SET_TOOL_MIME_PTR(part, encoder, 13);
+ SET_TOOL_MIME_PTR(part, filename);
+ SET_TOOL_MIME_PTR(part, type);
+ SET_TOOL_MIME_PTR(part, encoder);
/* *contp could be '\0', so we just check with the delimiter */
} while(sep); /* loop if there's another file name */
++contp;
sep = get_param_part(config, '\0', &contp,
&data, &type, NULL, &encoder, &headers);
- if(sep < 0) {
- Curl_safefree(contents);
- return 14;
- }
+ if(sep < 0)
+ goto fail;
- NULL_CHECK(part, tool_mime_new_filedata(*mimecurrent, data, FALSE,
- &res), 15);
+ part = tool_mime_new_filedata(*mimecurrent, data, FALSE,
+ &res);
+ if(!part)
+ goto fail;
part->headers = headers;
headers = NULL;
part->config = config->global;
if(part->size > 0) {
warnf(config->global,
"error while reading standard input\n");
- Curl_safefree(contents);
- return 16;
+ goto fail;
}
- CONST_SAFEFREE(part->data);
+ Curl_safefree(part->data);
part->data = NULL;
part->size = -1;
res = CURLE_OK;
else {
sep = get_param_part(config, '\0', &contp,
&data, &type, &filename, &encoder, &headers);
- if(sep < 0) {
- Curl_safefree(contents);
- return 17;
- }
+ if(sep < 0)
+ goto fail;
}
- NULL_CHECK(part, tool_mime_new_data(*mimecurrent, data), 18);
+ part = tool_mime_new_data(*mimecurrent, data);
+ if(!part)
+ goto fail;
part->headers = headers;
headers = NULL;
}
- SET_TOOL_MIME_PTR(part, filename, 19);
- SET_TOOL_MIME_PTR(part, type, 20);
- SET_TOOL_MIME_PTR(part, encoder, 21);
+ SET_TOOL_MIME_PTR(part, filename);
+ SET_TOOL_MIME_PTR(part, type);
+ SET_TOOL_MIME_PTR(part, encoder);
if(sep) {
*contp = (char) sep;
}
/* Set part name. */
- SET_TOOL_MIME_PTR(part, name, 22);
+ SET_TOOL_MIME_PTR(part, name);
}
else {
warnf(config->global, "Illegally formatted input field!\n");
- Curl_safefree(contents);
- return 23;
+ goto fail;
}
+ err = 0;
+ fail:
Curl_safefree(contents);
- return 0;
+ curl_slist_free_all(headers);
+ return err;
}