From ae1912cb0d494b48d514d937826c9fe83ec96c4d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 29 Dec 1999 14:20:26 +0000 Subject: Initial revision --- lib/formdata.c | 617 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 617 insertions(+) create mode 100644 lib/formdata.c (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c new file mode 100644 index 000000000..eff0212e4 --- /dev/null +++ b/lib/formdata.c @@ -0,0 +1,617 @@ +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Curl. + * + * The Initial Developer of the Original Code is Daniel Stenberg. + * + * Portions created by the Initial Developer are Copyright (C) 1998. + * All Rights Reserved. + * + * ------------------------------------------------------------ + * Main author: + * - Daniel Stenberg + * + * http://curl.haxx.nu + * + * $Source$ + * $Revision$ + * $Date$ + * $Author$ + * $State$ + * $Locker$ + * + * ------------------------------------------------------------ + ****************************************************************************/ + +/* + Debug the form generator stand-alone by compiling this source file with: + + gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c + + run the 'formdata' executable and make sure the output is ok! + + try './formdata "name=Daniel" "poo=noo" "foo=bar"' and similarly + + */ + +#include +#include +#include +#include + +#include + +#include "setup.h" +#include +#include "formdata.h" + +/* Length of the random boundary string. The risk of this being used + in binary data is very close to zero, 64^32 makes + 6277101735386680763835789423207666416102355444464034512896 + combinations... */ +#define BOUNDARY_LENGTH 32 + +/* What kind of Content-Type to use on un-specified files with unrecognized + extensions. */ +#define HTTPPOST_CONTENTTYPE_DEFAULT "text/plain" + +/* This is a silly duplicate of the function in main.c to enable this source + to compile stand-alone for better debugging */ +static void GetStr(char **string, + char *value) +{ + if(*string) + free(*string); + *string = strdup(value); +} + +/*************************************************************************** + * + * FormParse() + * + * Reads a 'name=value' paramter and builds the appropriate linked list. + * + * Specify files to upload with 'name=@filename'. Supports specified + * given Content-Type of the files. Such as ';type='. + * + * You may specify more than one file for a single name (field). Specify + * multiple files by writing it like: + * + * 'name=@filename,filename2,filename3' + * + * If you want content-types specified for each too, write them like: + * + * 'name=@filename;type=image/gif,filename2,filename3' + * + ***************************************************************************/ + +int curl_FormParse(char *input, + struct HttpPost **httppost, + struct HttpPost **last_post) +{ + return FormParse(input, httppost, last_post); +} + +#define FORM_FILE_SEPARATOR ',' +#define FORM_TYPE_SEPARATOR ';' + +int FormParse(char *input, + struct HttpPost **httppost, + struct HttpPost **last_post) +{ + /* nextarg MUST be a string in the format 'name=contents' and we'll + build a linked list with the info */ + char name[256]; + char contents[1024]=""; + char major[128]; + char minor[128]; + long flags = 0; + char *contp; + char *type = NULL; + char *prevtype = NULL; + char *sep; + char *sep2; + struct HttpPost *post; + struct HttpPost *subpost; /* a sub-node */ + unsigned int i; + + if(1 <= sscanf(input, "%255[^ =] = %1023[^\n]", name, contents)) { + /* the input was using the correct format */ + contp = contents; + + if('@' == contp[0]) { + /* we use the @-letter to indicate file name(s) */ + + flags = HTTPPOST_FILENAME; + contp++; + + post=NULL; + + do { + /* since this was a file, it may have a content-type specifier + at the end too */ + + sep=strchr(contp, FORM_TYPE_SEPARATOR); + sep2=strchr(contp, FORM_FILE_SEPARATOR); + + /* pick the closest */ + if(sep2 && (sep2 < sep)) { + sep = sep2; + + /* no type was specified! */ + } + if(sep) { + + /* if we got here on a comma, don't do much */ + if(FORM_FILE_SEPARATOR != *sep) + type = strstr(sep+1, "type="); + else + type=NULL; + + *sep=0; /* terminate file name at separator */ + + if(type) { + type += strlen("type="); + + if(2 != sscanf(type, "%127[^/]/%127[^,\n]", + major, minor)) { + fprintf(stderr, "Illegally formatted content-type field!\n"); + return 2; /* illegal content-type syntax! */ + } + /* now point beyond the content-type specifier */ + sep = type + strlen(major)+strlen(minor)+1; + + /* find the following comma */ + sep=strchr(sep, FORM_FILE_SEPARATOR); + } + } + else { + type=NULL; + sep=strchr(contp, FORM_FILE_SEPARATOR); + } + if(sep) { + /* the next file name starts here */ + *sep =0; + sep++; + } + if(!type) { + /* + * No type was specified, we scan through a few well-known + * extensions and pick the first we match! + */ + struct ContentType { + char *extension; + char *type; + }; + static struct ContentType ctts[]={ + {".gif", "image/gif"}, + {".jpg", "image/jpeg"}, + {".jpeg", "image/jpeg"}, + {".txt", "text/plain"}, + {".html", "text/plain"} + }; + + if(prevtype) + /* default to the previously set/used! */ + type = prevtype; + else + /* It seems RFC1867 defines no Content-Type to default to + text/plain so we don't actually need to set this: */ + type = HTTPPOST_CONTENTTYPE_DEFAULT; + + for(i=0; i= strlen(ctts[i].extension)) { + if(strequal(contp + + strlen(contp) - strlen(ctts[i].extension), + ctts[i].extension)) { + type = ctts[i].type; + break; + } + } + } + /* we have a type by now */ + } + + if(NULL == post) { + /* For the first file name, we allocate and initiate the main list + node */ + + post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); + if(post) { + memset(post, 0, sizeof(struct HttpPost)); + GetStr(&post->name, name); /* get the name */ + GetStr(&post->contents, contp); /* get the contents */ + post->flags = flags; + if(type) { + GetStr(&post->contenttype, type); /* get type */ + prevtype=post->contenttype; /* point to the allocated string! */ + } + /* make the previous point to this */ + if(*last_post) + (*last_post)->next = post; + else + (*httppost) = post; + + (*last_post) = post; + } + + } + else { + /* we add a file name to the previously allocated node, known as + 'post' now */ + subpost =(struct HttpPost *)malloc(sizeof(struct HttpPost)); + if(subpost) { + memset(subpost, 0, sizeof(struct HttpPost)); + GetStr(&subpost->name, name); /* get the name */ + GetStr(&subpost->contents, contp); /* get the contents */ + subpost->flags = flags; + if(type) { + GetStr(&subpost->contenttype, type); /* get type */ + prevtype=subpost->contenttype; /* point to the allocated string! */ + } + /* now, point our 'more' to the original 'more' */ + subpost->more = post->more; + + /* then move the original 'more' to point to ourselves */ + post->more = subpost; + } + } + contp = sep; /* move the contents pointer to after the separator */ + } while(sep && *sep); /* loop if there's another file name */ + } + else { + post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); + if(post) { + memset(post, 0, sizeof(struct HttpPost)); + GetStr(&post->name, name); /* get the name */ + GetStr(&post->contents, contp); /* get the contents */ + post->flags = 0; + + /* make the previous point to this */ + if(*last_post) + (*last_post)->next = post; + else + (*httppost) = post; + + (*last_post) = post; + } + + } + + } + else { + fprintf(stderr, "Illegally formatted input field!\n"); + return 1; + } + return 0; +} + +static int AddFormData(struct FormData **formp, + void *line, + long length) +{ + struct FormData *newform = (struct FormData *) + malloc(sizeof(struct FormData)); + newform->next = NULL; + + /* we make it easier for plain strings: */ + if(!length) + length = strlen((char *)line); + + newform->line = (char *)malloc(length+1); + memcpy(newform->line, line, length+1); + newform->length = length; + + if(*formp) { + (*formp)->next = newform; + *formp = newform; + } + else + *formp = newform; + + return length; +} + + +static int AddFormDataf(struct FormData **formp, + char *fmt, ...) +{ + char s[1024]; + va_list ap; + va_start(ap, fmt); + vsprintf(s, fmt, ap); + va_end(ap); + + return AddFormData(formp, s, 0); +} + + +char *MakeFormBoundary(void) +{ + char *retstring; + static int randomizer=0; /* this is just so that two boundaries within + the same form won't be identical */ + int i; + + static char table64[]= + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + retstring = (char *)malloc(BOUNDARY_LENGTH); + + if(!retstring) + return NULL; /* failed */ + + srand(time(NULL)+randomizer++); /* seed */ + + strcpy(retstring, "curl"); /* bonus commercials 8*) */ + + for(i=4; i<(BOUNDARY_LENGTH-1); i++) { + retstring[i] = table64[rand()%64]; + } + retstring[BOUNDARY_LENGTH-1]=0; /* zero terminate */ + + return retstring; +} + + +void FormFree(struct FormData *form) +{ + struct FormData *next; + do { + next=form->next; /* the following form line */ + free(form->line); /* free the line */ + free(form); /* free the struct */ + + } while(form=next); /* continue */ +} + +struct FormData *getFormData(struct HttpPost *post, + int *sizep) +{ + struct FormData *form = NULL; + struct FormData *firstform; + + struct HttpPost *file; + + int size =0; + char *boundary; + char *fileboundary=NULL; + + if(!post) + return NULL; /* no input => no output! */ + + boundary = MakeFormBoundary(); + + /* Make the first line of the output */ + AddFormDataf(&form, + "Content-Type: multipart/form-data;" + " boundary=%s\r\n", + boundary); + /* we DO NOT count that line since that'll be part of the header! */ + + firstform = form; + + do { + + /* boundary */ + size += AddFormDataf(&form, "\r\n--%s\r\n", boundary); + + size += AddFormDataf(&form, + "Content-Disposition: form-data; name=\"%s\"", + post->name); + + if(post->more) { + /* 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 */ + + fileboundary = MakeFormBoundary(); + + size += AddFormDataf(&form, + "\r\nContent-Type: multipart/mixed," + " boundary=%s\r\n", + fileboundary); + } + + file = post; + + do { + if(post->more) { + /* if multiple-file */ + size += AddFormDataf(&form, + "\r\n--%s\r\nContent-Disposition: attachment; filename=\"%s\"", + fileboundary, file->contents); + } + else if(post->flags & HTTPPOST_FILENAME) { + size += AddFormDataf(&form, + "; filename=\"%s\"", + post->contents); + } + + if(file->contenttype) { + /* we have a specified type */ + size += AddFormDataf(&form, + "\r\nContent-Type: %s", + file->contenttype); + } + if(file->contenttype && + !strnequal("text/", file->contenttype, 5)) { + /* this is not a text content, mention our binary encoding */ + size += AddFormDataf(&form, + "\r\nContent-Transfer-Encoding: binary"); + } + + + size += AddFormDataf(&form, + "\r\n\r\n"); + + if(post->flags & HTTPPOST_FILENAME) { + /* we should include the contents from the specified file */ + FILE *fileread; + char buffer[1024]; + int nread; + + fileread = strequal("-", file->contents)?stdin: + /* binary read for win32 crap */ + fopen(file->contents, "rb"); + if(fileread) { + while((nread = fread(buffer, 1, 1024, fileread))) { + size += AddFormData(&form, + buffer, + nread); + } + if(fileread != stdin) + fclose(fileread); + } + else { + size += AddFormDataf(&form, "[File wasn't found by client]"); + } + } + else { + /* include the contents we got */ + size += AddFormDataf(&form, + post->contents); + } + } while((file = file->more)); /* for each specified file for this field */ + + if(post->more) { + /* this was a multiple-file inclusion, make a termination file + boundary: */ + size += AddFormDataf(&form, + "\r\n--%s--", + fileboundary); + free(fileboundary); + } + + } while((post=post->next)); /* for each field */ + + /* end-boundary for everything */ + size += AddFormDataf(&form, + "\r\n--%s--\r\n", + boundary); + + *sizep = size; + + free(boundary); + + return firstform; +} + +int FormInit(struct Form *form, struct FormData *formdata ) +{ + form->data = formdata; + form->sent = 0; + + if(!formdata) + return 1; /* error */ + + return 0; +} + +/* fread() emulation */ +int FormReader(char *buffer, + size_t size, + size_t nitems, + FILE *mydata) +{ + struct Form *form; + int wantedsize; + int gotsize; + + form=(struct Form *)mydata; + + wantedsize = size * nitems; + + if(!form->data) + return 0; /* nothing, error, empty */ + + do { + + if( (form->data->length - form->sent ) > wantedsize ) { + + memcpy(buffer, form->data->line + form->sent, wantedsize); + + form->sent += wantedsize; + + return wantedsize; + } + + memcpy(buffer, + form->data->line + form->sent, + gotsize = (form->data->length - form->sent) ); + + form->sent = 0; + + form->data = form->data->next; /* advance */ + + } while(!gotsize && form->data); + /* If we got an empty line and we have more data, we proceed to the next + line immediately to avoid returning zero before we've reached the end. + This is the bug reported November 22 1999 on curl 6.3. (Daniel) */ + + return gotsize; +} + + +#ifdef _FORM_DEBUG + +int main(int argc, char **argv) +{ +#if 0 + char *testargs[]={ + "name1 = data in number one", + "name2 = number two data", + "test = @upload" + }; +#endif + int i; + char *nextarg; + struct HttpPost *httppost=NULL; + struct HttpPost *last_post=NULL; + struct HttpPost *post; + int size; + int nread; + char buffer[4096]; + + struct FormData *form; + struct Form formread; + + for(i=1; i Date: Mon, 22 May 2000 14:12:12 +0000 Subject: moved here from the newlib branch --- lib/formdata.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index eff0212e4..fb6ad0f69 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -60,6 +60,8 @@ #include #include "formdata.h" +#include "strequal.h" + /* Length of the random boundary string. The risk of this being used in binary data is very close to zero, 64^32 makes 6277101735386680763835789423207666416102355444464034512896 @@ -377,7 +379,7 @@ void FormFree(struct FormData *form) free(form->line); /* free the line */ free(form); /* free the struct */ - } while(form=next); /* continue */ + } while((form=next)); /* continue */ } struct FormData *getFormData(struct HttpPost *post, @@ -513,11 +515,16 @@ struct FormData *getFormData(struct HttpPost *post, int FormInit(struct Form *form, struct FormData *formdata ) { - form->data = formdata; - form->sent = 0; - if(!formdata) return 1; /* error */ + + /* First, make sure that we'll send a nice terminating sequence at the end + * of the post. We *DONT* add this string to the size of the data since this + * is actually AFTER the data. */ + AddFormDataf(&formdata, "\r\n\r\n"); + + form->data = formdata; + form->sent = 0; return 0; } -- cgit v1.2.1 From 476e0502ad4effcf7e69334426b5c8902088c7e9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Jun 2000 08:24:18 +0000 Subject: the curl_formparse() function was turned lowercase --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index fb6ad0f69..4eb2d94c2 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -102,7 +102,7 @@ static void GetStr(char **string, * ***************************************************************************/ -int curl_FormParse(char *input, +int curl_formparse(char *input, struct HttpPost **httppost, struct HttpPost **last_post) { -- cgit v1.2.1 From e9957b87cddec5ebba678be944c3d410843907e4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 15 Jun 2000 14:33:17 +0000 Subject: removed the last \r\n\r\n bytes now returns -1 from FormReader() when the last form data has been read! --- lib/formdata.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 4eb2d94c2..0cdf56889 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -318,6 +318,7 @@ static int AddFormData(struct FormData **formp, newform->line = (char *)malloc(length+1); memcpy(newform->line, line, length+1); newform->length = length; + newform->line[length]=0; /* zero terminate for easier debugging */ if(*formp) { (*formp)->next = newform; @@ -517,12 +518,20 @@ int FormInit(struct Form *form, struct FormData *formdata ) { if(!formdata) return 1; /* error */ - - /* First, make sure that we'll send a nice terminating sequence at the end + +#if 0 + struct FormData *lastnode=formdata; + + /* find the last node in the list */ + while(lastnode->next) { + lastnode = lastnode->next; + } + + /* Now, make sure that we'll send a nice terminating sequence at the end * of the post. We *DONT* add this string to the size of the data since this * is actually AFTER the data. */ - AddFormDataf(&formdata, "\r\n\r\n"); - + AddFormDataf(&lastnode, "\r\n\r\n"); +#endif form->data = formdata; form->sent = 0; @@ -544,7 +553,7 @@ int FormReader(char *buffer, wantedsize = size * nitems; if(!form->data) - return 0; /* nothing, error, empty */ + return -1; /* nothing, error, empty */ do { -- cgit v1.2.1 From 1ef3600a0731fef8f59563a1e49981f1b64b9746 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Jun 2000 15:31:26 +0000 Subject: haxx.nu => haxx.se --- lib/formdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 0cdf56889..bcdb71c11 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -24,9 +24,9 @@ * * ------------------------------------------------------------ * Main author: - * - Daniel Stenberg + * - Daniel Stenberg * - * http://curl.haxx.nu + * http://curl.haxx.se * * $Source$ * $Revision$ -- cgit v1.2.1 From 5b7a5046e6309710636c3347dba554b0b4a03c7c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Jul 2000 12:21:22 +0000 Subject: Torsten Foertsch's improvements --- lib/formdata.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index bcdb71c11..989ea1e7a 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -119,7 +119,7 @@ int FormParse(char *input, /* nextarg MUST be a string in the format 'name=contents' and we'll build a linked list with the info */ char name[256]; - char contents[1024]=""; + char contents[4096]=""; char major[128]; char minor[128]; long flags = 0; @@ -132,7 +132,7 @@ int FormParse(char *input, struct HttpPost *subpost; /* a sub-node */ unsigned int i; - if(1 <= sscanf(input, "%255[^ =] = %1023[^\n]", name, contents)) { + if(1 <= sscanf(input, "%255[^ =] = %4095[^\n]", name, contents)) { /* the input was using the correct format */ contp = contents; @@ -281,8 +281,14 @@ int FormParse(char *input, if(post) { memset(post, 0, sizeof(struct HttpPost)); GetStr(&post->name, name); /* get the name */ - GetStr(&post->contents, contp); /* get the contents */ - post->flags = 0; + if( contp[0]=='<' ) { + GetStr(&post->contents, contp+1); /* get the contents */ + post->flags = HTTPPOST_READFILE; + } + else { + GetStr(&post->contents, contp); /* get the contents */ + post->flags = 0; + } /* make the previous point to this */ if(*last_post) @@ -334,7 +340,7 @@ static int AddFormData(struct FormData **formp, static int AddFormDataf(struct FormData **formp, char *fmt, ...) { - char s[1024]; + char s[4096]; va_list ap; va_start(ap, fmt); vsprintf(s, fmt, ap); @@ -454,15 +460,14 @@ struct FormData *getFormData(struct HttpPost *post, if(file->contenttype && !strnequal("text/", file->contenttype, 5)) { /* this is not a text content, mention our binary encoding */ - size += AddFormDataf(&form, - "\r\nContent-Transfer-Encoding: binary"); + size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); } - size += AddFormDataf(&form, - "\r\n\r\n"); + size += AddFormData(&form, "\r\n\r\n", 0); - if(post->flags & HTTPPOST_FILENAME) { + if((post->flags & HTTPPOST_FILENAME) || + (post->flags & HTTPPOST_READFILE)) { /* we should include the contents from the specified file */ FILE *fileread; char buffer[1024]; @@ -479,15 +484,12 @@ struct FormData *getFormData(struct HttpPost *post, } if(fileread != stdin) fclose(fileread); + } else { + size += AddFormData(&form, "[File wasn't found by client]", 0); } - else { - size += AddFormDataf(&form, "[File wasn't found by client]"); - } - } - else { + } else { /* include the contents we got */ - size += AddFormDataf(&form, - post->contents); + size += AddFormData(&form, post->contents, 0); } } while((file = file->more)); /* for each specified file for this field */ -- cgit v1.2.1 From b6e18f2f665f16910c04cb52bdc7b90270ab7c9b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 24 Aug 2000 14:26:33 +0000 Subject: #include "setup.h" moved first of all includes --- lib/formdata.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 989ea1e7a..625b84ff3 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -49,6 +49,8 @@ */ +#include "setup.h" + #include #include #include @@ -56,7 +58,6 @@ #include -#include "setup.h" #include #include "formdata.h" -- cgit v1.2.1 From 0f8facb49b45a711fa7832c68260a5b45b362922 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 9 Oct 2000 11:12:34 +0000 Subject: added memory debugging include file --- lib/formdata.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 625b84ff3..11d459382 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -63,6 +63,11 @@ #include "strequal.h" +/* The last #include file should be: */ +#ifdef MALLOCDEBUG +#include "memdebug.h" +#endif + /* Length of the random boundary string. The risk of this being used in binary data is very close to zero, 64^32 makes 6277101735386680763835789423207666416102355444464034512896 -- cgit v1.2.1 From 111d1d09d3f9e6cea3ec89fadc028dd75b8a7b98 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 9 Oct 2000 22:29:35 +0000 Subject: removed the header that confuses PHP --- lib/formdata.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 11d459382..1e15f3ce4 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -463,12 +463,20 @@ struct FormData *getFormData(struct HttpPost *post, "\r\nContent-Type: %s", file->contenttype); } + +#if 0 + /* The header Content-Transfer-Encoding: seems to confuse some receivers + * (like the built-in PHP engine). While I can't see any reason why it + * should, I can just as well skip this to the benefit of the users who + * are using such confused receivers. + */ + if(file->contenttype && !strnequal("text/", file->contenttype, 5)) { /* this is not a text content, mention our binary encoding */ size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); } - +#endif size += AddFormData(&form, "\r\n\r\n", 0); -- cgit v1.2.1 From c0936824d4d45c4cdbaef180b21f87a0ea824120 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 17 Nov 2000 14:06:24 +0000 Subject: added curl_formfree() --- lib/formdata.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 1e15f3ce4..cee0b0b0e 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -382,8 +382,8 @@ char *MakeFormBoundary(void) return retstring; } - +/* Used from http.c */ void FormFree(struct FormData *form) { struct FormData *next; @@ -391,6 +391,28 @@ void FormFree(struct FormData *form) next=form->next; /* the following form line */ free(form->line); /* free the line */ free(form); /* free the struct */ + + } while((form=next)); /* continue */ +} + +/* external function to free up a whole form post chain */ +void curl_formfree(struct HttpPost *form) +{ + struct HttpPost *next; + do { + next=form->next; /* the following form line */ + + /* recurse to sub-contents */ + if(form->more) + curl_formfree(form->more); + + if(form->name) + free(form->name); /* free the name */ + if(form->contents) + free(form->contents); /* free the contents */ + if(form->contenttype) + free(form->contenttype); /* free the content type */ + free(form); /* free the struct */ } while((form=next)); /* continue */ } -- cgit v1.2.1 From 24dee483e9e925c2ab79dd582f70c9a55ab9ba4d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Jan 2001 09:29:33 +0000 Subject: dual-license fix --- lib/formdata.c | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index cee0b0b0e..8f86b980c 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,38 +5,21 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * The contents of this file are subject to the Mozilla Public License - * Version 1.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ + * Copyright (C) 2000, Daniel Stenberg, , et al. * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - * License for the specific language governing rights and limitations - * under the License. + * In order to be useful for every potential user, curl and libcurl are + * dual-licensed under the MPL and the MIT/X-derivate licenses. * - * The Original Code is Curl. + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the MPL or the MIT/X-derivate + * licenses. You may pick one of these licenses. * - * The Initial Developer of the Original Code is Daniel Stenberg. + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. * - * Portions created by the Initial Developer are Copyright (C) 1998. - * All Rights Reserved. - * - * ------------------------------------------------------------ - * Main author: - * - Daniel Stenberg - * - * http://curl.haxx.se - * - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * $State$ - * $Locker$ - * - * ------------------------------------------------------------ - ****************************************************************************/ + * $Id$ + *****************************************************************************/ /* Debug the form generator stand-alone by compiling this source file with: -- cgit v1.2.1 From 4031104404c6ceed5e57134125dcdb6cac51c564 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Jan 2001 10:11:41 +0000 Subject: Internal symbols that aren't static are now prefixed with 'Curl_' --- lib/formdata.c | 52 ++++++++++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 32 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 8f86b980c..14d911d35 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -91,16 +91,10 @@ static void GetStr(char **string, * ***************************************************************************/ -int curl_formparse(char *input, - struct HttpPost **httppost, - struct HttpPost **last_post) -{ - return FormParse(input, httppost, last_post); -} - #define FORM_FILE_SEPARATOR ',' #define FORM_TYPE_SEPARATOR ';' +static int FormParse(char *input, struct HttpPost **httppost, struct HttpPost **last_post) @@ -298,6 +292,13 @@ int FormParse(char *input, return 0; } +int curl_formparse(char *input, + struct HttpPost **httppost, + struct HttpPost **last_post) +{ + return FormParse(input, httppost, last_post); +} + static int AddFormData(struct FormData **formp, void *line, long length) @@ -339,7 +340,7 @@ static int AddFormDataf(struct FormData **formp, } -char *MakeFormBoundary(void) +char *Curl_FormBoundary(void) { char *retstring; static int randomizer=0; /* this is just so that two boundaries within @@ -367,7 +368,7 @@ char *MakeFormBoundary(void) } /* Used from http.c */ -void FormFree(struct FormData *form) +void Curl_FormFree(struct FormData *form) { struct FormData *next; do { @@ -400,8 +401,8 @@ void curl_formfree(struct HttpPost *form) } while((form=next)); /* continue */ } -struct FormData *getFormData(struct HttpPost *post, - int *sizep) +struct FormData *Curl_getFormData(struct HttpPost *post, + int *sizep) { struct FormData *form = NULL; struct FormData *firstform; @@ -415,7 +416,7 @@ struct FormData *getFormData(struct HttpPost *post, if(!post) return NULL; /* no input => no output! */ - boundary = MakeFormBoundary(); + boundary = Curl_FormBoundary(); /* Make the first line of the output */ AddFormDataf(&form, @@ -439,7 +440,7 @@ struct FormData *getFormData(struct HttpPost *post, /* 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 */ - fileboundary = MakeFormBoundary(); + fileboundary = Curl_FormBoundary(); size += AddFormDataf(&form, "\r\nContent-Type: multipart/mixed," @@ -535,24 +536,11 @@ struct FormData *getFormData(struct HttpPost *post, return firstform; } -int FormInit(struct Form *form, struct FormData *formdata ) +int Curl_FormInit(struct Form *form, struct FormData *formdata ) { if(!formdata) return 1; /* error */ -#if 0 - struct FormData *lastnode=formdata; - - /* find the last node in the list */ - while(lastnode->next) { - lastnode = lastnode->next; - } - - /* Now, make sure that we'll send a nice terminating sequence at the end - * of the post. We *DONT* add this string to the size of the data since this - * is actually AFTER the data. */ - AddFormDataf(&lastnode, "\r\n\r\n"); -#endif form->data = formdata; form->sent = 0; @@ -560,10 +548,10 @@ int FormInit(struct Form *form, struct FormData *formdata ) } /* fread() emulation */ -int FormReader(char *buffer, - size_t size, - size_t nitems, - FILE *mydata) +int Curl_FormReader(char *buffer, + size_t size, + size_t nitems, + FILE *mydata) { struct Form *form; int wantedsize; @@ -638,7 +626,7 @@ int main(int argc, char **argv) } } - form=getFormData(httppost, &size); + form=Curl_getFormData(httppost, &size); FormInit(&formread, form); -- cgit v1.2.1 From 53e3c225ee6db5da29050568f5173a77d060efde Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 6 Apr 2001 05:52:23 +0000 Subject: curl_formfree() can be called with a NULL argument --- lib/formdata.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 14d911d35..cadccb802 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -371,6 +371,7 @@ char *Curl_FormBoundary(void) void Curl_FormFree(struct FormData *form) { struct FormData *next; + do { next=form->next; /* the following form line */ free(form->line); /* free the line */ @@ -383,6 +384,11 @@ void Curl_FormFree(struct FormData *form) void curl_formfree(struct HttpPost *form) { struct HttpPost *next; + + if(!form) + /* no form to free, just get out of this */ + return; + do { next=form->next; /* the following form line */ -- cgit v1.2.1 From b1cd033c277d3b4b819458925db448fb7676ad80 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Jun 2001 11:27:40 +0000 Subject: made the test-program in the bottom compile/build, remember to link with strequal.o as well! --- lib/formdata.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index cadccb802..656e4de1b 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -634,11 +634,16 @@ int main(int argc, char **argv) form=Curl_getFormData(httppost, &size); - FormInit(&formread, form); + Curl_FormInit(&formread, form); - while(nread = FormReader(buffer, 1, sizeof(buffer), (FILE *)&formread)) { + do { + nread = Curl_FormReader(buffer, 1, sizeof(buffer), + (FILE *)&formread); + + if(-1 == nread) + break; fwrite(buffer, nread, 1, stderr); - } + } while(1); fprintf(stderr, "size: %d\n", size); -- cgit v1.2.1 From fa601af722c0701b812225ccf5da94b863983d61 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Jun 2001 09:39:35 +0000 Subject: Anton Kalmykov's fix for dealing with form names with spaces! --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 656e4de1b..e7e0dd9ee 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -115,7 +115,7 @@ int FormParse(char *input, struct HttpPost *subpost; /* a sub-node */ unsigned int i; - if(1 <= sscanf(input, "%255[^ =] = %4095[^\n]", name, contents)) { + if(1 <= sscanf(input, "%255[^=]=%4095[^\n]", name, contents)) { /* the input was using the correct format */ contp = contents; -- cgit v1.2.1 From 2cf45f68b095f478a8a80a2acb5e0ea54e49db70 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 Aug 2001 12:36:18 +0000 Subject: Curl_FormFree renamed to Curl_formclean, as it turns out VMS for example requires all global symbols to be *case insentively* unique! curl_formfree is a global function we shouldn't touch. --- lib/formdata.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index e7e0dd9ee..41629cc75 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -367,8 +367,8 @@ char *Curl_FormBoundary(void) return retstring; } -/* Used from http.c */ -void Curl_FormFree(struct FormData *form) +/* Used from http.c, this cleans a built FormData linked list */ +void Curl_formclean(struct FormData *form) { struct FormData *next; @@ -501,7 +501,9 @@ struct FormData *Curl_getFormData(struct HttpPost *post, fileread = strequal("-", file->contents)?stdin: /* binary read for win32 crap */ - fopen(file->contents, "rb"); +/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */ +/*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */ +/*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */ if(fileread) { while((nread = fread(buffer, 1, 1024, fileread))) { size += AddFormData(&form, -- cgit v1.2.1 From b49565308f6f2afe8ab7a193740653eced0b3892 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 13 Aug 2001 06:33:26 +0000 Subject: curl_formparse() should no longer have any size-limit in the data section after this patch from Peter Todd --- lib/formdata.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 41629cc75..06281f422 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -102,7 +102,7 @@ int FormParse(char *input, /* nextarg MUST be a string in the format 'name=contents' and we'll build a linked list with the info */ char name[256]; - char contents[4096]=""; + char *contents; char major[128]; char minor[128]; long flags = 0; @@ -115,7 +115,12 @@ int FormParse(char *input, struct HttpPost *subpost; /* a sub-node */ unsigned int i; - if(1 <= sscanf(input, "%255[^=]=%4095[^\n]", name, contents)) { + /* Preallocate contents to the length of input to make sure we don't + overwrite anything. */ + contents = malloc(strlen(input)); + contents[0] = '\000'; + + if(1 <= sscanf(input, "%255[^=]=%[^\n]", name, contents)) { /* the input was using the correct format */ contp = contents; @@ -156,6 +161,7 @@ int FormParse(char *input, if(2 != sscanf(type, "%127[^/]/%127[^,\n]", major, minor)) { fprintf(stderr, "Illegally formatted content-type field!\n"); + free(contents); return 2; /* illegal content-type syntax! */ } /* now point beyond the content-type specifier */ @@ -287,8 +293,10 @@ int FormParse(char *input, } else { fprintf(stderr, "Illegally formatted input field!\n"); + free(contents); return 1; } + free(contents); return 0; } -- cgit v1.2.1 From 5abe5f664afabfc68cae3abde56991f24301812b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 14 Aug 2001 08:23:20 +0000 Subject: added a few consts and a few typecasts to please picky compiler options --- lib/formdata.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 06281f422..e195e0ba2 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -107,7 +107,7 @@ int FormParse(char *input, char minor[128]; long flags = 0; char *contp; - char *type = NULL; + const char *type = NULL; char *prevtype = NULL; char *sep; char *sep2; @@ -165,7 +165,7 @@ int FormParse(char *input, return 2; /* illegal content-type syntax! */ } /* now point beyond the content-type specifier */ - sep = type + strlen(major)+strlen(minor)+1; + sep = (char *)type + strlen(major)+strlen(minor)+1; /* find the following comma */ sep=strchr(sep, FORM_FILE_SEPARATOR); @@ -186,10 +186,10 @@ int FormParse(char *input, * extensions and pick the first we match! */ struct ContentType { - char *extension; - char *type; + const char *extension; + const char *type; }; - static struct ContentType ctts[]={ + static struct ContentType ctts[]={ {".gif", "image/gif"}, {".jpg", "image/jpeg"}, {".jpeg", "image/jpeg"}, @@ -229,7 +229,7 @@ int FormParse(char *input, GetStr(&post->contents, contp); /* get the contents */ post->flags = flags; if(type) { - GetStr(&post->contenttype, type); /* get type */ + GetStr(&post->contenttype, (char *)type); /* get type */ prevtype=post->contenttype; /* point to the allocated string! */ } /* make the previous point to this */ @@ -252,8 +252,8 @@ int FormParse(char *input, GetStr(&subpost->contents, contp); /* get the contents */ subpost->flags = flags; if(type) { - GetStr(&subpost->contenttype, type); /* get type */ - prevtype=subpost->contenttype; /* point to the allocated string! */ + GetStr(&subpost->contenttype, (char *)type); /* get type */ + prevtype=subpost->contenttype; /* point to allocated string! */ } /* now, point our 'more' to the original 'more' */ subpost->more = post->more; @@ -308,8 +308,8 @@ int curl_formparse(char *input, } static int AddFormData(struct FormData **formp, - void *line, - long length) + const void *line, + long length) { struct FormData *newform = (struct FormData *) malloc(sizeof(struct FormData)); @@ -336,7 +336,7 @@ static int AddFormData(struct FormData **formp, static int AddFormDataf(struct FormData **formp, - char *fmt, ...) + const char *fmt, ...) { char s[4096]; va_list ap; -- cgit v1.2.1 From 08655d8d5d0ea980227096366c231693198e61d6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 Aug 2001 13:18:07 +0000 Subject: Georg Huettenegger's patch curl-7.8.1-pre5-patch-20010819 --- lib/formdata.c | 467 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 463 insertions(+), 4 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index e195e0ba2..9733e3d0f 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -24,7 +24,46 @@ /* Debug the form generator stand-alone by compiling this source file with: - gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c + gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c strequal.c + + run the 'formdata' executable the output should end with: + All Tests seem to have worked ... + and the following parts should be there: + +Content-Disposition: form-data; name="simple_COPYCONTENTS" +value for simple COPYCONTENTS + +Content-Disposition: form-data; name="COPYCONTENTS_+_CONTENTTYPE" +Content-Type: image/gif +value for COPYCONTENTS + CONTENTTYPE + +Content-Disposition: form-data; name="simple_PTRCONTENTS" +value for simple PTRCONTENTS + +Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH" +vlue for PTRCONTENTS + CONTENTSLENGTH +(or you might see v^@lue at the start) + +Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE" +Content-Type: text/plain +vlue for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE + +Content-Disposition: form-data; name="FILE1_+_CONTENTTYPE"; filename="inet_ntoa_r.h" +Content-Type: text/html +... + +Content-Disposition: form-data; name="FILE1_+_FILE2" +Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz +Content-Disposition: attachment; filename="inet_ntoa_r.h" +Content-Type: text/plain +... +Content-Disposition: attachment; filename="Makefile.b32.resp" +Content-Type: text/plain +... + + For the old FormParse used by curl_formparse use: + + gcc -DHAVE_CONFIG_H -I../ -g -D_OLD_FORM_DEBUG -o formdata -I../include formdata.c strequal.c run the 'formdata' executable and make sure the output is ok! @@ -64,7 +103,7 @@ /* This is a silly duplicate of the function in main.c to enable this source to compile stand-alone for better debugging */ static void GetStr(char **string, - char *value) + const char *value) { if(*string) free(*string); @@ -227,6 +266,7 @@ int FormParse(char *input, memset(post, 0, sizeof(struct HttpPost)); GetStr(&post->name, name); /* get the name */ GetStr(&post->contents, contp); /* get the contents */ + post->contentslength = 0; post->flags = flags; if(type) { GetStr(&post->contenttype, (char *)type); /* get type */ @@ -250,6 +290,7 @@ int FormParse(char *input, memset(subpost, 0, sizeof(struct HttpPost)); GetStr(&subpost->name, name); /* get the name */ GetStr(&subpost->contents, contp); /* get the contents */ + subpost->contentslength = 0; subpost->flags = flags; if(type) { GetStr(&subpost->contenttype, (char *)type); /* get type */ @@ -272,10 +313,12 @@ int FormParse(char *input, GetStr(&post->name, name); /* get the name */ if( contp[0]=='<' ) { GetStr(&post->contents, contp+1); /* get the contents */ + post->contentslength = 0; post->flags = HTTPPOST_READFILE; } else { GetStr(&post->contents, contp); /* get the contents */ + post->contentslength = 0; post->flags = 0; } @@ -307,6 +350,264 @@ int curl_formparse(char *input, return FormParse(input, httppost, last_post); } +/*************************************************************************** + * + * AddHttpPost() + * + * Adds a HttpPost structure to the list, if parent_post is given becomes + * a subpost of parent_post instead of a direct list element. + * + * Returns 0 on success and 1 if malloc failed. + * + ***************************************************************************/ +static struct HttpPost * AddHttpPost (char * name, + char * value, + long contentslength, + long flags, + struct HttpPost *parent_post, + struct HttpPost **httppost, + struct HttpPost **last_post) +{ + struct HttpPost *post; + post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); + if(post) { + memset(post, 0, sizeof(struct HttpPost)); + post->name = name; + post->contents = value; + post->contentslength = contentslength; + post->flags = flags; + } + else + return NULL; + + if (parent_post) { + /* now, point our 'more' to the original 'more' */ + post->more = parent_post->more; + + /* then move the original 'more' to point to ourselves */ + parent_post->more = post; + } + else { + /* make the previous point to this */ + if(*last_post) + (*last_post)->next = post; + else + (*httppost) = post; + + (*last_post) = post; + } + return post; +} + +/*************************************************************************** + * + * FormAdd() + * + * Stores a 'name=value' formpost parameter and builds the appropriate + * linked list. + * + * Has two principal functionalities: using files and byte arrays as + * post parts. Byte arrays are either copied or just the pointer is stored + * (as the user requests) while for files only the filename and not the + * content is stored. + * + * While you may have only one byte array for each name, multiple filenames + * are allowed (and because of this feature CURLFORM_END is needed after + * using CURLFORM_FILE). + * + * Examples: + * + * Simple name/value pair with copied contents: + * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_COPYCONTENTS, "value"); + * + * name/value pair where only the content pointer is remembered: + * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10); + * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used) + * + * storing a filename (CONTENTTYPE is optional!): + * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text", + * CURLFORM_END); + * + * storing multiple filenames: + * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); + * + * Returns 0 on success, 1 if the first option is not CURLFORM_COPYNAME, + * 2 if AddHttpPost failes, and 3 if an unknown option is encountered + * + ***************************************************************************/ + +static +int FormAdd(struct HttpPost **httppost, + struct HttpPost **last_post, + va_list params) +{ + int go_on = TRUE; + int read_argument = TRUE; + unsigned int i; + char *name; + char *value; + const char *prevtype = NULL; + struct HttpPost *post = NULL; + CURLformoption next_option; + + /* We always expect CURLFORM_COPYNAME first for the moment. */ + next_option = va_arg(params, CURLformoption); + if (next_option != CURLFORM_COPYNAME) + return 1; + + name = va_arg(params, char *); + do + { + /* if not already read read next argument */ + if (read_argument) + next_option = va_arg(params, CURLformoption); + else + read_argument = TRUE; + + switch (next_option) + { + case CURLFORM_COPYCONTENTS: + { /* simple name/value storage of duplicated data */ + const char * contenttype = NULL; + value = va_arg(params, char *); + next_option = va_arg(params, CURLformoption); + if (next_option == CURLFORM_CONTENTTYPE) + contenttype = va_arg(params, char *); + else + read_argument = FALSE; + if ((post = AddHttpPost(strdup(name), strdup(value), 0, 0, NULL, + httppost, last_post)) == NULL) { + return 2; + } + if (contenttype) + post->contenttype = strdup(contenttype); + /* at the moment no more options are allowd in this case */ + go_on = FALSE; + break; + } + case CURLFORM_PTRCONTENTS: + { /* name/value storage with value stored as a pointer */ + const char * contenttype = NULL; + void * ptr_contents = va_arg(params, void *); + long contentslength; + int got_contentslength = FALSE; + /* either use provided length or use strlen () to get it */ + next_option = va_arg(params, CURLformoption); + while ( (next_option == CURLFORM_CONTENTSLENGTH) || + (next_option == CURLFORM_CONTENTTYPE) ) { + if (next_option == CURLFORM_CONTENTSLENGTH) { + contentslength = va_arg(params, long); + got_contentslength = TRUE; + } + else { /* CURLFORM_CONTENTTYPE */ + contenttype = va_arg(params, char *); + } + next_option = va_arg(params, CURLformoption); + }; + /* we already read the next CURLformoption */ + read_argument = FALSE; + if (!got_contentslength) + /* no length given, use strlen to find out */ + contentslength = strlen (ptr_contents); + if ((post = AddHttpPost(strdup(name), ptr_contents, contentslength, + HTTPPOST_PTRCONTENTS, NULL, httppost, + last_post)) + == NULL) { + return 2; + } + if (contenttype) + post->contenttype = strdup(contenttype); + /* at the moment no more options are allowd in this case */ + go_on = FALSE; + break; + } + case CURLFORM_FILE: + { + const char * contenttype = NULL; + value = va_arg(params, char *); + next_option = va_arg(params, CURLformoption); + /* if contenttype was provided retrieve it */ + if (next_option == CURLFORM_CONTENTTYPE) { + contenttype = va_arg(params, char *); + } + else { + /* + * No type was specified, we scan through a few well-known + * extensions and pick the first we match! + */ + struct ContentType { + const char *extension; + const char *type; + }; + static struct ContentType ctts[]={ + {".gif", "image/gif"}, + {".jpg", "image/jpeg"}, + {".jpeg", "image/jpeg"}, + {".txt", "text/plain"}, + {".html", "text/plain"} + }; + + if(prevtype) + /* default to the previously set/used! */ + contenttype = prevtype; + else + /* It seems RFC1867 defines no Content-Type to default to + text/plain so we don't actually need to set this: */ + contenttype = HTTPPOST_CONTENTTYPE_DEFAULT; + + for(i=0; i= strlen(ctts[i].extension)) { + if(strequal(value + + strlen(value) - strlen(ctts[i].extension), + ctts[i].extension)) { + contenttype = ctts[i].type; + break; + } + } + } + /* we have a contenttype by now */ + /* do not try to read the next option we already did that */ + read_argument = FALSE; + } + if ( (post = AddHttpPost (strdup(name), strdup(value), 0, + HTTPPOST_FILENAME, post, httppost, + last_post)) == NULL) { + return 2; + } + post->contenttype = strdup (contenttype); + prevtype = post->contenttype; + /* we do not set go_on to false as multiple files are allowed */ + break; + } + case CURLFORM_END: + /* this ends our loop */ + break; + default: + fprintf (stderr, "got: %d\n", next_option); + return 3; + }; + + } while (go_on && next_option != CURLFORM_END); + + return 0; +} + +int curl_formadd(struct HttpPost **httppost, + struct HttpPost **last_post, + ...) +{ + va_list arg; + int result; + va_start(arg, last_post); + result = FormAdd(httppost, last_post, arg); + va_end(arg); + return result; +} + static int AddFormData(struct FormData **formp, const void *line, long length) @@ -406,7 +707,7 @@ void curl_formfree(struct HttpPost *form) if(form->name) free(form->name); /* free the name */ - if(form->contents) + if( !(form->flags & HTTPPOST_PTRCONTENTS) && form->contents) free(form->contents); /* free the contents */ if(form->contenttype) free(form->contenttype); /* free the content type */ @@ -525,7 +826,7 @@ struct FormData *Curl_getFormData(struct HttpPost *post, } } else { /* include the contents we got */ - size += AddFormData(&form, post->contents, 0); + size += AddFormData(&form, post->contents, post->contentslength); } } while((file = file->more)); /* for each specified file for this field */ @@ -568,6 +869,52 @@ int Curl_FormReader(char *buffer, size_t size, size_t nitems, FILE *mydata) +{ + struct Form *form; + int wantedsize; + int gotsize = 0; + + form=(struct Form *)mydata; + + wantedsize = size * nitems; + + if(!form->data) + return -1; /* nothing, error, empty */ + + do { + + if( (form->data->length - form->sent ) > wantedsize - gotsize) { + + memcpy(buffer + gotsize , form->data->line + form->sent, + wantedsize - gotsize); + + form->sent += wantedsize-gotsize; + + return wantedsize; + } + + memcpy(buffer+gotsize, + form->data->line + form->sent, + (form->data->length - form->sent) ); + gotsize += form->data->length - form->sent; + + form->sent = 0; + + form->data = form->data->next; /* advance */ + + } while(form->data); + /* If we got an empty line and we have more data, we proceed to the next + line immediately to avoid returning zero before we've reached the end. + This is the bug reported November 22 1999 on curl 6.3. (Daniel) */ + + return gotsize; +} + +/* possible (old) fread() emulation that copies at most one line */ +int Curl_FormReadOneLine(char *buffer, + size_t size, + size_t nitems, + FILE *mydata) { struct Form *form; int wantedsize; @@ -609,6 +956,118 @@ int Curl_FormReader(char *buffer, #ifdef _FORM_DEBUG +int FormAddTest(const char * errormsg, + struct HttpPost **httppost, + struct HttpPost **last_post, + ...) +{ + int result; + va_list arg; + CURLformoption next_option; + char * value; + va_start(arg, last_post); + if ((result = FormAdd(httppost, last_post, arg))) + fprintf (stderr, "ERROR doing FormAdd ret: %d action: %s\n", result, + errormsg); + va_end(arg); + return result; +} + + +int main() +{ + char name1[] = "simple_COPYCONTENTS"; + char name2[] = "COPYCONTENTS_+_CONTENTTYPE"; + char name3[] = "simple_PTRCONTENTS"; + char name4[] = "PTRCONTENTS_+_CONTENTSLENGTH"; + char name5[] = "PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE"; + char name6[] = "FILE1_+_CONTENTTYPE"; + char name7[] = "FILE1_+_FILE2"; + char value1[] = "value for simple COPYCONTENTS"; + char value2[] = "value for COPYCONTENTS + CONTENTTYPE"; + char value3[] = "value for simple PTRCONTENTS"; + char value4[] = "value for PTRCONTENTS + CONTENTSLENGTH"; + char value5[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE"; + char value6[] = "inet_ntoa_r.h"; + char value7[] = "Makefile.b32.resp"; + char type2[] = "image/gif"; + char type5[] = "text/plain"; + char type6[] = "text/html"; + int value4length = strlen(value4); + int value5length = strlen(value5); + int errors = 0; + int size; + int nread; + char buffer[4096]; + struct HttpPost *httppost=NULL; + struct HttpPost *last_post=NULL; + struct HttpPost *post; + + struct FormData *form; + struct Form formread; + + if (FormAddTest("simple COPYCONTENTS test", &httppost, &last_post, + CURLFORM_COPYNAME, name1, CURLFORM_COPYCONTENTS, value1, + CURLFORM_END)) + ++errors; + if (FormAddTest("COPYCONTENTS + CONTENTTYPE test", &httppost, &last_post, + CURLFORM_COPYNAME, name2, CURLFORM_COPYCONTENTS, value2, + CURLFORM_CONTENTTYPE, type2, CURLFORM_END)) + ++errors; + if (FormAddTest("simple PTRCONTENTS test", &httppost, &last_post, + CURLFORM_COPYNAME, name3, CURLFORM_PTRCONTENTS, value3, + CURLFORM_END)) + ++errors; + /* make null character at start to check that contentslength works + correctly */ + value4[1] = '\0'; + if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH test", &httppost, &last_post, + CURLFORM_COPYNAME, name4, CURLFORM_PTRCONTENTS, value4, + CURLFORM_CONTENTSLENGTH, value4length, CURLFORM_END)) + ++errors; + /* make null character at start to check that contentslength works + correctly */ + value5[1] = '\0'; + if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE test", + &httppost, &last_post, + CURLFORM_COPYNAME, name5, CURLFORM_PTRCONTENTS, value5, + CURLFORM_CONTENTSLENGTH, value5length, + CURLFORM_CONTENTTYPE, type5, CURLFORM_END)) + ++errors; + if (FormAddTest("FILE + CONTENTTYPE test", &httppost, &last_post, + CURLFORM_COPYNAME, name6, CURLFORM_FILE, value6, + CURLFORM_CONTENTTYPE, type6, CURLFORM_END)) + ++errors; + if (FormAddTest("FILE1 + FILE2 test", &httppost, &last_post, + CURLFORM_COPYNAME, name7, CURLFORM_FILE, value6, + CURLFORM_FILE, value7, CURLFORM_END)) + ++errors; + + form=Curl_getFormData(httppost, &size); + + Curl_FormInit(&formread, form); + + do { + nread = Curl_FormReader(buffer, 1, sizeof(buffer), + (FILE *)&formread); + + if(-1 == nread) + break; + fwrite(buffer, nread, 1, stderr); + } while(1); + + fprintf(stderr, "size: %d\n", size); + if (errors) + fprintf(stderr, "\n==> %d Test(s) failed!\n", errors); + else + fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n"); + + return 0; +} + +#endif + +#ifdef _OLD_FORM_DEBUG int main(int argc, char **argv) { -- cgit v1.2.1 From 725bd1dddf24d4775ebcbe6414f19517b2cd2a6c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 28 Aug 2001 08:54:33 +0000 Subject: Georg Huettenegger's fixes and improvements to curl_formadd() --- lib/formdata.c | 524 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 363 insertions(+), 161 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 9733e3d0f..bbca0b8f7 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2000, Daniel Stenberg, , et al. + * Copyright (C) 2001, Daniel Stenberg, , et al. * * In order to be useful for every potential user, curl and libcurl are * dual-licensed under the MPL and the MIT/X-derivate licenses. @@ -37,6 +37,10 @@ Content-Disposition: form-data; name="COPYCONTENTS_+_CONTENTTYPE" Content-Type: image/gif value for COPYCONTENTS + CONTENTTYPE +Content-Disposition: form-data; name="PRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH" +vlue for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH +(or you might see P^@RNAME and v^@lue at the start) + Content-Disposition: form-data; name="simple_PTRCONTENTS" value for simple PTRCONTENTS @@ -47,6 +51,7 @@ vlue for PTRCONTENTS + CONTENTSLENGTH Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE" Content-Type: text/plain vlue for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE +(or you might see v^@lue at the start) Content-Disposition: form-data; name="FILE1_+_CONTENTTYPE"; filename="inet_ntoa_r.h" Content-Type: text/html @@ -54,11 +59,25 @@ Content-Type: text/html Content-Disposition: form-data; name="FILE1_+_FILE2" Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz +... +Content-Disposition: attachment; filename="inet_ntoa_r.h" +Content-Type: text/plain +... +Content-Disposition: attachment; filename="Makefile.b32.resp" +Content-Type: text/plain +... + +Content-Disposition: form-data; name="FILE1_+_FILE2_+_FILE3" +Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 +... Content-Disposition: attachment; filename="inet_ntoa_r.h" Content-Type: text/plain ... Content-Disposition: attachment; filename="Makefile.b32.resp" Content-Type: text/plain +... +Content-Disposition: attachment; filename="inet_ntoa_r.h" +Content-Type: text/plain ... For the old FormParse used by curl_formparse use: @@ -357,12 +376,14 @@ int curl_formparse(char *input, * Adds a HttpPost structure to the list, if parent_post is given becomes * a subpost of parent_post instead of a direct list element. * - * Returns 0 on success and 1 if malloc failed. + * Returns newly allocated HttpPost on success and NULL if malloc failed. * ***************************************************************************/ static struct HttpPost * AddHttpPost (char * name, + long namelength, char * value, long contentslength, + char *contenttype, long flags, struct HttpPost *parent_post, struct HttpPost **httppost, @@ -373,8 +394,10 @@ static struct HttpPost * AddHttpPost (char * name, if(post) { memset(post, 0, sizeof(struct HttpPost)); post->name = name; + post->namelength = namelength; post->contents = value; post->contentslength = contentslength; + post->contenttype = contenttype; post->flags = flags; } else @@ -399,6 +422,125 @@ static struct HttpPost * AddHttpPost (char * name, return post; } +/*************************************************************************** + * + * AddFormInfo() + * + * Adds a FormInfo structure to the list presented by parent_form_info. + * + * Returns newly allocated FormInfo on success and NULL if malloc failed/ + * parent_form_info is NULL. + * + ***************************************************************************/ +static FormInfo * AddFormInfo (char *value, + char *contenttype, + FormInfo *parent_form_info) +{ + FormInfo *form_info; + form_info = (FormInfo *)malloc(sizeof(FormInfo)); + if(form_info) { + memset(form_info, 0, sizeof(FormInfo)); + if (value) + form_info->value = value; + if (contenttype) + form_info->contenttype = contenttype; + form_info->flags = HTTPPOST_FILENAME; + } + else + return NULL; + + if (parent_form_info) { + /* now, point our 'more' to the original 'more' */ + form_info->more = parent_form_info->more; + + /* then move the original 'more' to point to ourselves */ + parent_form_info->more = form_info; + } + else + return NULL; + + return form_info; +} + +/*************************************************************************** + * + * ContentTypeForFilename() + * + * Provides content type for filename if one of the known types (else + * (either the prevtype or the default is returned). + * + * Returns some valid contenttype for filename. + * + ***************************************************************************/ +static const char * ContentTypeForFilename (char *filename, + const char *prevtype) +{ + const char *contenttype = NULL; + unsigned int i; + /* + * No type was specified, we scan through a few well-known + * extensions and pick the first we match! + */ + struct ContentType { + const char *extension; + const char *type; + }; + static struct ContentType ctts[]={ + {".gif", "image/gif"}, + {".jpg", "image/jpeg"}, + {".jpeg", "image/jpeg"}, + {".txt", "text/plain"}, + {".html", "text/plain"} + }; + + if(prevtype) + /* default to the previously set/used! */ + contenttype = prevtype; + else + /* It seems RFC1867 defines no Content-Type to default to + text/plain so we don't actually need to set this: */ + contenttype = HTTPPOST_CONTENTTYPE_DEFAULT; + + for(i=0; i= strlen(ctts[i].extension)) { + if(strequal(filename + + strlen(filename) - strlen(ctts[i].extension), + ctts[i].extension)) { + contenttype = ctts[i].type; + break; + } + } + } + /* we have a contenttype by now */ + return contenttype; +} + +/*************************************************************************** + * + * AllocAndCopy() + * + * Copies the data currently available under *buffer using newly allocated + * buffer (that becomes *buffer). Uses buffer_length if not null, else + * uses strlen to determine the length of the buffer to be copied + * + * Returns 0 on success and 1 if the malloc failed. + * + ***************************************************************************/ +static int AllocAndCopy (char **buffer, int buffer_length) +{ + char *src = *buffer; + int length; + if (buffer_length) + length = buffer_length; + else + length = strlen(*buffer); + *buffer = (char*)malloc(length); + if (!*buffer) + return 1; + memcpy(*buffer, src, length); + return 0; +} + /*************************************************************************** * * FormAdd() @@ -435,8 +577,12 @@ static struct HttpPost * AddHttpPost (char * name, * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); * - * Returns 0 on success, 1 if the first option is not CURLFORM_COPYNAME, - * 2 if AddHttpPost failes, and 3 if an unknown option is encountered + * Returns 0 on success, 1 if the FormInfo allocation fails, 2 if one + * option is given twice for one Form, 3 if a null pointer was given for + * a char *, 4 if the allocation of a FormInfo struct failed, 5 if an + * unknown option was used, 6 if the some FormInfo is not complete (or + * has an error), 7 if a HttpPost struct cannot be allocated, and 8 + * if some allocation for string copying failed. * ***************************************************************************/ @@ -445,155 +591,192 @@ int FormAdd(struct HttpPost **httppost, struct HttpPost **last_post, va_list params) { - int go_on = TRUE; - int read_argument = TRUE; - unsigned int i; - char *name; - char *value; + FormInfo *first_form_info, *current_form_info, *form_info; + int return_value = 0; const char *prevtype = NULL; struct HttpPost *post = NULL; CURLformoption next_option; - /* We always expect CURLFORM_COPYNAME first for the moment. */ - next_option = va_arg(params, CURLformoption); - if (next_option != CURLFORM_COPYNAME) + first_form_info = (FormInfo *)malloc(sizeof(struct FormInfo)); + if(first_form_info) { + memset(first_form_info, 0, sizeof(FormInfo)); + current_form_info = first_form_info; + } + else return 1; - name = va_arg(params, char *); - do + /** TODO: first check whether char * is not NULL + TODO: transfer.c + */ + while ( ((next_option = va_arg(params, CURLformoption)) != CURLFORM_END) && + (return_value == 0) ) { - /* if not already read read next argument */ - if (read_argument) - next_option = va_arg(params, CURLformoption); - else - read_argument = TRUE; - switch (next_option) { - case CURLFORM_COPYCONTENTS: - { /* simple name/value storage of duplicated data */ - const char * contenttype = NULL; - value = va_arg(params, char *); - next_option = va_arg(params, CURLformoption); - if (next_option == CURLFORM_CONTENTTYPE) - contenttype = va_arg(params, char *); - else - read_argument = FALSE; - if ((post = AddHttpPost(strdup(name), strdup(value), 0, 0, NULL, - httppost, last_post)) == NULL) { - return 2; + case CURLFORM_PTRNAME: + current_form_info->flags |= HTTPPOST_PTRNAME; /* fall through */ + case CURLFORM_COPYNAME: + if (current_form_info->name) + return_value = 2; + else { + if (next_option == CURLFORM_PTRNAME) + current_form_info->name = va_arg(params, char *); + else { + char *name = va_arg(params, char *); + if (name) + current_form_info->name = name; /* store for the moment */ + else + return_value = 3; + } } - if (contenttype) - post->contenttype = strdup(contenttype); - /* at the moment no more options are allowd in this case */ - go_on = FALSE; break; - } + case CURLFORM_NAMELENGTH: + if (current_form_info->namelength) + return_value = 2; + else + current_form_info->namelength = va_arg(params, long); + break; case CURLFORM_PTRCONTENTS: - { /* name/value storage with value stored as a pointer */ - const char * contenttype = NULL; - void * ptr_contents = va_arg(params, void *); - long contentslength; - int got_contentslength = FALSE; - /* either use provided length or use strlen () to get it */ - next_option = va_arg(params, CURLformoption); - while ( (next_option == CURLFORM_CONTENTSLENGTH) || - (next_option == CURLFORM_CONTENTTYPE) ) { - if (next_option == CURLFORM_CONTENTSLENGTH) { - contentslength = va_arg(params, long); - got_contentslength = TRUE; - } - else { /* CURLFORM_CONTENTTYPE */ - contenttype = va_arg(params, char *); - } - next_option = va_arg(params, CURLformoption); - }; - /* we already read the next CURLformoption */ - read_argument = FALSE; - if (!got_contentslength) - /* no length given, use strlen to find out */ - contentslength = strlen (ptr_contents); - if ((post = AddHttpPost(strdup(name), ptr_contents, contentslength, - HTTPPOST_PTRCONTENTS, NULL, httppost, - last_post)) - == NULL) { - return 2; + current_form_info->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ + case CURLFORM_COPYCONTENTS: + if (current_form_info->value) + return_value = 2; + else { + if (next_option == CURLFORM_PTRCONTENTS) + current_form_info->value = va_arg(params, char *); + else { + char *value = va_arg(params, char *); + if (value) + current_form_info->value = value; /* store for the moment */ + else + return_value = 3; + } } - if (contenttype) - post->contenttype = strdup(contenttype); - /* at the moment no more options are allowd in this case */ - go_on = FALSE; break; - } - case CURLFORM_FILE: - { - const char * contenttype = NULL; - value = va_arg(params, char *); - next_option = va_arg(params, CURLformoption); - /* if contenttype was provided retrieve it */ - if (next_option == CURLFORM_CONTENTTYPE) { - contenttype = va_arg(params, char *); + case CURLFORM_CONTENTSLENGTH: + if (current_form_info->contentslength) + return_value = 2; + else + current_form_info->contentslength = va_arg(params, long); + break; + case CURLFORM_FILE: { + char *filename = va_arg(params, char *); + if (current_form_info->value) { + if (current_form_info->flags & HTTPPOST_FILENAME) { + if (filename) { + if (!(current_form_info = AddFormInfo (strdup(filename), + NULL, current_form_info))) + return_value = 4; + } + else + return_value = 3; + } + else + return_value = 2; } else { - /* - * No type was specified, we scan through a few well-known - * extensions and pick the first we match! - */ - struct ContentType { - const char *extension; - const char *type; - }; - static struct ContentType ctts[]={ - {".gif", "image/gif"}, - {".jpg", "image/jpeg"}, - {".jpeg", "image/jpeg"}, - {".txt", "text/plain"}, - {".html", "text/plain"} - }; - - if(prevtype) - /* default to the previously set/used! */ - contenttype = prevtype; + if (filename) + current_form_info->value = strdup(filename); else - /* It seems RFC1867 defines no Content-Type to default to - text/plain so we don't actually need to set this: */ - contenttype = HTTPPOST_CONTENTTYPE_DEFAULT; - - for(i=0; i= strlen(ctts[i].extension)) { - if(strequal(value + - strlen(value) - strlen(ctts[i].extension), - ctts[i].extension)) { - contenttype = ctts[i].type; - break; - } - } - } - /* we have a contenttype by now */ - /* do not try to read the next option we already did that */ - read_argument = FALSE; + return_value = 3; + current_form_info->flags |= HTTPPOST_FILENAME; } - if ( (post = AddHttpPost (strdup(name), strdup(value), 0, - HTTPPOST_FILENAME, post, httppost, - last_post)) == NULL) { - return 2; - } - post->contenttype = strdup (contenttype); - prevtype = post->contenttype; - /* we do not set go_on to false as multiple files are allowed */ break; } - case CURLFORM_END: - /* this ends our loop */ + case CURLFORM_CONTENTTYPE: { + char *contenttype = va_arg(params, char *); + if (current_form_info->contenttype) { + if (current_form_info->flags & HTTPPOST_FILENAME) { + if (contenttype) { + if (!(current_form_info = AddFormInfo (NULL, + strdup(contenttype), + current_form_info))) + return_value = 4; + } + else + return_value = 3; + } + else + return_value = 2; + } + else { + if (contenttype) + current_form_info->contenttype = strdup(contenttype); + else + return_value = 3; + } break; + } default: - fprintf (stderr, "got: %d\n", next_option); - return 3; + fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", next_option); + return_value = 5; }; + }; - } while (go_on && next_option != CURLFORM_END); + /* go through the list, check for copleteness and if everything is + * alright add the HttpPost item otherwise set return_value accordingly */ + form_info = first_form_info; + while (form_info != NULL) + { + if ( (!first_form_info->name) || + (!form_info->value) || + ( (!form_info->namelength) && + (form_info->flags & HTTPPOST_PTRNAME) ) || + ( (form_info->contentslength) && + (form_info->flags & HTTPPOST_FILENAME) ) || + ( (form_info->flags & HTTPPOST_FILENAME) && + (form_info->flags & HTTPPOST_PTRCONTENTS) ) + ) { + return_value = 6; + break; + } + else { + if ( (form_info->flags & HTTPPOST_FILENAME) && + (!form_info->contenttype) ) { + /* our contenttype is missing */ + form_info->contenttype + = strdup(ContentTypeForFilename(form_info->value, prevtype)); + } + if ( !(form_info->flags & HTTPPOST_PTRNAME) && + (form_info == first_form_info) ) { + /* copy name (without strdup; possibly contains null characters) */ + if (AllocAndCopy(&form_info->name, form_info->namelength)) { + return_value = 8; + break; + } + } + if ( !(form_info->flags & HTTPPOST_FILENAME) && + !(form_info->flags & HTTPPOST_PTRCONTENTS) ) { + /* copy value (without strdup; possibly contains null characters) */ + if (AllocAndCopy(&form_info->value, form_info->contentslength)) { + return_value = 8; + break; + } + } + if ( (post = AddHttpPost (form_info->name, form_info->namelength, + form_info->value, form_info->contentslength, + form_info->contenttype, form_info->flags, + post, httppost, + last_post)) == NULL) { + return_value = 7; + } + if (form_info->contenttype) + prevtype = form_info->contenttype; + } + form_info = form_info->more; + }; - return 0; + /* and finally delete the allocated memory */ + form_info = first_form_info; + while (form_info != NULL) { + FormInfo *delete_form_info; + + delete_form_info = form_info; + form_info = form_info->more; + free (delete_form_info); + }; + + return return_value; } int curl_formadd(struct HttpPost **httppost, @@ -705,7 +888,7 @@ void curl_formfree(struct HttpPost *form) if(form->more) curl_formfree(form->more); - if(form->name) + if( !(form->flags & HTTPPOST_PTRNAME) && form->name) free(form->name); /* free the name */ if( !(form->flags & HTTPPOST_PTRCONTENTS) && form->contents) free(form->contents); /* free the contents */ @@ -747,9 +930,12 @@ struct FormData *Curl_getFormData(struct HttpPost *post, /* boundary */ size += AddFormDataf(&form, "\r\n--%s\r\n", boundary); - size += AddFormDataf(&form, - "Content-Disposition: form-data; name=\"%s\"", - post->name); + size += AddFormData(&form, + "Content-Disposition: form-data; name=\"", 0); + + size += AddFormData(&form, post->name, post->namelength); + + size += AddFormData(&form, "\"", 0); if(post->more) { /* If used, this is a link to more file names, we must then do @@ -963,8 +1149,6 @@ int FormAddTest(const char * errormsg, { int result; va_list arg; - CURLformoption next_option; - char * value; va_start(arg, last_post); if ((result = FormAdd(httppost, last_post, arg))) fprintf (stderr, "ERROR doing FormAdd ret: %d action: %s\n", result, @@ -978,30 +1162,34 @@ int main() { char name1[] = "simple_COPYCONTENTS"; char name2[] = "COPYCONTENTS_+_CONTENTTYPE"; - char name3[] = "simple_PTRCONTENTS"; - char name4[] = "PTRCONTENTS_+_CONTENTSLENGTH"; - char name5[] = "PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE"; - char name6[] = "FILE1_+_CONTENTTYPE"; - char name7[] = "FILE1_+_FILE2"; + char name3[] = "PTRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH"; + char name4[] = "simple_PTRCONTENTS"; + char name5[] = "PTRCONTENTS_+_CONTENTSLENGTH"; + char name6[] = "PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE"; + char name7[] = "FILE1_+_CONTENTTYPE"; + char name8[] = "FILE1_+_FILE2"; + char name9[] = "FILE1_+_FILE2_+_FILE3"; char value1[] = "value for simple COPYCONTENTS"; char value2[] = "value for COPYCONTENTS + CONTENTTYPE"; - char value3[] = "value for simple PTRCONTENTS"; - char value4[] = "value for PTRCONTENTS + CONTENTSLENGTH"; - char value5[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE"; - char value6[] = "inet_ntoa_r.h"; - char value7[] = "Makefile.b32.resp"; + char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH"; + char value4[] = "value for simple PTRCONTENTS"; + char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH"; + char value6[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE"; + char value7[] = "inet_ntoa_r.h"; + char value8[] = "Makefile.b32.resp"; char type2[] = "image/gif"; - char type5[] = "text/plain"; - char type6[] = "text/html"; - int value4length = strlen(value4); - int value5length = strlen(value5); + char type6[] = "text/plain"; + char type7[] = "text/html"; + int name3length = strlen(name3); + int value3length = strlen(value3); + int value5length = strlen(value4); + int value6length = strlen(value5); int errors = 0; int size; int nread; char buffer[4096]; struct HttpPost *httppost=NULL; struct HttpPost *last_post=NULL; - struct HttpPost *post; struct FormData *form; struct Form formread; @@ -1014,33 +1202,47 @@ int main() CURLFORM_COPYNAME, name2, CURLFORM_COPYCONTENTS, value2, CURLFORM_CONTENTTYPE, type2, CURLFORM_END)) ++errors; + /* make null character at start to check that contentslength works + correctly */ + name3[1] = '\0'; + value3[1] = '\0'; + if (FormAddTest("PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH test", + &httppost, &last_post, + CURLFORM_PTRNAME, name3, CURLFORM_COPYCONTENTS, value3, + CURLFORM_CONTENTSLENGTH, value3length, + CURLFORM_NAMELENGTH, name3length, CURLFORM_END)) + ++errors; if (FormAddTest("simple PTRCONTENTS test", &httppost, &last_post, - CURLFORM_COPYNAME, name3, CURLFORM_PTRCONTENTS, value3, + CURLFORM_COPYNAME, name4, CURLFORM_PTRCONTENTS, value4, CURLFORM_END)) ++errors; /* make null character at start to check that contentslength works correctly */ - value4[1] = '\0'; + value5[1] = '\0'; if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH test", &httppost, &last_post, - CURLFORM_COPYNAME, name4, CURLFORM_PTRCONTENTS, value4, - CURLFORM_CONTENTSLENGTH, value4length, CURLFORM_END)) + CURLFORM_COPYNAME, name5, CURLFORM_PTRCONTENTS, value5, + CURLFORM_CONTENTSLENGTH, value5length, CURLFORM_END)) ++errors; /* make null character at start to check that contentslength works correctly */ - value5[1] = '\0'; + value6[1] = '\0'; if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE test", &httppost, &last_post, - CURLFORM_COPYNAME, name5, CURLFORM_PTRCONTENTS, value5, - CURLFORM_CONTENTSLENGTH, value5length, - CURLFORM_CONTENTTYPE, type5, CURLFORM_END)) + CURLFORM_COPYNAME, name6, CURLFORM_PTRCONTENTS, value6, + CURLFORM_CONTENTSLENGTH, value6length, + CURLFORM_CONTENTTYPE, type6, CURLFORM_END)) ++errors; if (FormAddTest("FILE + CONTENTTYPE test", &httppost, &last_post, - CURLFORM_COPYNAME, name6, CURLFORM_FILE, value6, - CURLFORM_CONTENTTYPE, type6, CURLFORM_END)) + CURLFORM_COPYNAME, name7, CURLFORM_FILE, value7, + CURLFORM_CONTENTTYPE, type7, CURLFORM_END)) ++errors; if (FormAddTest("FILE1 + FILE2 test", &httppost, &last_post, - CURLFORM_COPYNAME, name7, CURLFORM_FILE, value6, - CURLFORM_FILE, value7, CURLFORM_END)) + CURLFORM_COPYNAME, name8, CURLFORM_FILE, value7, + CURLFORM_FILE, value8, CURLFORM_END)) + ++errors; + if (FormAddTest("FILE1 + FILE2 + FILE3 test", &httppost, &last_post, + CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7, + CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END)) ++errors; form=Curl_getFormData(httppost, &size); -- cgit v1.2.1 From 6147879837a53d22c9be04e7a4fc315a297ba2b3 Mon Sep 17 00:00:00 2001 From: Sterling Hughes Date: Fri, 7 Sep 2001 04:01:32 +0000 Subject: Added formatting sections for emacs and vim --- lib/formdata.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index bbca0b8f7..728fe33e3 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1322,3 +1322,11 @@ int main(int argc, char **argv) } #endif + +/* + * local variables: + * eval: (load-file "../curl-mode.el") + * end: + * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker + * vim<600: et sw=2 ts=2 sts=2 tw=78 + */ -- cgit v1.2.1 From 66087bdac61be61f68edd6c233174cd71f0674bd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Oct 2001 07:54:42 +0000 Subject: Georg Huettenegger's curl_formadd fixes --- lib/formdata.c | 471 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 303 insertions(+), 168 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 728fe33e3..28a1dd4e6 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -80,6 +80,23 @@ Content-Disposition: attachment; filename="inet_ntoa_r.h" Content-Type: text/plain ... + +Content-Disposition: form-data; name="ARRAY: FILE1_+_FILE2_+_FILE3" +Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 +... +Content-Disposition: attachment; filename="inet_ntoa_r.h" +Content-Type: text/plain +... +Content-Disposition: attachment; filename="Makefile.b32.resp" +Content-Type: text/plain +... +Content-Disposition: attachment; filename="inet_ntoa_r.h" +Content-Type: text/plain +... + +Content-Disposition: form-data; name="FILECONTENT" +... + For the old FormParse used by curl_formparse use: gcc -DHAVE_CONFIG_H -I../ -g -D_OLD_FORM_DEBUG -o formdata -I../include formdata.c strequal.c @@ -394,7 +411,7 @@ static struct HttpPost * AddHttpPost (char * name, if(post) { memset(post, 0, sizeof(struct HttpPost)); post->name = name; - post->namelength = namelength; + post->namelength = namelength?namelength:(long)strlen(name); post->contents = value; post->contentslength = contentslength; post->contenttype = contenttype; @@ -432,9 +449,9 @@ static struct HttpPost * AddHttpPost (char * name, * parent_form_info is NULL. * ***************************************************************************/ -static FormInfo * AddFormInfo (char *value, - char *contenttype, - FormInfo *parent_form_info) +static FormInfo * AddFormInfo(char *value, + char *contenttype, + FormInfo *parent_form_info) { FormInfo *form_info; form_info = (FormInfo *)malloc(sizeof(FormInfo)); @@ -472,7 +489,7 @@ static FormInfo * AddFormInfo (char *value, * Returns some valid contenttype for filename. * ***************************************************************************/ -static const char * ContentTypeForFilename (char *filename, +static const char * ContentTypeForFilename (const char *filename, const char *prevtype) { const char *contenttype = NULL; @@ -528,16 +545,21 @@ static const char * ContentTypeForFilename (char *filename, ***************************************************************************/ static int AllocAndCopy (char **buffer, int buffer_length) { - char *src = *buffer; - int length; + const char *src = *buffer; + int length, add = 0; if (buffer_length) length = buffer_length; - else + else { length = strlen(*buffer); - *buffer = (char*)malloc(length); + add = 1; + } + *buffer = (char*)malloc(length+add); if (!*buffer) return 1; memcpy(*buffer, src, length); + /* if length unknown do null termination */ + if (add) + (*buffer)[length] = '\0'; return 0; } @@ -561,11 +583,11 @@ static int AllocAndCopy (char **buffer, int buffer_length) * * Simple name/value pair with copied contents: * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_COPYCONTENTS, "value"); + * CURLFORM_COPYCONTENTS, "value", CURLFORM_END); * * name/value pair where only the content pointer is remembered: * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10); + * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END); * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used) * * storing a filename (CONTENTTYPE is optional!): @@ -577,204 +599,299 @@ static int AllocAndCopy (char **buffer, int buffer_length) * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); * - * Returns 0 on success, 1 if the FormInfo allocation fails, 2 if one - * option is given twice for one Form, 3 if a null pointer was given for - * a char *, 4 if the allocation of a FormInfo struct failed, 5 if an - * unknown option was used, 6 if the some FormInfo is not complete (or - * has an error), 7 if a HttpPost struct cannot be allocated, and 8 - * if some allocation for string copying failed. + * Returns: + * FORMADD_OK on success + * FORMADD_MEMORY if the FormInfo allocation fails + * FORMADD_OPTION_TWICE if one option is given twice for one Form + * FORMADD_NULL if a null pointer was given for a char + * FORMADD_MEMORY if the allocation of a FormInfo struct failed + * FORMADD_UNKNOWN_OPTION if an unknown option was used + * FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error) + * FORMADD_MEMORY if a HttpPost struct cannot be allocated + * FORMADD_MEMORY if some allocation for string copying failed. + * FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array * ***************************************************************************/ +typedef enum { + FORMADD_OK, /* first, no error */ + + FORMADD_MEMORY, + FORMADD_OPTION_TWICE, + FORMADD_NULL, + FORMADD_UNKNOWN_OPTION, + FORMADD_INCOMPLETE, + FORMADD_ILLEGAL_ARRAY, + + FORMADD_LAST /* last */ +} FORMcode; + static -int FormAdd(struct HttpPost **httppost, - struct HttpPost **last_post, - va_list params) +FORMcode FormAdd(struct HttpPost **httppost, + struct HttpPost **last_post, + va_list params) { - FormInfo *first_form_info, *current_form_info, *form_info; - int return_value = 0; + FormInfo *first_form, *current_form, *form; + FORMcode return_value = FORMADD_OK; const char *prevtype = NULL; struct HttpPost *post = NULL; - CURLformoption next_option; + CURLformoption option; + struct curl_forms *forms = NULL; + int array_index = 0; + + /* This is a state variable, that if TRUE means that we're parsing an + array that we got passed to us. If FALSE we're parsing the input + va_list arguments. */ + bool array_state = FALSE; - first_form_info = (FormInfo *)malloc(sizeof(struct FormInfo)); - if(first_form_info) { - memset(first_form_info, 0, sizeof(FormInfo)); - current_form_info = first_form_info; + /* + * We need to allocate the first struct to fill in. + */ + first_form = (FormInfo *)malloc(sizeof(struct FormInfo)); + if(first_form) { + memset(first_form, 0, sizeof(FormInfo)); + current_form = first_form; } else - return 1; + return FORMADD_MEMORY; - /** TODO: first check whether char * is not NULL - TODO: transfer.c - */ - while ( ((next_option = va_arg(params, CURLformoption)) != CURLFORM_END) && - (return_value == 0) ) - { - switch (next_option) - { - case CURLFORM_PTRNAME: - current_form_info->flags |= HTTPPOST_PTRNAME; /* fall through */ - case CURLFORM_COPYNAME: - if (current_form_info->name) - return_value = 2; - else { - if (next_option == CURLFORM_PTRNAME) - current_form_info->name = va_arg(params, char *); - else { - char *name = va_arg(params, char *); - if (name) - current_form_info->name = name; /* store for the moment */ - else - return_value = 3; - } + /* + * Loop through all the options set. + */ + while (1) { + + /* break if we have an error to report */ + if (return_value != FORMADD_OK) + break; + + /* first see if we have more parts of the array param */ + if ( array_state ) { + /* get the upcoming option from the given array */ + option = forms[array_index++].option; + if (CURLFORM_END == option) { + /* end of array state */ + array_state = FALSE; + continue; + } + else { + /* check that the option is OK in an array */ + + /* Daniel's note: do we really need to do this? */ + if ( (option <= CURLFORM_ARRAY_START) || + (option >= CURLFORM_ARRAY_END) ) { + return_value = FORMADD_ILLEGAL_ARRAY; + break; } + } + } + else { + /* This is not array-state, get next option */ + option = va_arg(params, CURLformoption); + if (CURLFORM_END == option) break; - case CURLFORM_NAMELENGTH: - if (current_form_info->namelength) - return_value = 2; + } + + switch (option) { + case CURLFORM_ARRAY: + forms = va_arg(params, struct curl_forms *); + if (forms) { + array_state = TRUE; + array_index = 0; + } + else + return_value = FORMADD_NULL; + break; + + /* + * Set the Name property. + */ + case CURLFORM_PTRNAME: + current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ + case CURLFORM_COPYNAME: + if (current_form->name) + return_value = FORMADD_OPTION_TWICE; + else { + char *name = va_arg(params, char *); + if (name) + current_form->name = name; /* store for the moment */ else - current_form_info->namelength = va_arg(params, long); - break; - case CURLFORM_PTRCONTENTS: - current_form_info->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ - case CURLFORM_COPYCONTENTS: - if (current_form_info->value) - return_value = 2; - else { - if (next_option == CURLFORM_PTRCONTENTS) - current_form_info->value = va_arg(params, char *); - else { - char *value = va_arg(params, char *); - if (value) - current_form_info->value = value; /* store for the moment */ - else - return_value = 3; - } + return_value = FORMADD_NULL; + } + break; + case CURLFORM_NAMELENGTH: + if (current_form->namelength) + return_value = FORMADD_OPTION_TWICE; + else + current_form->namelength = va_arg(params, long); + break; + + /* + * Set the contents property. + */ + case CURLFORM_PTRCONTENTS: + current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ + case CURLFORM_COPYCONTENTS: + if (current_form->value) + return_value = FORMADD_OPTION_TWICE; + else { + char *value = va_arg(params, char *); + if (value) + current_form->value = value; /* store for the moment */ + else + return_value = FORMADD_NULL; + } + break; + case CURLFORM_CONTENTSLENGTH: + if (current_form->contentslength) + return_value = FORMADD_OPTION_TWICE; + else + current_form->contentslength = va_arg(params, long); + break; + + /* Get contents from a given file name */ + case CURLFORM_FILECONTENT: + if (current_form->flags != 0) + return_value = FORMADD_OPTION_TWICE; + else { + char *filename = va_arg(params, char *); + if (filename) { + current_form->value = strdup(filename); + current_form->flags |= HTTPPOST_READFILE; } - break; - case CURLFORM_CONTENTSLENGTH: - if (current_form_info->contentslength) - return_value = 2; else - current_form_info->contentslength = va_arg(params, long); - break; - case CURLFORM_FILE: { - char *filename = va_arg(params, char *); - if (current_form_info->value) { - if (current_form_info->flags & HTTPPOST_FILENAME) { - if (filename) { - if (!(current_form_info = AddFormInfo (strdup(filename), - NULL, current_form_info))) - return_value = 4; - } - else - return_value = 3; + return_value = FORMADD_NULL; + } + break; + + /* We upload a file */ + case CURLFORM_FILE: + { + const char *filename = NULL; + if (array_state) + filename = forms[array_index].value; + else + filename = va_arg(params, const char *); + if (current_form->value) { + if (current_form->flags & HTTPPOST_FILENAME) { + if (filename) { + if (!(current_form = AddFormInfo(strdup(filename), + NULL, current_form))) + return_value = FORMADD_MEMORY; + } + else + return_value = FORMADD_NULL; } else - return_value = 2; + return_value = FORMADD_OPTION_TWICE; } else { - if (filename) - current_form_info->value = strdup(filename); - else - return_value = 3; - current_form_info->flags |= HTTPPOST_FILENAME; + if (filename) + current_form->value = strdup(filename); + else + return_value = FORMADD_NULL; + current_form->flags |= HTTPPOST_FILENAME; } break; } - case CURLFORM_CONTENTTYPE: { - char *contenttype = va_arg(params, char *); - if (current_form_info->contenttype) { - if (current_form_info->flags & HTTPPOST_FILENAME) { + case CURLFORM_CONTENTTYPE: + { + const char *contenttype = NULL; + if (array_state) + contenttype = forms[array_index].value; + else + contenttype = va_arg(params, const char *); + if (current_form->contenttype) { + if (current_form->flags & HTTPPOST_FILENAME) { if (contenttype) { - if (!(current_form_info = AddFormInfo (NULL, - strdup(contenttype), - current_form_info))) - return_value = 4; + if (!(current_form = AddFormInfo(NULL, + strdup(contenttype), + current_form))) + return_value = FORMADD_MEMORY; } else - return_value = 3; + return_value = FORMADD_NULL; } else - return_value = 2; + return_value = FORMADD_OPTION_TWICE; } else { if (contenttype) - current_form_info->contenttype = strdup(contenttype); + current_form->contenttype = strdup(contenttype); else - return_value = 3; + return_value = FORMADD_NULL; } break; } - default: - fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", next_option); - return_value = 5; - }; - }; - - /* go through the list, check for copleteness and if everything is - * alright add the HttpPost item otherwise set return_value accordingly */ - form_info = first_form_info; - while (form_info != NULL) - { - if ( (!first_form_info->name) || - (!form_info->value) || - ( (!form_info->namelength) && - (form_info->flags & HTTPPOST_PTRNAME) ) || - ( (form_info->contentslength) && - (form_info->flags & HTTPPOST_FILENAME) ) || - ( (form_info->flags & HTTPPOST_FILENAME) && - (form_info->flags & HTTPPOST_PTRCONTENTS) ) - ) { - return_value = 6; - break; + default: + fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", option); + return_value = FORMADD_UNKNOWN_OPTION; } - else { - if ( (form_info->flags & HTTPPOST_FILENAME) && - (!form_info->contenttype) ) { - /* our contenttype is missing */ - form_info->contenttype - = strdup(ContentTypeForFilename(form_info->value, prevtype)); - } - if ( !(form_info->flags & HTTPPOST_PTRNAME) && - (form_info == first_form_info) ) { - /* copy name (without strdup; possibly contains null characters) */ - if (AllocAndCopy(&form_info->name, form_info->namelength)) { - return_value = 8; - break; - } - } - if ( !(form_info->flags & HTTPPOST_FILENAME) && - !(form_info->flags & HTTPPOST_PTRCONTENTS) ) { - /* copy value (without strdup; possibly contains null characters) */ - if (AllocAndCopy(&form_info->value, form_info->contentslength)) { - return_value = 8; - break; - } + } + + if(FORMADD_OK == return_value) { + /* go through the list, check for copleteness and if everything is + * alright add the HttpPost item otherwise set return_value accordingly */ + form = first_form; + while (form != NULL) { + if ( (!form->name) || + (!form->value) || + ( (form->contentslength) && + (form->flags & HTTPPOST_FILENAME) ) || + ( (form->flags & HTTPPOST_FILENAME) && + (form->flags & HTTPPOST_PTRCONTENTS) ) || + ( (form->flags & HTTPPOST_READFILE) && + (form->flags & HTTPPOST_PTRCONTENTS) ) + ) { + return_value = FORMADD_INCOMPLETE; + break; } - if ( (post = AddHttpPost (form_info->name, form_info->namelength, - form_info->value, form_info->contentslength, - form_info->contenttype, form_info->flags, - post, httppost, - last_post)) == NULL) { - return_value = 7; + else { + if ( (form->flags & HTTPPOST_FILENAME) && + !form->contenttype ) { + /* our contenttype is missing */ + form->contenttype + = strdup(ContentTypeForFilename(form->value, prevtype)); + } + if ( !(form->flags & HTTPPOST_PTRNAME) && + (form == first_form) ) { + /* copy name (without strdup; possibly contains null characters) */ + if (AllocAndCopy(&form->name, form->namelength)) { + return_value = FORMADD_MEMORY; + break; + } + } + if ( !(form->flags & HTTPPOST_FILENAME) && + !(form->flags & HTTPPOST_READFILE) && + !(form->flags & HTTPPOST_PTRCONTENTS) ) { + /* copy value (without strdup; possibly contains null characters) */ + if (AllocAndCopy(&form->value, form->contentslength)) { + return_value = FORMADD_MEMORY; + break; + } + } + if ( (post = AddHttpPost(form->name, form->namelength, + form->value, form->contentslength, + form->contenttype, form->flags, + post, httppost, + last_post)) == NULL) { + return_value = FORMADD_MEMORY; + } + if (form->contenttype) + prevtype = form->contenttype; } - if (form_info->contenttype) - prevtype = form_info->contenttype; + form = form->more; } - form_info = form_info->more; - }; + } - /* and finally delete the allocated memory */ - form_info = first_form_info; - while (form_info != NULL) { - FormInfo *delete_form_info; + /* always delete the allocated memory before returning */ + form = first_form; + while (form != NULL) { + FormInfo *delete_form; - delete_form_info = form_info; - form_info = form_info->more; - free (delete_form_info); - }; + delete_form = form; + form = form->more; + free (delete_form); + } return return_value; } @@ -1169,6 +1286,8 @@ int main() char name7[] = "FILE1_+_CONTENTTYPE"; char name8[] = "FILE1_+_FILE2"; char name9[] = "FILE1_+_FILE2_+_FILE3"; + char name10[] = "ARRAY: FILE1_+_FILE2_+_FILE3"; + char name11[] = "FILECONTENT"; char value1[] = "value for simple COPYCONTENTS"; char value2[] = "value for COPYCONTENTS + CONTENTTYPE"; char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH"; @@ -1190,6 +1309,7 @@ int main() char buffer[4096]; struct HttpPost *httppost=NULL; struct HttpPost *last_post=NULL; + struct curl_forms forms[4]; struct FormData *form; struct Form formread; @@ -1244,6 +1364,21 @@ int main() CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7, CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END)) ++errors; + forms[0].option = CURLFORM_FILE; + forms[0].value = value7; + forms[1].option = CURLFORM_FILE; + forms[1].value = value8; + forms[2].option = CURLFORM_FILE; + forms[2].value = value7; + forms[3].option = CURLFORM_END; + if (FormAddTest("FILE1 + FILE2 + FILE3 ARRAY test", &httppost, &last_post, + CURLFORM_COPYNAME, name10, CURLFORM_ARRAY, forms, + CURLFORM_END)) + ++errors; + if (FormAddTest("FILECONTENT test", &httppost, &last_post, + CURLFORM_COPYNAME, name11, CURLFORM_FILECONTENT, value7, + CURLFORM_END)) + ++errors; form=Curl_getFormData(httppost, &size); -- cgit v1.2.1 From 64f00454e515ba0451e8a961bfa0395bc24f3159 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Oct 2001 09:31:16 +0000 Subject: hm, I edited away the fine functionality and with this edit test case 9 is once again running OK --- lib/formdata.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 28a1dd4e6..1c73e923c 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -637,7 +637,7 @@ FORMcode FormAdd(struct HttpPost **httppost, struct HttpPost *post = NULL; CURLformoption option; struct curl_forms *forms = NULL; - int array_index = 0; + const char *array_value; /* value read from an array */ /* This is a state variable, that if TRUE means that we're parsing an array that we got passed to us. If FALSE we're parsing the input @@ -667,7 +667,10 @@ FORMcode FormAdd(struct HttpPost **httppost, /* first see if we have more parts of the array param */ if ( array_state ) { /* get the upcoming option from the given array */ - option = forms[array_index++].option; + option = forms->option; + array_value = forms->value; + + forms++; /* advance this to next entry */ if (CURLFORM_END == option) { /* end of array state */ array_state = FALSE; @@ -694,10 +697,8 @@ FORMcode FormAdd(struct HttpPost **httppost, switch (option) { case CURLFORM_ARRAY: forms = va_arg(params, struct curl_forms *); - if (forms) { + if (forms) array_state = TRUE; - array_index = 0; - } else return_value = FORMADD_NULL; break; @@ -768,7 +769,7 @@ FORMcode FormAdd(struct HttpPost **httppost, { const char *filename = NULL; if (array_state) - filename = forms[array_index].value; + filename = array_value; else filename = va_arg(params, const char *); if (current_form->value) { @@ -797,7 +798,7 @@ FORMcode FormAdd(struct HttpPost **httppost, { const char *contenttype = NULL; if (array_state) - contenttype = forms[array_index].value; + contenttype = array_value; else contenttype = va_arg(params, const char *); if (current_form->contenttype) { -- cgit v1.2.1 From 8e91d5de8e4e17ce3d4936cc91171d09726e7bb3 Mon Sep 17 00:00:00 2001 From: Sterling Hughes Date: Thu, 11 Oct 2001 09:32:19 +0000 Subject: looks nicer and is better compatible with older vim versions --- lib/formdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 1c73e923c..0651a7b04 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1463,6 +1463,6 @@ int main(int argc, char **argv) * local variables: * eval: (load-file "../curl-mode.el") * end: - * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker - * vim<600: et sw=2 ts=2 sts=2 tw=78 + * vim600: fdm=marker + * vim: et sw=2 ts=2 sts=2 tw=78 */ -- cgit v1.2.1 From e165332211567588a55c7d8198ccf0ac9f62e748 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 29 Oct 2001 13:21:25 +0000 Subject: minor fix to support multiple files in one formadd() call --- lib/formdata.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 0651a7b04..e0c487dc6 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -411,7 +411,7 @@ static struct HttpPost * AddHttpPost (char * name, if(post) { memset(post, 0, sizeof(struct HttpPost)); post->name = name; - post->namelength = namelength?namelength:(long)strlen(name); + post->namelength = name?(namelength?namelength:(long)strlen(name)):0; post->contents = value; post->contentslength = contentslength; post->contenttype = contenttype; @@ -832,10 +832,12 @@ FORMcode FormAdd(struct HttpPost **httppost, if(FORMADD_OK == return_value) { /* go through the list, check for copleteness and if everything is * alright add the HttpPost item otherwise set return_value accordingly */ - form = first_form; - while (form != NULL) { - if ( (!form->name) || - (!form->value) || + + post = NULL; + for(form = first_form; + form != NULL; + form = form->more) { + if ( ((!form->name || !form->value) && !post) || ( (form->contentslength) && (form->flags & HTTPPOST_FILENAME) ) || ( (form->flags & HTTPPOST_FILENAME) && @@ -880,7 +882,6 @@ FORMcode FormAdd(struct HttpPost **httppost, if (form->contenttype) prevtype = form->contenttype; } - form = form->more; } } @@ -1391,12 +1392,12 @@ int main() if(-1 == nread) break; - fwrite(buffer, nread, 1, stderr); + fwrite(buffer, nread, 1, stdout); } while(1); - fprintf(stderr, "size: %d\n", size); + fprintf(stdout, "size: %d\n", size); if (errors) - fprintf(stderr, "\n==> %d Test(s) failed!\n", errors); + fprintf(stdout, "\n==> %d Test(s) failed!\n", errors); else fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n"); -- cgit v1.2.1 From 0ffec712e1b6479ff236d387c3d6b17d66f61881 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 8 Nov 2001 15:06:58 +0000 Subject: Marcus Webster reported and fixed this read-one-byte-too-many problem... --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index e0c487dc6..ef5e15374 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -923,7 +923,7 @@ static int AddFormData(struct FormData **formp, length = strlen((char *)line); newform->line = (char *)malloc(length+1); - memcpy(newform->line, line, length+1); + memcpy(newform->line, line, length); newform->length = length; newform->line[length]=0; /* zero terminate for easier debugging */ -- cgit v1.2.1 From 2eb355733ff3b9a6cde53f7c114f9ae77368a25f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 14 Dec 2001 12:59:16 +0000 Subject: Marcus Webster's newly added CURLFORM_CONTENTHEADER --- lib/formdata.c | 59 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 15 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index ef5e15374..c767da9fc 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -396,15 +396,16 @@ int curl_formparse(char *input, * Returns newly allocated HttpPost on success and NULL if malloc failed. * ***************************************************************************/ -static struct HttpPost * AddHttpPost (char * name, - long namelength, - char * value, - long contentslength, - char *contenttype, - long flags, - struct HttpPost *parent_post, - struct HttpPost **httppost, - struct HttpPost **last_post) +static struct HttpPost * AddHttpPost(char * name, + long namelength, + char * value, + long contentslength, + char *contenttype, + long flags, + struct curl_slist* contentHeader, + struct HttpPost *parent_post, + struct HttpPost **httppost, + struct HttpPost **last_post) { struct HttpPost *post; post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); @@ -415,6 +416,7 @@ static struct HttpPost * AddHttpPost (char * name, post->contents = value; post->contentslength = contentslength; post->contenttype = contenttype; + post->contentheader = contentHeader; post->flags = flags; } else @@ -823,6 +825,21 @@ FORMcode FormAdd(struct HttpPost **httppost, } break; } + case CURLFORM_CONTENTHEADER: + { + struct curl_slist* list = NULL; + if( array_state ) + list = (struct curl_slist*)array_value; + else + list = va_arg(params,struct curl_slist*); + + if( current_form->contentheader ) + return_value = FORMADD_OPTION_TWICE; + else + current_form->contentheader = list; + + break; + } default: fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", option); return_value = FORMADD_UNKNOWN_OPTION; @@ -872,13 +889,16 @@ FORMcode FormAdd(struct HttpPost **httppost, break; } } - if ( (post = AddHttpPost(form->name, form->namelength, - form->value, form->contentslength, - form->contenttype, form->flags, - post, httppost, - last_post)) == NULL) { + post = AddHttpPost(form->name, form->namelength, + form->value, form->contentslength, + form->contenttype, form->flags, + form->contentheader, + post, httppost, + last_post); + + if(!post) return_value = FORMADD_MEMORY; - } + if (form->contenttype) prevtype = form->contenttype; } @@ -1029,6 +1049,8 @@ struct FormData *Curl_getFormData(struct HttpPost *post, int size =0; char *boundary; char *fileboundary=NULL; + struct curl_slist* curList; + if(!post) return NULL; /* no input => no output! */ @@ -1090,6 +1112,13 @@ struct FormData *Curl_getFormData(struct HttpPost *post, file->contenttype); } + curList = file->contentheader; + while( curList ) { + /* Process the additional headers specified for this form */ + size += AddFormDataf( &form, "\r\n%s", curList->data ); + curList = curList->next; + } + #if 0 /* The header Content-Transfer-Encoding: seems to confuse some receivers * (like the built-in PHP engine). While I can't see any reason why it -- cgit v1.2.1 From e911945c55b32ea802b7eec4914499e102168951 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 19 Jan 2002 11:08:05 +0000 Subject: #505514, as correctly pointed out by Antonio (anton@concord.ru), trying to post a non-existing file should include nothing, not an error text! --- lib/formdata.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index c767da9fc..bc137cfd0 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1155,10 +1155,13 @@ struct FormData *Curl_getFormData(struct HttpPost *post, } if(fileread != stdin) fclose(fileread); - } else { - size += AddFormData(&form, "[File wasn't found by client]", 0); } - } else { + else { + /* File wasn't found, add a nothing field! */ + size += AddFormData(&form, "", 0); + } + } + else { /* include the contents we got */ size += AddFormData(&form, post->contents, post->contentslength); } -- cgit v1.2.1 From a9c4963cc0e2d517685f2c99e5a0c99e8217c690 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 29 Jan 2002 20:30:56 +0000 Subject: removed three loust fprintf()s removed the initial CRLF in the formpost, as they are part of the request and should be written by the code in http.c! --- lib/formdata.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index bc137cfd0..addbdf9d1 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -235,7 +235,6 @@ int FormParse(char *input, if(2 != sscanf(type, "%127[^/]/%127[^,\n]", major, minor)) { - fprintf(stderr, "Illegally formatted content-type field!\n"); free(contents); return 2; /* illegal content-type syntax! */ } @@ -371,7 +370,6 @@ int FormParse(char *input, } else { - fprintf(stderr, "Illegally formatted input field!\n"); free(contents); return 1; } @@ -841,7 +839,6 @@ FORMcode FormAdd(struct HttpPost **httppost, break; } default: - fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", option); return_value = FORMADD_UNKNOWN_OPTION; } } @@ -1069,7 +1066,7 @@ struct FormData *Curl_getFormData(struct HttpPost *post, do { /* boundary */ - size += AddFormDataf(&form, "\r\n--%s\r\n", boundary); + size += AddFormDataf(&form, "--%s\r\n", boundary); size += AddFormData(&form, "Content-Disposition: form-data; name=\"", 0); -- cgit v1.2.1 From b544c5fa5c7474bcf792969934564e0446334134 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 6 Feb 2002 15:48:53 +0000 Subject: ARGH the CRLF I removed recently was not only done after the initial content-type header, it was used for each part and thus without this it failed MISERABLY. *smacks forhead* --- lib/formdata.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index addbdf9d1..b607e57bd 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1065,6 +1065,9 @@ struct FormData *Curl_getFormData(struct HttpPost *post, do { + if(size) + size += AddFormDataf(&form, "\r\n"); + /* boundary */ size += AddFormDataf(&form, "--%s\r\n", boundary); -- cgit v1.2.1 From 9f374c20507940862601c3dbad3250a44541a85e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Mar 2002 15:18:59 +0000 Subject: Added support for CURLFORM_FILENAME to set the filename field of a file part. --- lib/formdata.c | 121 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 49 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index b607e57bd..12108cb8b 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2001, Daniel Stenberg, , et al. + * Copyright (C) 2002, Daniel Stenberg, , et al. * * In order to be useful for every potential user, curl and libcurl are * dual-licensed under the MPL and the MIT/X-derivate licenses. @@ -171,8 +171,8 @@ static void GetStr(char **string, static int FormParse(char *input, - struct HttpPost **httppost, - struct HttpPost **last_post) + struct curl_httppost **httppost, + struct curl_httppost **last_post) { /* nextarg MUST be a string in the format 'name=contents' and we'll build a linked list with the info */ @@ -186,8 +186,8 @@ int FormParse(char *input, char *prevtype = NULL; char *sep; char *sep2; - struct HttpPost *post; - struct HttpPost *subpost; /* a sub-node */ + struct curl_httppost *post; + struct curl_httppost *subpost; /* a sub-node */ unsigned int i; /* Preallocate contents to the length of input to make sure we don't @@ -296,9 +296,9 @@ int FormParse(char *input, /* For the first file name, we allocate and initiate the main list node */ - post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); + post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost)); if(post) { - memset(post, 0, sizeof(struct HttpPost)); + memset(post, 0, sizeof(struct curl_httppost)); GetStr(&post->name, name); /* get the name */ GetStr(&post->contents, contp); /* get the contents */ post->contentslength = 0; @@ -320,9 +320,10 @@ int FormParse(char *input, else { /* we add a file name to the previously allocated node, known as 'post' now */ - subpost =(struct HttpPost *)malloc(sizeof(struct HttpPost)); + subpost =(struct curl_httppost *) + malloc(sizeof(struct curl_httppost)); if(subpost) { - memset(subpost, 0, sizeof(struct HttpPost)); + memset(subpost, 0, sizeof(struct curl_httppost)); GetStr(&subpost->name, name); /* get the name */ GetStr(&subpost->contents, contp); /* get the contents */ subpost->contentslength = 0; @@ -342,9 +343,9 @@ int FormParse(char *input, } while(sep && *sep); /* loop if there's another file name */ } else { - post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); + post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost)); if(post) { - memset(post, 0, sizeof(struct HttpPost)); + memset(post, 0, sizeof(struct curl_httppost)); GetStr(&post->name, name); /* get the name */ if( contp[0]=='<' ) { GetStr(&post->contents, contp+1); /* get the contents */ @@ -378,8 +379,8 @@ int FormParse(char *input, } int curl_formparse(char *input, - struct HttpPost **httppost, - struct HttpPost **last_post) + struct curl_httppost **httppost, + struct curl_httppost **last_post) { return FormParse(input, httppost, last_post); } @@ -394,27 +395,28 @@ int curl_formparse(char *input, * Returns newly allocated HttpPost on success and NULL if malloc failed. * ***************************************************************************/ -static struct HttpPost * AddHttpPost(char * name, - long namelength, - char * value, - long contentslength, - char *contenttype, - long flags, - struct curl_slist* contentHeader, - struct HttpPost *parent_post, - struct HttpPost **httppost, - struct HttpPost **last_post) +static struct curl_httppost * +AddHttpPost(char * name, long namelength, + char * value, long contentslength, + char *contenttype, + long flags, + struct curl_slist* contentHeader, + char *showfilename, + struct curl_httppost *parent_post, + struct curl_httppost **httppost, + struct curl_httppost **last_post) { - struct HttpPost *post; - post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); + struct curl_httppost *post; + post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost)); if(post) { - memset(post, 0, sizeof(struct HttpPost)); + memset(post, 0, sizeof(struct curl_httppost)); post->name = name; post->namelength = name?(namelength?namelength:(long)strlen(name)):0; post->contents = value; post->contentslength = contentslength; post->contenttype = contenttype; post->contentheader = contentHeader; + post->showfilename = showfilename; post->flags = flags; } else @@ -627,14 +629,14 @@ typedef enum { } FORMcode; static -FORMcode FormAdd(struct HttpPost **httppost, - struct HttpPost **last_post, +FORMcode FormAdd(struct curl_httppost **httppost, + struct curl_httppost **last_post, va_list params) { FormInfo *first_form, *current_form, *form; FORMcode return_value = FORMADD_OK; const char *prevtype = NULL; - struct HttpPost *post = NULL; + struct curl_httppost *post = NULL; CURLformoption option; struct curl_forms *forms = NULL; const char *array_value; /* value read from an array */ @@ -677,9 +679,9 @@ FORMcode FormAdd(struct HttpPost **httppost, continue; } else { - /* check that the option is OK in an array */ + /* Check that the option is OK in an array. + TODO: make ALL options work in arrays */ - /* Daniel's note: do we really need to do this? */ if ( (option <= CURLFORM_ARRAY_START) || (option >= CURLFORM_ARRAY_END) ) { return_value = FORMADD_ILLEGAL_ARRAY; @@ -829,7 +831,7 @@ FORMcode FormAdd(struct HttpPost **httppost, if( array_state ) list = (struct curl_slist*)array_value; else - list = va_arg(params,struct curl_slist*); + list = va_arg(params, struct curl_slist*); if( current_form->contentheader ) return_value = FORMADD_OPTION_TWICE; @@ -838,6 +840,16 @@ FORMcode FormAdd(struct HttpPost **httppost, break; } + case CURLFORM_FILENAME: + { + char *filename = array_state?(char *)array_value: + va_arg(params, char *); + if( current_form->showfilename ) + return_value = FORMADD_OPTION_TWICE; + else + current_form->showfilename = strdup(filename); + break; + } default: return_value = FORMADD_UNKNOWN_OPTION; } @@ -889,7 +901,7 @@ FORMcode FormAdd(struct HttpPost **httppost, post = AddHttpPost(form->name, form->namelength, form->value, form->contentslength, form->contenttype, form->flags, - form->contentheader, + form->contentheader, form->showfilename, post, httppost, last_post); @@ -915,8 +927,8 @@ FORMcode FormAdd(struct HttpPost **httppost, return return_value; } -int curl_formadd(struct HttpPost **httppost, - struct HttpPost **last_post, +int curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, ...) { va_list arg; @@ -1009,9 +1021,9 @@ void Curl_formclean(struct FormData *form) } /* external function to free up a whole form post chain */ -void curl_formfree(struct HttpPost *form) +void curl_formfree(struct curl_httppost *form) { - struct HttpPost *next; + struct curl_httppost *next; if(!form) /* no form to free, just get out of this */ @@ -1030,18 +1042,20 @@ void curl_formfree(struct HttpPost *form) free(form->contents); /* free the contents */ if(form->contenttype) free(form->contenttype); /* free the content type */ + if(form->showfilename) + free(form->showfilename); /* free the faked file name */ free(form); /* free the struct */ } while((form=next)); /* continue */ } -struct FormData *Curl_getFormData(struct HttpPost *post, +struct FormData *Curl_getFormData(struct curl_httppost *post, int *sizep) { struct FormData *form = NULL; struct FormData *firstform; - struct HttpPost *file; + struct curl_httppost *file; int size =0; char *boundary; @@ -1093,16 +1107,25 @@ struct FormData *Curl_getFormData(struct HttpPost *post, file = post; do { + + /* If 'showfilename' is set, that is a faked name passed on to us + to use to in the formpost. If that is not set, the actually used + local file name should be added. */ + if(post->more) { /* if multiple-file */ size += AddFormDataf(&form, - "\r\n--%s\r\nContent-Disposition: attachment; filename=\"%s\"", - fileboundary, file->contents); + "\r\n--%s\r\nContent-Disposition: " + "attachment; filename=\"%s\"", + fileboundary, + (file->showfilename?file->showfilename: + file->contents)); } else if(post->flags & HTTPPOST_FILENAME) { size += AddFormDataf(&form, "; filename=\"%s\"", - post->contents); + (post->showfilename?post->showfilename: + post->contents)); } if(file->contenttype) { @@ -1294,8 +1317,8 @@ int Curl_FormReadOneLine(char *buffer, #ifdef _FORM_DEBUG int FormAddTest(const char * errormsg, - struct HttpPost **httppost, - struct HttpPost **last_post, + struct curl_httppost **httppost, + struct curl_httppost **last_post, ...) { int result; @@ -1341,8 +1364,8 @@ int main() int size; int nread; char buffer[4096]; - struct HttpPost *httppost=NULL; - struct HttpPost *last_post=NULL; + struct curl_httppost *httppost=NULL; + struct curl_httppost *last_post=NULL; struct curl_forms forms[4]; struct FormData *form; @@ -1451,9 +1474,9 @@ int main(int argc, char **argv) #endif int i; char *nextarg; - struct HttpPost *httppost=NULL; - struct HttpPost *last_post=NULL; - struct HttpPost *post; + struct curl_httppost *httppost=NULL; + struct curl_httppost *last_post=NULL; + struct curl_httppost *post; int size; int nread; char buffer[4096]; -- cgit v1.2.1 From c819e234b8980fd0484848c1e16c70c2890b55c6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 13 Mar 2002 12:10:20 +0000 Subject: now supports all options in arrays, except the CURLFORM_ARRAY itself --- lib/formdata.c | 63 +++++++++++++++++++++++++--------------------------------- 1 file changed, 27 insertions(+), 36 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 12108cb8b..16e59beed 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -678,16 +678,6 @@ FORMcode FormAdd(struct curl_httppost **httppost, array_state = FALSE; continue; } - else { - /* Check that the option is OK in an array. - TODO: make ALL options work in arrays */ - - if ( (option <= CURLFORM_ARRAY_START) || - (option >= CURLFORM_ARRAY_END) ) { - return_value = FORMADD_ILLEGAL_ARRAY; - break; - } - } } else { /* This is not array-state, get next option */ @@ -698,11 +688,16 @@ FORMcode FormAdd(struct curl_httppost **httppost, switch (option) { case CURLFORM_ARRAY: - forms = va_arg(params, struct curl_forms *); - if (forms) - array_state = TRUE; - else - return_value = FORMADD_NULL; + if(array_state) + /* we don't support an array from within an array */ + return_value = FORMADD_ILLEGAL_ARRAY; + else { + forms = va_arg(params, struct curl_forms *); + if (forms) + array_state = TRUE; + else + return_value = FORMADD_NULL; + } break; /* @@ -714,7 +709,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, if (current_form->name) return_value = FORMADD_OPTION_TWICE; else { - char *name = va_arg(params, char *); + char *name = array_state?array_value:va_arg(params, char *); if (name) current_form->name = name; /* store for the moment */ else @@ -725,7 +720,8 @@ FORMcode FormAdd(struct curl_httppost **httppost, if (current_form->namelength) return_value = FORMADD_OPTION_TWICE; else - current_form->namelength = va_arg(params, long); + current_form->namelength = + array_state?array_value:va_arg(params, long); break; /* @@ -737,7 +733,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, if (current_form->value) return_value = FORMADD_OPTION_TWICE; else { - char *value = va_arg(params, char *); + char *value = array_state?array_value:va_arg(params, char *); if (value) current_form->value = value; /* store for the moment */ else @@ -748,7 +744,8 @@ FORMcode FormAdd(struct curl_httppost **httppost, if (current_form->contentslength) return_value = FORMADD_OPTION_TWICE; else - current_form->contentslength = va_arg(params, long); + current_form->contentslength = + array_state?array_value:va_arg(params, long); break; /* Get contents from a given file name */ @@ -756,7 +753,8 @@ FORMcode FormAdd(struct curl_httppost **httppost, if (current_form->flags != 0) return_value = FORMADD_OPTION_TWICE; else { - char *filename = va_arg(params, char *); + char *filename = array_state? + array_value:va_arg(params, char *); if (filename) { current_form->value = strdup(filename); current_form->flags |= HTTPPOST_READFILE; @@ -769,11 +767,9 @@ FORMcode FormAdd(struct curl_httppost **httppost, /* We upload a file */ case CURLFORM_FILE: { - const char *filename = NULL; - if (array_state) - filename = array_value; - else - filename = va_arg(params, const char *); + const char *filename = array_state?array_value: + va_arg(params, const char *); + if (current_form->value) { if (current_form->flags & HTTPPOST_FILENAME) { if (filename) { @@ -798,11 +794,8 @@ FORMcode FormAdd(struct curl_httppost **httppost, } case CURLFORM_CONTENTTYPE: { - const char *contenttype = NULL; - if (array_state) - contenttype = array_value; - else - contenttype = va_arg(params, const char *); + const char *contenttype = + array_state?array_value:va_arg(params, const char *); if (current_form->contenttype) { if (current_form->flags & HTTPPOST_FILENAME) { if (contenttype) { @@ -827,11 +820,9 @@ FORMcode FormAdd(struct curl_httppost **httppost, } case CURLFORM_CONTENTHEADER: { - struct curl_slist* list = NULL; - if( array_state ) - list = (struct curl_slist*)array_value; - else - list = va_arg(params, struct curl_slist*); + struct curl_slist* list = array_state? + (struct curl_slist*)array_value: + va_arg(params, struct curl_slist*); if( current_form->contentheader ) return_value = FORMADD_OPTION_TWICE; @@ -842,7 +833,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, } case CURLFORM_FILENAME: { - char *filename = array_state?(char *)array_value: + char *filename = array_state?array_value: va_arg(params, char *); if( current_form->showfilename ) return_value = FORMADD_OPTION_TWICE; -- cgit v1.2.1 From eaff1a344ec0957b913766fec990a2c848824f0f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 19 Mar 2002 07:32:35 +0000 Subject: made it pass stricter compiler flags with less warnings --- lib/formdata.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 16e59beed..514fbd8ed 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -639,7 +639,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, struct curl_httppost *post = NULL; CURLformoption option; struct curl_forms *forms = NULL; - const char *array_value; /* value read from an array */ + char *array_value; /* value read from an array */ /* This is a state variable, that if TRUE means that we're parsing an array that we got passed to us. If FALSE we're parsing the input @@ -670,7 +670,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, if ( array_state ) { /* get the upcoming option from the given array */ option = forms->option; - array_value = forms->value; + array_value = (char *)forms->value; forms++; /* advance this to next entry */ if (CURLFORM_END == option) { @@ -709,7 +709,8 @@ FORMcode FormAdd(struct curl_httppost **httppost, if (current_form->name) return_value = FORMADD_OPTION_TWICE; else { - char *name = array_state?array_value:va_arg(params, char *); + char *name = array_state? + array_value:va_arg(params, char *); if (name) current_form->name = name; /* store for the moment */ else @@ -721,7 +722,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, return_value = FORMADD_OPTION_TWICE; else current_form->namelength = - array_state?array_value:va_arg(params, long); + array_state?(long)array_value:va_arg(params, long); break; /* @@ -733,7 +734,8 @@ FORMcode FormAdd(struct curl_httppost **httppost, if (current_form->value) return_value = FORMADD_OPTION_TWICE; else { - char *value = array_state?array_value:va_arg(params, char *); + char *value = + array_state?array_value:va_arg(params, char *); if (value) current_form->value = value; /* store for the moment */ else @@ -745,7 +747,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, return_value = FORMADD_OPTION_TWICE; else current_form->contentslength = - array_state?array_value:va_arg(params, long); + array_state?(long)array_value:va_arg(params, long); break; /* Get contents from a given file name */ @@ -767,8 +769,8 @@ FORMcode FormAdd(struct curl_httppost **httppost, /* We upload a file */ case CURLFORM_FILE: { - const char *filename = array_state?array_value: - va_arg(params, const char *); + char *filename = array_state?array_value: + va_arg(params, char *); if (current_form->value) { if (current_form->flags & HTTPPOST_FILENAME) { @@ -794,8 +796,8 @@ FORMcode FormAdd(struct curl_httppost **httppost, } case CURLFORM_CONTENTTYPE: { - const char *contenttype = - array_state?array_value:va_arg(params, const char *); + char *contenttype = + array_state?array_value:va_arg(params, char *); if (current_form->contenttype) { if (current_form->flags & HTTPPOST_FILENAME) { if (contenttype) { @@ -820,6 +822,8 @@ FORMcode FormAdd(struct curl_httppost **httppost, } case CURLFORM_CONTENTHEADER: { + /* this "cast increases required alignment of target type" but + we consider it OK anyway */ struct curl_slist* list = array_state? (struct curl_slist*)array_value: va_arg(params, struct curl_slist*); -- cgit v1.2.1 From 974f314f5785156af6983675aeb28313cc8ba2ea Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 19 Mar 2002 07:54:55 +0000 Subject: copyright string (year) update --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 514fbd8ed..8f8ae3744 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2002, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. * * In order to be useful for every potential user, curl and libcurl are * dual-licensed under the MPL and the MIT/X-derivate licenses. -- cgit v1.2.1 From 90b51831fd2dea9a4c29237e74472eb4735034ef Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Apr 2002 11:11:01 +0000 Subject: Tor Arntsen's fix for "CGI_Lite" compliance! --- lib/formdata.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 8f8ae3744..08715d5b3 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -982,8 +982,8 @@ char *Curl_FormBoundary(void) the same form won't be identical */ int i; - static char table64[]= - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + static char table62[]= + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; retstring = (char *)malloc(BOUNDARY_LENGTH); @@ -995,7 +995,7 @@ char *Curl_FormBoundary(void) strcpy(retstring, "curl"); /* bonus commercials 8*) */ for(i=4; i<(BOUNDARY_LENGTH-1); i++) { - retstring[i] = table64[rand()%64]; + retstring[i] = table62[rand()%62]; } retstring[BOUNDARY_LENGTH-1]=0; /* zero terminate */ -- cgit v1.2.1 From 95f78080abd4a07f95e1aa06737e1faa854614c7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 15 Apr 2002 11:19:03 +0000 Subject: This makes formposting with a specified file missing fail. curl_easy_perform will then return CURLE_READ_ERROR. --- lib/formdata.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 08715d5b3..e032382b1 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1044,22 +1044,24 @@ void curl_formfree(struct curl_httppost *form) } while((form=next)); /* continue */ } -struct FormData *Curl_getFormData(struct curl_httppost *post, - int *sizep) +CURLcode Curl_getFormData(struct FormData **finalform, + struct curl_httppost *post, + int *sizep) { struct FormData *form = NULL; struct FormData *firstform; - struct curl_httppost *file; + CURLcode result = CURLE_OK; int size =0; char *boundary; char *fileboundary=NULL; struct curl_slist* curList; + *finalform=NULL; /* default form is empty */ if(!post) - return NULL; /* no input => no output! */ + return result; /* no input => no output! */ boundary = Curl_FormBoundary(); @@ -1166,20 +1168,24 @@ struct FormData *Curl_getFormData(struct curl_httppost *post, /*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */ /*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */ if(fileread) { - while((nread = fread(buffer, 1, 1024, fileread))) { - size += AddFormData(&form, - buffer, - nread); - } + while((nread = fread(buffer, 1, 1024, fileread))) + size += AddFormData(&form, buffer, nread); + if(fileread != stdin) fclose(fileread); } else { +#if 0 /* File wasn't found, add a nothing field! */ size += AddFormData(&form, "", 0); +#endif + Curl_formclean(firstform); + free(boundary); + *finalform = NULL; + return CURLE_READ_ERROR; } } - else { + else { /* include the contents we got */ size += AddFormData(&form, post->contents, post->contentslength); } @@ -1205,7 +1211,9 @@ struct FormData *Curl_getFormData(struct curl_httppost *post, free(boundary); - return firstform; + *finalform=firstform; + + return result; } int Curl_FormInit(struct Form *form, struct FormData *formdata ) -- cgit v1.2.1 From 5d2944c21185200ebc1ba194fd8214557bb62e66 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 May 2002 07:44:27 +0000 Subject: curl_formadd() now returns 'CURLFORMcode' instead of int, to better enable checking for particular errors. curl/curl.h defines the errros --- lib/formdata.c | 101 +++++++++++++++++++++++++-------------------------------- 1 file changed, 44 insertions(+), 57 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index e032382b1..a5d367cd5 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -602,39 +602,26 @@ static int AllocAndCopy (char **buffer, int buffer_length) * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); * * Returns: - * FORMADD_OK on success - * FORMADD_MEMORY if the FormInfo allocation fails - * FORMADD_OPTION_TWICE if one option is given twice for one Form - * FORMADD_NULL if a null pointer was given for a char - * FORMADD_MEMORY if the allocation of a FormInfo struct failed - * FORMADD_UNKNOWN_OPTION if an unknown option was used - * FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error) - * FORMADD_MEMORY if a HttpPost struct cannot be allocated - * FORMADD_MEMORY if some allocation for string copying failed. - * FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error) + * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array * ***************************************************************************/ -typedef enum { - FORMADD_OK, /* first, no error */ - - FORMADD_MEMORY, - FORMADD_OPTION_TWICE, - FORMADD_NULL, - FORMADD_UNKNOWN_OPTION, - FORMADD_INCOMPLETE, - FORMADD_ILLEGAL_ARRAY, - - FORMADD_LAST /* last */ -} FORMcode; - static -FORMcode FormAdd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - va_list params) +CURLFORMcode FormAdd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + va_list params) { FormInfo *first_form, *current_form, *form; - FORMcode return_value = FORMADD_OK; + CURLFORMcode return_value = CURL_FORMADD_OK; const char *prevtype = NULL; struct curl_httppost *post = NULL; CURLformoption option; @@ -655,7 +642,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, current_form = first_form; } else - return FORMADD_MEMORY; + return CURL_FORMADD_MEMORY; /* * Loop through all the options set. @@ -663,7 +650,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, while (1) { /* break if we have an error to report */ - if (return_value != FORMADD_OK) + if (return_value != CURL_FORMADD_OK) break; /* first see if we have more parts of the array param */ @@ -690,13 +677,13 @@ FORMcode FormAdd(struct curl_httppost **httppost, case CURLFORM_ARRAY: if(array_state) /* we don't support an array from within an array */ - return_value = FORMADD_ILLEGAL_ARRAY; + return_value = CURL_FORMADD_ILLEGAL_ARRAY; else { forms = va_arg(params, struct curl_forms *); if (forms) array_state = TRUE; else - return_value = FORMADD_NULL; + return_value = CURL_FORMADD_NULL; } break; @@ -707,19 +694,19 @@ FORMcode FormAdd(struct curl_httppost **httppost, current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ case CURLFORM_COPYNAME: if (current_form->name) - return_value = FORMADD_OPTION_TWICE; + return_value = CURL_FORMADD_OPTION_TWICE; else { char *name = array_state? array_value:va_arg(params, char *); if (name) current_form->name = name; /* store for the moment */ else - return_value = FORMADD_NULL; + return_value = CURL_FORMADD_NULL; } break; case CURLFORM_NAMELENGTH: if (current_form->namelength) - return_value = FORMADD_OPTION_TWICE; + return_value = CURL_FORMADD_OPTION_TWICE; else current_form->namelength = array_state?(long)array_value:va_arg(params, long); @@ -732,19 +719,19 @@ FORMcode FormAdd(struct curl_httppost **httppost, current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ case CURLFORM_COPYCONTENTS: if (current_form->value) - return_value = FORMADD_OPTION_TWICE; + return_value = CURL_FORMADD_OPTION_TWICE; else { char *value = array_state?array_value:va_arg(params, char *); if (value) current_form->value = value; /* store for the moment */ else - return_value = FORMADD_NULL; + return_value = CURL_FORMADD_NULL; } break; case CURLFORM_CONTENTSLENGTH: if (current_form->contentslength) - return_value = FORMADD_OPTION_TWICE; + return_value = CURL_FORMADD_OPTION_TWICE; else current_form->contentslength = array_state?(long)array_value:va_arg(params, long); @@ -753,7 +740,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, /* Get contents from a given file name */ case CURLFORM_FILECONTENT: if (current_form->flags != 0) - return_value = FORMADD_OPTION_TWICE; + return_value = CURL_FORMADD_OPTION_TWICE; else { char *filename = array_state? array_value:va_arg(params, char *); @@ -762,7 +749,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, current_form->flags |= HTTPPOST_READFILE; } else - return_value = FORMADD_NULL; + return_value = CURL_FORMADD_NULL; } break; @@ -777,19 +764,19 @@ FORMcode FormAdd(struct curl_httppost **httppost, if (filename) { if (!(current_form = AddFormInfo(strdup(filename), NULL, current_form))) - return_value = FORMADD_MEMORY; + return_value = CURL_FORMADD_MEMORY; } else - return_value = FORMADD_NULL; + return_value = CURL_FORMADD_NULL; } else - return_value = FORMADD_OPTION_TWICE; + return_value = CURL_FORMADD_OPTION_TWICE; } else { if (filename) current_form->value = strdup(filename); else - return_value = FORMADD_NULL; + return_value = CURL_FORMADD_NULL; current_form->flags |= HTTPPOST_FILENAME; } break; @@ -804,19 +791,19 @@ FORMcode FormAdd(struct curl_httppost **httppost, if (!(current_form = AddFormInfo(NULL, strdup(contenttype), current_form))) - return_value = FORMADD_MEMORY; + return_value = CURL_FORMADD_MEMORY; } else - return_value = FORMADD_NULL; + return_value = CURL_FORMADD_NULL; } else - return_value = FORMADD_OPTION_TWICE; + return_value = CURL_FORMADD_OPTION_TWICE; } else { if (contenttype) current_form->contenttype = strdup(contenttype); else - return_value = FORMADD_NULL; + return_value = CURL_FORMADD_NULL; } break; } @@ -829,7 +816,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, va_arg(params, struct curl_slist*); if( current_form->contentheader ) - return_value = FORMADD_OPTION_TWICE; + return_value = CURL_FORMADD_OPTION_TWICE; else current_form->contentheader = list; @@ -840,17 +827,17 @@ FORMcode FormAdd(struct curl_httppost **httppost, char *filename = array_state?array_value: va_arg(params, char *); if( current_form->showfilename ) - return_value = FORMADD_OPTION_TWICE; + return_value = CURL_FORMADD_OPTION_TWICE; else current_form->showfilename = strdup(filename); break; } default: - return_value = FORMADD_UNKNOWN_OPTION; + return_value = CURL_FORMADD_UNKNOWN_OPTION; } } - if(FORMADD_OK == return_value) { + if(CURL_FORMADD_OK == return_value) { /* go through the list, check for copleteness and if everything is * alright add the HttpPost item otherwise set return_value accordingly */ @@ -866,7 +853,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, ( (form->flags & HTTPPOST_READFILE) && (form->flags & HTTPPOST_PTRCONTENTS) ) ) { - return_value = FORMADD_INCOMPLETE; + return_value = CURL_FORMADD_INCOMPLETE; break; } else { @@ -880,7 +867,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, (form == first_form) ) { /* copy name (without strdup; possibly contains null characters) */ if (AllocAndCopy(&form->name, form->namelength)) { - return_value = FORMADD_MEMORY; + return_value = CURL_FORMADD_MEMORY; break; } } @@ -889,7 +876,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, !(form->flags & HTTPPOST_PTRCONTENTS) ) { /* copy value (without strdup; possibly contains null characters) */ if (AllocAndCopy(&form->value, form->contentslength)) { - return_value = FORMADD_MEMORY; + return_value = CURL_FORMADD_MEMORY; break; } } @@ -901,7 +888,7 @@ FORMcode FormAdd(struct curl_httppost **httppost, last_post); if(!post) - return_value = FORMADD_MEMORY; + return_value = CURL_FORMADD_MEMORY; if (form->contenttype) prevtype = form->contenttype; @@ -922,12 +909,12 @@ FORMcode FormAdd(struct curl_httppost **httppost, return return_value; } -int curl_formadd(struct curl_httppost **httppost, +CURLFORMcode curl_formadd(struct curl_httppost **httppost, struct curl_httppost **last_post, ...) { va_list arg; - int result; + CURLFORMcode result; va_start(arg, last_post); result = FormAdd(httppost, last_post, arg); va_end(arg); -- cgit v1.2.1 From 08ef208fb78fb2eabc5cec08c23e74e251eac898 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Jun 2002 11:13:01 +0000 Subject: added disable-[protocol] support, largely provided by Miklos Nemeth --- lib/formdata.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index a5d367cd5..5c1575e57 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -109,6 +109,8 @@ Content-Disposition: form-data; name="FILECONTENT" #include "setup.h" +#ifndef CURL_DISABLE_HTTP + #include #include #include @@ -1505,6 +1507,8 @@ int main(int argc, char **argv) #endif +#endif /* CURL_DISABLE_HTTP */ + /* * local variables: * eval: (load-file "../curl-mode.el") -- cgit v1.2.1 From 131645dc310a70d8d8ca1df00ec7329bc80c940e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 Jun 2002 21:40:59 +0000 Subject: Chris Combes added CURLFORM_BUFFER, CURLFORM_BUFFERPTR, CURLFORM_BUFFERLENGTH --- lib/formdata.c | 172 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 130 insertions(+), 42 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 5c1575e57..b4623ec70 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -400,6 +400,10 @@ int curl_formparse(char *input, static struct curl_httppost * AddHttpPost(char * name, long namelength, char * value, long contentslength, + + /* CMC: Added support for buffer uploads */ + char * buffer, long bufferlength, + char *contenttype, long flags, struct curl_slist* contentHeader, @@ -416,6 +420,11 @@ AddHttpPost(char * name, long namelength, post->namelength = name?(namelength?namelength:(long)strlen(name)):0; post->contents = value; post->contentslength = contentslength; + + /* CMC: Added support for buffer uploads */ + post->buffer = buffer; + post->bufferlength = bufferlength; + post->contenttype = contenttype; post->contentheader = contentHeader; post->showfilename = showfilename; @@ -783,9 +792,63 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } break; } + + /* CMC: Added support for buffer uploads */ + case CURLFORM_BUFFER: + { + char *filename = array_state?array_value: + va_arg(params, char *); + + if (current_form->value) { + if (current_form->flags & HTTPPOST_BUFFER) { + if (filename) { + if (!(current_form = AddFormInfo(strdup(filename), + NULL, current_form))) + return_value = CURL_FORMADD_MEMORY; + } + else + return_value = CURL_FORMADD_NULL; + } + else + return_value = CURL_FORMADD_OPTION_TWICE; + } + else { + if (filename) + current_form->value = strdup(filename); + else + return_value = CURL_FORMADD_NULL; + current_form->flags |= HTTPPOST_BUFFER; + } + break; + } + + /* CMC: Added support for buffer uploads */ + case CURLFORM_BUFFERPTR: + current_form->flags |= HTTPPOST_PTRBUFFER; + if (current_form->buffer) + return_value = CURL_FORMADD_OPTION_TWICE; + else { + char *buffer = + array_state?array_value:va_arg(params, char *); + if (buffer) + current_form->buffer = buffer; /* store for the moment */ + else + return_value = CURL_FORMADD_NULL; + } + break; + + /* CMC: Added support for buffer uploads */ + case CURLFORM_BUFFERLENGTH: + if (current_form->bufferlength) + return_value = CURL_FORMADD_OPTION_TWICE; + else + current_form->bufferlength = + array_state?(long)array_value:va_arg(params, long); + break; + case CURLFORM_CONTENTTYPE: { - char *contenttype = + char *contenttype = array_state?array_value:va_arg(params, char *); if (current_form->contenttype) { if (current_form->flags & HTTPPOST_FILENAME) { @@ -852,6 +915,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, (form->flags & HTTPPOST_FILENAME) ) || ( (form->flags & HTTPPOST_FILENAME) && (form->flags & HTTPPOST_PTRCONTENTS) ) || + + /* CMC: Added support for buffer uploads */ + ( (!form->buffer) && + (form->flags & HTTPPOST_BUFFER) && + (form->flags & HTTPPOST_PTRBUFFER) ) || + ( (form->flags & HTTPPOST_READFILE) && (form->flags & HTTPPOST_PTRCONTENTS) ) ) { @@ -859,7 +928,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, break; } else { - if ( (form->flags & HTTPPOST_FILENAME) && + if ( ((form->flags & HTTPPOST_FILENAME) || + (form->flags & HTTPPOST_BUFFER)) && !form->contenttype ) { /* our contenttype is missing */ form->contenttype @@ -875,7 +945,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } if ( !(form->flags & HTTPPOST_FILENAME) && !(form->flags & HTTPPOST_READFILE) && - !(form->flags & HTTPPOST_PTRCONTENTS) ) { + !(form->flags & HTTPPOST_PTRCONTENTS) && + + /* CMC: Added support for buffer uploads */ + !(form->flags & HTTPPOST_PTRBUFFER) ) { + /* copy value (without strdup; possibly contains null characters) */ if (AllocAndCopy(&form->value, form->contentslength)) { return_value = CURL_FORMADD_MEMORY; @@ -884,6 +958,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } post = AddHttpPost(form->name, form->namelength, form->value, form->contentslength, + + /* CMC: Added support for buffer uploads */ + form->buffer, form->bufferlength, + form->contenttype, form->flags, form->contentheader, form->showfilename, post, httppost, @@ -1085,9 +1163,9 @@ CURLcode Curl_getFormData(struct FormData **finalform, fileboundary = Curl_FormBoundary(); size += AddFormDataf(&form, - "\r\nContent-Type: multipart/mixed," - " boundary=%s\r\n", - fileboundary); + "\r\nContent-Type: multipart/mixed," + " boundary=%s\r\n", + fileboundary); } file = post; @@ -1099,26 +1177,30 @@ CURLcode Curl_getFormData(struct FormData **finalform, local file name should be added. */ if(post->more) { - /* if multiple-file */ - size += AddFormDataf(&form, - "\r\n--%s\r\nContent-Disposition: " + /* if multiple-file */ + size += AddFormDataf(&form, + "\r\n--%s\r\nContent-Disposition: " "attachment; filename=\"%s\"", - fileboundary, + fileboundary, (file->showfilename?file->showfilename: file->contents)); } - else if(post->flags & HTTPPOST_FILENAME) { - size += AddFormDataf(&form, - "; filename=\"%s\"", - (post->showfilename?post->showfilename: + else if((post->flags & HTTPPOST_FILENAME) || + + /* CMC: Added support for buffer uploads */ + (post->flags & HTTPPOST_BUFFER)) { + + size += AddFormDataf(&form, + "; filename=\"%s\"", + (post->showfilename?post->showfilename: post->contents)); } if(file->contenttype) { - /* we have a specified type */ - size += AddFormDataf(&form, - "\r\nContent-Type: %s", - file->contenttype); + /* we have a specified type */ + size += AddFormDataf(&form, + "\r\nContent-Type: %s", + file->contenttype); } curList = file->contentheader; @@ -1136,47 +1218,53 @@ CURLcode Curl_getFormData(struct FormData **finalform, */ if(file->contenttype && - !strnequal("text/", file->contenttype, 5)) { - /* this is not a text content, mention our binary encoding */ - size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); + !strnequal("text/", file->contenttype, 5)) { + /* this is not a text content, mention our binary encoding */ + size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); } #endif size += AddFormData(&form, "\r\n\r\n", 0); if((post->flags & HTTPPOST_FILENAME) || - (post->flags & HTTPPOST_READFILE)) { - /* we should include the contents from the specified file */ - FILE *fileread; - char buffer[1024]; - int nread; + (post->flags & HTTPPOST_READFILE)) { + /* we should include the contents from the specified file */ + FILE *fileread; + char buffer[1024]; + int nread; - fileread = strequal("-", file->contents)?stdin: + fileread = strequal("-", file->contents)?stdin: /* binary read for win32 crap */ -/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */ -/*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */ -/*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */ - if(fileread) { - while((nread = fread(buffer, 1, 1024, fileread))) - size += AddFormData(&form, buffer, nread); + /*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */ + /*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */ + /*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */ + if(fileread) { + while((nread = fread(buffer, 1, 1024, fileread))) + size += AddFormData(&form, buffer, nread); if(fileread != stdin) fclose(fileread); - } + } else { #if 0 /* File wasn't found, add a nothing field! */ - size += AddFormData(&form, "", 0); + size += AddFormData(&form, "", 0); #endif Curl_formclean(firstform); free(boundary); *finalform = NULL; return CURLE_READ_ERROR; - } + } + + /* CMC: Added support for buffer uploads */ + } else if (post->flags & HTTPPOST_BUFFER) { + /* include contents of buffer */ + size += AddFormData(&form, post->buffer, post->bufferlength); } + else { - /* include the contents we got */ - size += AddFormData(&form, post->contents, post->contentslength); + /* include the contents we got */ + size += AddFormData(&form, post->contents, post->contentslength); } } while((file = file->more)); /* for each specified file for this field */ @@ -1184,8 +1272,8 @@ CURLcode Curl_getFormData(struct FormData **finalform, /* this was a multiple-file inclusion, make a termination file boundary: */ size += AddFormDataf(&form, - "\r\n--%s--", - fileboundary); + "\r\n--%s--", + fileboundary); free(fileboundary); } @@ -1193,8 +1281,8 @@ CURLcode Curl_getFormData(struct FormData **finalform, /* end-boundary for everything */ size += AddFormDataf(&form, - "\r\n--%s--\r\n", - boundary); + "\r\n--%s--\r\n", + boundary); *sizep = size; -- cgit v1.2.1 From ba4e69bebc8f7f32f3bc7faa1e13e7580754075b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 3 Sep 2002 11:52:59 +0000 Subject: updated source code boilerplate/header --- lib/formdata.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index b4623ec70..d8df7e3da 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | * / __| | | | |_) | | @@ -7,19 +7,19 @@ * * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. * - * In order to be useful for every potential user, curl and libcurl are - * dual-licensed under the MPL and the MIT/X-derivate licenses. - * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the MPL or the MIT/X-derivate - * licenses. You may pick one of these licenses. + * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * $Id$ - *****************************************************************************/ + ***************************************************************************/ /* Debug the form generator stand-alone by compiling this source file with: -- cgit v1.2.1 From 6a88c8d845bc5aa6b0170f4194bc8cbde36976e0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 28 Oct 2002 19:21:30 +0000 Subject: prevent compiler warning --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index d8df7e3da..c883ec78c 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -637,7 +637,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, struct curl_httppost *post = NULL; CURLformoption option; struct curl_forms *forms = NULL; - char *array_value; /* value read from an array */ + char *array_value=NULL; /* value read from an array */ /* This is a state variable, that if TRUE means that we're parsing an array that we got passed to us. If FALSE we're parsing the input -- cgit v1.2.1 From 01387f42c582fdbebc12cee39ed91346bd42ec04 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 28 Oct 2002 21:52:00 +0000 Subject: kromJx@crosswinds.net's fix that now uses checkprefix() instead of strnequal() when the third argument was strlen(first argument) anyway. This makes it less prone to errors. (Slightly edited by me) --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index c883ec78c..1b15e8102 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1218,7 +1218,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, */ if(file->contenttype && - !strnequal("text/", file->contenttype, 5)) { + !checkprefix("text/", file->contenttype)) { /* this is not a text content, mention our binary encoding */ size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); } -- cgit v1.2.1 From e90d5280260808a164c1c59677fa884fcba60c9c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 29 Nov 2002 08:12:20 +0000 Subject: let the Curl_FormReader() return 0 when it reaches end of data to that the chunked transfer work --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 1b15e8102..0015a6203 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1319,7 +1319,7 @@ int Curl_FormReader(char *buffer, wantedsize = size * nitems; if(!form->data) - return -1; /* nothing, error, empty */ + return 0; /* nothing, error, empty */ do { -- cgit v1.2.1 From f26a338a54e04d0a6907f5d2479d8b0fa9daf297 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Jan 2003 21:08:12 +0000 Subject: copyright year update in the source header --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 0015a6203..a9a4b762d 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2003, 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 -- cgit v1.2.1 From a7c72b7abf1213c471f3fd11e6b8e3a37d526f60 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 29 Jan 2003 10:14:20 +0000 Subject: removed the local variables for emacs and vim, use the new sample.emacs way for emacs, and vim users should provide a similar non-polluting style --- lib/formdata.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index a9a4b762d..5e961440a 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1596,11 +1596,3 @@ int main(int argc, char **argv) #endif #endif /* CURL_DISABLE_HTTP */ - -/* - * local variables: - * eval: (load-file "../curl-mode.el") - * end: - * vim600: fdm=marker - * vim: et sw=2 ts=2 sts=2 tw=78 - */ -- cgit v1.2.1 From 61788a0389962ecf22b3711b142a1e6783359bf1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 4 Apr 2003 12:24:01 +0000 Subject: Changed how boundary strings are generated. This new way uses 28 dashes and 12 following hexadecimal letters, which seems to be what IE uses. This makes curl work smoother with more stupidly written server apps. Worked this out together with Martijn Broenland. --- lib/formdata.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 5e961440a..46dd454fa 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -128,11 +128,8 @@ Content-Disposition: form-data; name="FILECONTENT" #include "memdebug.h" #endif -/* Length of the random boundary string. The risk of this being used - in binary data is very close to zero, 64^32 makes - 6277101735386680763835789423207666416102355444464034512896 - combinations... */ -#define BOUNDARY_LENGTH 32 +/* Length of the random boundary string. */ +#define BOUNDARY_LENGTH 40 /* What kind of Content-Type to use on un-specified files with unrecognized extensions. */ @@ -1049,22 +1046,23 @@ char *Curl_FormBoundary(void) the same form won't be identical */ int i; - static char table62[]= - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + static char table16[]="abcdef0123456789"; - retstring = (char *)malloc(BOUNDARY_LENGTH); + retstring = (char *)malloc(BOUNDARY_LENGTH+1); if(!retstring) return NULL; /* failed */ srand(time(NULL)+randomizer++); /* seed */ - strcpy(retstring, "curl"); /* bonus commercials 8*) */ + strcpy(retstring, "----------------------------"); - for(i=4; i<(BOUNDARY_LENGTH-1); i++) { - retstring[i] = table62[rand()%62]; - } - retstring[BOUNDARY_LENGTH-1]=0; /* zero terminate */ + for(i=strlen(retstring); i Date: Tue, 15 Apr 2003 09:29:39 +0000 Subject: treat uploaded .html files as text/html by default --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 46dd454fa..76798616a 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -517,7 +517,7 @@ static const char * ContentTypeForFilename (const char *filename, {".jpg", "image/jpeg"}, {".jpeg", "image/jpeg"}, {".txt", "text/plain"}, - {".html", "text/plain"} + {".html", "text/html"} }; if(prevtype) -- cgit v1.2.1 From 308bc9d919d57388f269c473778ea7f6a331d1c5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 26 Jun 2003 11:22:12 +0000 Subject: use CURLDEBUG instead of MALLOCDEBUG for preprocessor conditions --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 76798616a..9ac805bb0 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -124,7 +124,7 @@ Content-Disposition: form-data; name="FILECONTENT" #include "strequal.h" /* The last #include file should be: */ -#ifdef MALLOCDEBUG +#ifdef CURLDEBUG #include "memdebug.h" #endif -- cgit v1.2.1 From 1e251a64f3ba31ef19c979ffac5601adae391783 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 13 Nov 2003 07:43:18 +0000 Subject: Default Content-Type for formparts has changed to "application/octet-stream". This seems more appropriate, and I believe mozilla and the likes do this. .html files now get text/html as Content-Type. Pointed out in bug report #839806. --- lib/formdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 9ac805bb0..6aaeb167b 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -133,7 +133,7 @@ Content-Disposition: form-data; name="FILECONTENT" /* What kind of Content-Type to use on un-specified files with unrecognized extensions. */ -#define HTTPPOST_CONTENTTYPE_DEFAULT "text/plain" +#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream" /* This is a silly duplicate of the function in main.c to enable this source to compile stand-alone for better debugging */ @@ -267,7 +267,7 @@ int FormParse(char *input, {".jpg", "image/jpeg"}, {".jpeg", "image/jpeg"}, {".txt", "text/plain"}, - {".html", "text/plain"} + {".html", "text/html"} }; if(prevtype) -- cgit v1.2.1 From 053f6c85efd0bf698f73343989474d672d0563a8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 7 Jan 2004 09:19:33 +0000 Subject: updated year in the copyright string --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 6aaeb167b..ecfb0e559 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2003, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2004, 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 -- cgit v1.2.1 From 4d17d6876e4b2f08380812c4ec113073b0a14639 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 29 Jan 2004 13:56:45 +0000 Subject: Dan Fandrich's cleanup patch to make pedantic compiler options cause less warnings. Minor edits by me. --- lib/formdata.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index ecfb0e559..31d14feb4 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -118,6 +118,9 @@ Content-Disposition: form-data; name="FILECONTENT" #include +#ifndef CURL_OLDSTYLE +#define CURL_OLDSTYLE 1 /* enable deprecated prototype for curl_formparse */ +#endif #include #include "formdata.h" -- cgit v1.2.1 From d571064b65195aa7c71200af549a95404a2f0ce1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 26 Feb 2004 13:40:43 +0000 Subject: Clear up int/long/size_t/ssize_t usage a bit --- lib/formdata.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 31d14feb4..61ea3d0a7 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -556,15 +556,16 @@ static const char * ContentTypeForFilename (const char *filename, * Returns 0 on success and 1 if the malloc failed. * ***************************************************************************/ -static int AllocAndCopy (char **buffer, int buffer_length) +static int AllocAndCopy(char **buffer, size_t buffer_length) { const char *src = *buffer; - int length, add = 0; + size_t length; + bool add = FALSE; if (buffer_length) length = buffer_length; else { length = strlen(*buffer); - add = 1; + add = TRUE; } *buffer = (char*)malloc(length+add); if (!*buffer) @@ -1003,7 +1004,7 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost, static int AddFormData(struct FormData **formp, const void *line, - long length) + size_t length) { struct FormData *newform = (struct FormData *) malloc(sizeof(struct FormData)); @@ -1047,7 +1048,7 @@ char *Curl_FormBoundary(void) char *retstring; static int randomizer=0; /* this is just so that two boundaries within the same form won't be identical */ - int i; + size_t i; static char table16[]="abcdef0123456789"; @@ -1114,7 +1115,7 @@ void curl_formfree(struct curl_httppost *form) CURLcode Curl_getFormData(struct FormData **finalform, struct curl_httppost *post, - int *sizep) + size_t *sizep) { struct FormData *form = NULL; struct FormData *firstform; @@ -1232,7 +1233,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, /* we should include the contents from the specified file */ FILE *fileread; char buffer[1024]; - int nread; + size_t nread; fileread = strequal("-", file->contents)?stdin: /* binary read for win32 crap */ @@ -1306,14 +1307,14 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata ) } /* fread() emulation */ -int Curl_FormReader(char *buffer, - size_t size, - size_t nitems, - FILE *mydata) +size_t Curl_FormReader(char *buffer, + size_t size, + size_t nitems, + FILE *mydata) { struct Form *form; - int wantedsize; - int gotsize = 0; + size_t wantedsize; + size_t gotsize = 0; form=(struct Form *)mydata; @@ -1352,21 +1353,21 @@ int Curl_FormReader(char *buffer, } /* possible (old) fread() emulation that copies at most one line */ -int Curl_FormReadOneLine(char *buffer, - size_t size, - size_t nitems, - FILE *mydata) +size_t Curl_FormReadOneLine(char *buffer, + size_t size, + size_t nitems, + FILE *mydata) { struct Form *form; - int wantedsize; - int gotsize; + size_t wantedsize; + size_t gotsize; form=(struct Form *)mydata; wantedsize = size * nitems; if(!form->data) - return -1; /* nothing, error, empty */ + return 0; /* nothing, error, empty */ do { @@ -1443,7 +1444,7 @@ int main() int value6length = strlen(value5); int errors = 0; int size; - int nread; + size_t nread; char buffer[4096]; struct curl_httppost *httppost=NULL; struct curl_httppost *last_post=NULL; -- cgit v1.2.1 From 6c78b4b7c0673be0ca92d728c6fab6c260a78599 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 27 Feb 2004 13:21:14 +0000 Subject: fixed some more size_t/int/long warnings and removed a few CMC comments --- lib/formdata.c | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 61ea3d0a7..98838dd5c 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -398,12 +398,9 @@ int curl_formparse(char *input, * ***************************************************************************/ static struct curl_httppost * -AddHttpPost(char * name, long namelength, - char * value, long contentslength, - - /* CMC: Added support for buffer uploads */ - char * buffer, long bufferlength, - +AddHttpPost(char * name, size_t namelength, + char * value, size_t contentslength, + char * buffer, size_t bufferlength, char *contenttype, long flags, struct curl_slist* contentHeader, @@ -417,14 +414,11 @@ AddHttpPost(char * name, long namelength, if(post) { memset(post, 0, sizeof(struct curl_httppost)); post->name = name; - post->namelength = name?(namelength?namelength:(long)strlen(name)):0; + post->namelength = (long)(name?(namelength?namelength:strlen(name)):0); post->contents = value; post->contentslength = contentslength; - - /* CMC: Added support for buffer uploads */ post->buffer = buffer; post->bufferlength = bufferlength; - post->contenttype = contenttype; post->contentheader = contentHeader; post->showfilename = showfilename; @@ -794,7 +788,6 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, break; } - /* CMC: Added support for buffer uploads */ case CURLFORM_BUFFER: { char *filename = array_state?array_value: @@ -823,7 +816,6 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, break; } - /* CMC: Added support for buffer uploads */ case CURLFORM_BUFFERPTR: current_form->flags |= HTTPPOST_PTRBUFFER; if (current_form->buffer) @@ -838,7 +830,6 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } break; - /* CMC: Added support for buffer uploads */ case CURLFORM_BUFFERLENGTH: if (current_form->bufferlength) return_value = CURL_FORMADD_OPTION_TWICE; @@ -917,7 +908,6 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, ( (form->flags & HTTPPOST_FILENAME) && (form->flags & HTTPPOST_PTRCONTENTS) ) || - /* CMC: Added support for buffer uploads */ ( (!form->buffer) && (form->flags & HTTPPOST_BUFFER) && (form->flags & HTTPPOST_PTRBUFFER) ) || @@ -947,8 +937,6 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if ( !(form->flags & HTTPPOST_FILENAME) && !(form->flags & HTTPPOST_READFILE) && !(form->flags & HTTPPOST_PTRCONTENTS) && - - /* CMC: Added support for buffer uploads */ !(form->flags & HTTPPOST_PTRBUFFER) ) { /* copy value (without strdup; possibly contains null characters) */ @@ -959,10 +947,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } post = AddHttpPost(form->name, form->namelength, form->value, form->contentslength, - - /* CMC: Added support for buffer uploads */ form->buffer, form->bufferlength, - form->contenttype, form->flags, form->contentheader, form->showfilename, post, httppost, @@ -1188,8 +1173,6 @@ CURLcode Curl_getFormData(struct FormData **finalform, file->contents)); } else if((post->flags & HTTPPOST_FILENAME) || - - /* CMC: Added support for buffer uploads */ (post->flags & HTTPPOST_BUFFER)) { size += AddFormDataf(&form, @@ -1258,8 +1241,8 @@ CURLcode Curl_getFormData(struct FormData **finalform, return CURLE_READ_ERROR; } - /* CMC: Added support for buffer uploads */ - } else if (post->flags & HTTPPOST_BUFFER) { + } + else if (post->flags & HTTPPOST_BUFFER) { /* include contents of buffer */ size += AddFormData(&form, post->buffer, post->bufferlength); } -- cgit v1.2.1 From 88e226c686d97a84ea7cbce34ce5bcba0f5d58ea Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Mar 2004 13:11:28 +0000 Subject: some more size_t usage, and two added typecasts when converting from size_t to long (MIPSpro warnings) --- lib/formdata.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 98838dd5c..ccb73fad0 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -416,9 +416,9 @@ AddHttpPost(char * name, size_t namelength, post->name = name; post->namelength = (long)(name?(namelength?namelength:strlen(name)):0); post->contents = value; - post->contentslength = contentslength; + post->contentslength = (long)contentslength; post->buffer = buffer; - post->bufferlength = bufferlength; + post->bufferlength = (long)bufferlength; post->contenttype = contenttype; post->contentheader = contentHeader; post->showfilename = showfilename; @@ -987,9 +987,9 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost, return result; } -static int AddFormData(struct FormData **formp, - const void *line, - size_t length) +static size_t AddFormData(struct FormData **formp, + const void *line, + size_t length) { struct FormData *newform = (struct FormData *) malloc(sizeof(struct FormData)); @@ -1015,7 +1015,7 @@ static int AddFormData(struct FormData **formp, } -static int AddFormDataf(struct FormData **formp, +static size_t AddFormDataf(struct FormData **formp, const char *fmt, ...) { char s[4096]; @@ -1107,7 +1107,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, struct curl_httppost *file; CURLcode result = CURLE_OK; - int size =0; + size_t size =0; char *boundary; char *fileboundary=NULL; struct curl_slist* curList; -- cgit v1.2.1 From 94a1d09ac7500afdd6f3cef3fbfefa16072f2704 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Mar 2004 14:22:16 +0000 Subject: more variable type fixing for the huge posts --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index ccb73fad0..58d1547af 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1100,7 +1100,7 @@ void curl_formfree(struct curl_httppost *form) CURLcode Curl_getFormData(struct FormData **finalform, struct curl_httppost *post, - size_t *sizep) + curl_off_t *sizep) { struct FormData *form = NULL; struct FormData *firstform; -- cgit v1.2.1 From 70e2aadc18fce9f6e3b9c06612c8314bf4f710b1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 23 Apr 2004 10:37:52 +0000 Subject: Replaced Curl_FormReadOneLine with Curl_formpostheader as that is the only use for it. It saves one extra copy of the header. I also added comments for several functions in formdata.c --- lib/formdata.c | 98 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 54 insertions(+), 44 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 58d1547af..57ad283af 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -176,7 +176,7 @@ int FormParse(char *input, struct curl_httppost **httppost, struct curl_httppost **last_post) { - /* nextarg MUST be a string in the format 'name=contents' and we'll + /* 'input' MUST be a string in the format 'name=contents' and we'll build a linked list with the info */ char name[256]; char *contents; @@ -975,9 +975,13 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return return_value; } +/* + * curl_formadd() is a public API to add a section to the multipart formpost. + */ + CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...) + struct curl_httppost **last_post, + ...) { va_list arg; CURLFORMcode result; @@ -987,6 +991,9 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost, return result; } +/* + * AddFormData() adds a chunk of data to the FormData linked list. + */ static size_t AddFormData(struct FormData **formp, const void *line, size_t length) @@ -1014,9 +1021,12 @@ static size_t AddFormData(struct FormData **formp, return length; } +/* + * AddFormDataf() adds printf()-style formatted data to the formdata chain. + */ static size_t AddFormDataf(struct FormData **formp, - const char *fmt, ...) + const char *fmt, ...) { char s[4096]; va_list ap; @@ -1027,7 +1037,10 @@ static size_t AddFormDataf(struct FormData **formp, return AddFormData(formp, s, 0); } - +/* + * Curl_FormBoundary() creates a suitable boundary string and returns an + * allocated one. + */ char *Curl_FormBoundary(void) { char *retstring; @@ -1056,7 +1069,10 @@ char *Curl_FormBoundary(void) return retstring; } -/* Used from http.c, this cleans a built FormData linked list */ +/* + * Curl_formclean() is used from http.c, this cleans a built FormData linked + * list + */ void Curl_formclean(struct FormData *form) { struct FormData *next; @@ -1069,7 +1085,10 @@ void Curl_formclean(struct FormData *form) } while((form=next)); /* continue */ } -/* external function to free up a whole form post chain */ +/* + * curl_formfree() is an external function to free up a whole form post + * chain + */ void curl_formfree(struct curl_httppost *form) { struct curl_httppost *next; @@ -1098,6 +1117,13 @@ void curl_formfree(struct curl_httppost *form) } while((form=next)); /* continue */ } +/* + * Curl_getFormData() converts a linked list of "meta data" into a complete + * (possibly huge) multipart formdata. The input list is in 'post', while the + * output resulting linked lists gets stored in '*finalform'. *sizep will get + * the total size of the whole POST. + */ + CURLcode Curl_getFormData(struct FormData **finalform, struct curl_httppost *post, curl_off_t *sizep) @@ -1278,6 +1304,10 @@ CURLcode Curl_getFormData(struct FormData **finalform, return result; } +/* + * Curl_FormInit() inits the struct 'form' points to with the 'formdata' + * and resets the 'sent' counter. + */ int Curl_FormInit(struct Form *form, struct FormData *formdata ) { if(!formdata) @@ -1289,7 +1319,10 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata ) return 0; } -/* fread() emulation */ +/* + * Curl_FormReader() is the fread() emulation function that will be used to + * deliver the formdata to the transfer loop and then sent away to the peer. + */ size_t Curl_FormReader(char *buffer, size_t size, size_t nitems, @@ -1335,48 +1368,25 @@ size_t Curl_FormReader(char *buffer, return gotsize; } -/* possible (old) fread() emulation that copies at most one line */ -size_t Curl_FormReadOneLine(char *buffer, - size_t size, - size_t nitems, - FILE *mydata) +/* + * Curl_formpostheader() returns the first line of the formpost, the + * request-header part (which is not part of the request-body like the rest of + * the post). + */ +char *Curl_formpostheader(void *formp, size_t *len) { - struct Form *form; - size_t wantedsize; - size_t gotsize; - - form=(struct Form *)mydata; - - wantedsize = size * nitems; + char *header; + struct Form *form=(struct Form *)formp; if(!form->data) - return 0; /* nothing, error, empty */ - - do { - - if( (form->data->length - form->sent ) > wantedsize ) { - - memcpy(buffer, form->data->line + form->sent, wantedsize); - - form->sent += wantedsize; + return 0; /* nothing, ERROR! */ - return wantedsize; - } - - memcpy(buffer, - form->data->line + form->sent, - gotsize = (form->data->length - form->sent) ); - - form->sent = 0; + header = form->data->line; + *len = form->data->length; - form->data = form->data->next; /* advance */ - - } while(!gotsize && form->data); - /* If we got an empty line and we have more data, we proceed to the next - line immediately to avoid returning zero before we've reached the end. - This is the bug reported November 22 1999 on curl 6.3. (Daniel) */ + form->data = form->data->next; /* advance */ - return gotsize; + return header; } -- cgit v1.2.1 From 2a0a3053006632786b73f2e8ae6239e119b8ede9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 23 Apr 2004 11:00:47 +0000 Subject: only a minor comment/format change --- lib/formdata.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 57ad283af..3e3318446 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1244,11 +1244,14 @@ CURLcode Curl_getFormData(struct FormData **finalform, char buffer[1024]; size_t nread; - fileread = strequal("-", file->contents)?stdin: - /* binary read for win32 crap */ - /*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */ - /*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */ - /*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */ + fileread = strequal("-", file->contents)? + stdin:fopen(file->contents, "rb"); /* binary read for win32 */ + /* + * VMS: This only allows for stream files on VMS. Stream files are + * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC, + * every record needs to have a \n appended & 1 added to SIZE + */ + if(fileread) { while((nread = fread(buffer, 1, 1024, fileread))) size += AddFormData(&form, buffer, nread); @@ -1257,10 +1260,6 @@ CURLcode Curl_getFormData(struct FormData **finalform, fclose(fileread); } else { -#if 0 - /* File wasn't found, add a nothing field! */ - size += AddFormData(&form, "", 0); -#endif Curl_formclean(firstform); free(boundary); *finalform = NULL; -- cgit v1.2.1 From 2960d37d7172976dff3eb8953fb4ca5f17b4bc47 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 4 May 2004 08:24:13 +0000 Subject: removed curl_formparse() from the library --- lib/formdata.c | 227 --------------------------------------------------------- 1 file changed, 227 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 3e3318446..967b1166d 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -97,14 +97,6 @@ Content-Type: text/plain Content-Disposition: form-data; name="FILECONTENT" ... - For the old FormParse used by curl_formparse use: - - gcc -DHAVE_CONFIG_H -I../ -g -D_OLD_FORM_DEBUG -o formdata -I../include formdata.c strequal.c - - run the 'formdata' executable and make sure the output is ok! - - try './formdata "name=Daniel" "poo=noo" "foo=bar"' and similarly - */ #include "setup.h" @@ -118,9 +110,6 @@ Content-Disposition: form-data; name="FILECONTENT" #include -#ifndef CURL_OLDSTYLE -#define CURL_OLDSTYLE 1 /* enable deprecated prototype for curl_formparse */ -#endif #include #include "formdata.h" @@ -171,222 +160,6 @@ static void GetStr(char **string, #define FORM_FILE_SEPARATOR ',' #define FORM_TYPE_SEPARATOR ';' -static -int FormParse(char *input, - struct curl_httppost **httppost, - struct curl_httppost **last_post) -{ - /* 'input' MUST be a string in the format 'name=contents' and we'll - build a linked list with the info */ - char name[256]; - char *contents; - char major[128]; - char minor[128]; - long flags = 0; - char *contp; - const char *type = NULL; - char *prevtype = NULL; - char *sep; - char *sep2; - struct curl_httppost *post; - struct curl_httppost *subpost; /* a sub-node */ - unsigned int i; - - /* Preallocate contents to the length of input to make sure we don't - overwrite anything. */ - contents = malloc(strlen(input)); - contents[0] = '\000'; - - if(1 <= sscanf(input, "%255[^=]=%[^\n]", name, contents)) { - /* the input was using the correct format */ - contp = contents; - - if('@' == contp[0]) { - /* we use the @-letter to indicate file name(s) */ - - flags = HTTPPOST_FILENAME; - contp++; - - post=NULL; - - do { - /* since this was a file, it may have a content-type specifier - at the end too */ - - sep=strchr(contp, FORM_TYPE_SEPARATOR); - sep2=strchr(contp, FORM_FILE_SEPARATOR); - - /* pick the closest */ - if(sep2 && (sep2 < sep)) { - sep = sep2; - - /* no type was specified! */ - } - if(sep) { - - /* if we got here on a comma, don't do much */ - if(FORM_FILE_SEPARATOR != *sep) - type = strstr(sep+1, "type="); - else - type=NULL; - - *sep=0; /* terminate file name at separator */ - - if(type) { - type += strlen("type="); - - if(2 != sscanf(type, "%127[^/]/%127[^,\n]", - major, minor)) { - free(contents); - return 2; /* illegal content-type syntax! */ - } - /* now point beyond the content-type specifier */ - sep = (char *)type + strlen(major)+strlen(minor)+1; - - /* find the following comma */ - sep=strchr(sep, FORM_FILE_SEPARATOR); - } - } - else { - type=NULL; - sep=strchr(contp, FORM_FILE_SEPARATOR); - } - if(sep) { - /* the next file name starts here */ - *sep =0; - sep++; - } - if(!type) { - /* - * No type was specified, we scan through a few well-known - * extensions and pick the first we match! - */ - struct ContentType { - const char *extension; - const char *type; - }; - static struct ContentType ctts[]={ - {".gif", "image/gif"}, - {".jpg", "image/jpeg"}, - {".jpeg", "image/jpeg"}, - {".txt", "text/plain"}, - {".html", "text/html"} - }; - - if(prevtype) - /* default to the previously set/used! */ - type = prevtype; - else - /* It seems RFC1867 defines no Content-Type to default to - text/plain so we don't actually need to set this: */ - type = HTTPPOST_CONTENTTYPE_DEFAULT; - - for(i=0; i= strlen(ctts[i].extension)) { - if(strequal(contp + - strlen(contp) - strlen(ctts[i].extension), - ctts[i].extension)) { - type = ctts[i].type; - break; - } - } - } - /* we have a type by now */ - } - - if(NULL == post) { - /* For the first file name, we allocate and initiate the main list - node */ - - post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost)); - if(post) { - memset(post, 0, sizeof(struct curl_httppost)); - GetStr(&post->name, name); /* get the name */ - GetStr(&post->contents, contp); /* get the contents */ - post->contentslength = 0; - post->flags = flags; - if(type) { - GetStr(&post->contenttype, (char *)type); /* get type */ - prevtype=post->contenttype; /* point to the allocated string! */ - } - /* make the previous point to this */ - if(*last_post) - (*last_post)->next = post; - else - (*httppost) = post; - - (*last_post) = post; - } - - } - else { - /* we add a file name to the previously allocated node, known as - 'post' now */ - subpost =(struct curl_httppost *) - malloc(sizeof(struct curl_httppost)); - if(subpost) { - memset(subpost, 0, sizeof(struct curl_httppost)); - GetStr(&subpost->name, name); /* get the name */ - GetStr(&subpost->contents, contp); /* get the contents */ - subpost->contentslength = 0; - subpost->flags = flags; - if(type) { - GetStr(&subpost->contenttype, (char *)type); /* get type */ - prevtype=subpost->contenttype; /* point to allocated string! */ - } - /* now, point our 'more' to the original 'more' */ - subpost->more = post->more; - - /* then move the original 'more' to point to ourselves */ - post->more = subpost; - } - } - contp = sep; /* move the contents pointer to after the separator */ - } while(sep && *sep); /* loop if there's another file name */ - } - else { - post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost)); - if(post) { - memset(post, 0, sizeof(struct curl_httppost)); - GetStr(&post->name, name); /* get the name */ - if( contp[0]=='<' ) { - GetStr(&post->contents, contp+1); /* get the contents */ - post->contentslength = 0; - post->flags = HTTPPOST_READFILE; - } - else { - GetStr(&post->contents, contp); /* get the contents */ - post->contentslength = 0; - post->flags = 0; - } - - /* make the previous point to this */ - if(*last_post) - (*last_post)->next = post; - else - (*httppost) = post; - - (*last_post) = post; - } - - } - - } - else { - free(contents); - return 1; - } - free(contents); - return 0; -} - -int curl_formparse(char *input, - struct curl_httppost **httppost, - struct curl_httppost **last_post) -{ - return FormParse(input, httppost, last_post); -} - /*************************************************************************** * * AddHttpPost() -- cgit v1.2.1 From 9e31a0536e7d0d5abe78673a6d384d2f7fc87bd5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 4 May 2004 09:31:04 +0000 Subject: removed more leftovers from the formparse function --- lib/formdata.c | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 967b1166d..7ad8a1fa3 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -127,36 +127,6 @@ Content-Disposition: form-data; name="FILECONTENT" extensions. */ #define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream" -/* This is a silly duplicate of the function in main.c to enable this source - to compile stand-alone for better debugging */ -static void GetStr(char **string, - const char *value) -{ - if(*string) - free(*string); - *string = strdup(value); -} - -/*************************************************************************** - * - * FormParse() - * - * Reads a 'name=value' paramter and builds the appropriate linked list. - * - * Specify files to upload with 'name=@filename'. Supports specified - * given Content-Type of the files. Such as ';type='. - * - * You may specify more than one file for a single name (field). Specify - * multiple files by writing it like: - * - * 'name=@filename,filename2,filename3' - * - * If you want content-types specified for each too, write them like: - * - * 'name=@filename;type=image/gif,filename2,filename3' - * - ***************************************************************************/ - #define FORM_FILE_SEPARATOR ',' #define FORM_TYPE_SEPARATOR ';' @@ -348,8 +318,7 @@ static int AllocAndCopy(char **buffer, size_t buffer_length) * * FormAdd() * - * Stores a 'name=value' formpost parameter and builds the appropriate - * linked list. + * Stores a formpost parameter and builds the appropriate linked list. * * Has two principal functionalities: using files and byte arrays as * post parts. Byte arrays are either copied or just the pointer is stored -- cgit v1.2.1 From d67ea8c7ad76380c9c757072d402f62513985a05 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 7 May 2004 09:50:49 +0000 Subject: count the formdata size using a 64bit size if avaialble --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 7ad8a1fa3..160f51fbd 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -875,7 +875,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, struct curl_httppost *file; CURLcode result = CURLE_OK; - size_t size =0; + curl_off_t size =0; char *boundary; char *fileboundary=NULL; struct curl_slist* curList; -- cgit v1.2.1 From e55dee3807f8f7b41d9fe91c83e3cfe7cda07ecd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 10 May 2004 07:11:52 +0000 Subject: James Bursa added better error checking for failer memory calls when building formposts --- lib/formdata.c | 129 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 27 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 160f51fbd..5d258a965 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -735,13 +735,18 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost, /* * AddFormData() adds a chunk of data to the FormData linked list. + * + * size is incremented by the chunk length, unless it is NULL */ -static size_t AddFormData(struct FormData **formp, - const void *line, - size_t length) +static CURLcode AddFormData(struct FormData **formp, + const void *line, + size_t length, + size_t *size) { struct FormData *newform = (struct FormData *) malloc(sizeof(struct FormData)); + if (!newform) + return CURLE_OUT_OF_MEMORY; newform->next = NULL; /* we make it easier for plain strings: */ @@ -749,6 +754,10 @@ static size_t AddFormData(struct FormData **formp, length = strlen((char *)line); newform->line = (char *)malloc(length+1); + if (!newform->line) { + free(newform); + return CURLE_OUT_OF_MEMORY; + } memcpy(newform->line, line, length); newform->length = length; newform->line[length]=0; /* zero terminate for easier debugging */ @@ -760,14 +769,17 @@ static size_t AddFormData(struct FormData **formp, else *formp = newform; - return length; + if (size) + *size += length; + return CURLE_OK; } /* * AddFormDataf() adds printf()-style formatted data to the formdata chain. */ -static size_t AddFormDataf(struct FormData **formp, +static CURLcode AddFormDataf(struct FormData **formp, + size_t *size, const char *fmt, ...) { char s[4096]; @@ -776,7 +788,7 @@ static size_t AddFormDataf(struct FormData **formp, vsprintf(s, fmt, ap); va_end(ap); - return AddFormData(formp, s, 0); + return AddFormData(formp, s, 0, size); } /* @@ -875,7 +887,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, struct curl_httppost *file; CURLcode result = CURLE_OK; - curl_off_t size =0; + size_t size =0; char *boundary; char *fileboundary=NULL; struct curl_slist* curList; @@ -888,28 +900,43 @@ CURLcode Curl_getFormData(struct FormData **finalform, boundary = Curl_FormBoundary(); /* Make the first line of the output */ - AddFormDataf(&form, + result = AddFormDataf(&form, 0, "Content-Type: multipart/form-data;" " boundary=%s\r\n", boundary); + if (result != CURLE_OK) { + free(boundary); + return result; + } /* we DO NOT count that line since that'll be part of the header! */ firstform = form; do { - if(size) - size += AddFormDataf(&form, "\r\n"); + if(size) { + result = AddFormDataf(&form, &size, "\r\n"); + if (result != CURLE_OK) + break; + } /* boundary */ - size += AddFormDataf(&form, "--%s\r\n", boundary); + result = AddFormDataf(&form, &size, "--%s\r\n", boundary); + if (result != CURLE_OK) + break; - size += AddFormData(&form, - "Content-Disposition: form-data; name=\"", 0); + result = AddFormData(&form, + "Content-Disposition: form-data; name=\"", 0, &size); + if (result != CURLE_OK) + break; - size += AddFormData(&form, post->name, post->namelength); + result = AddFormData(&form, post->name, post->namelength, &size); + if (result != CURLE_OK) + break; - size += AddFormData(&form, "\"", 0); + size += AddFormData(&form, "\"", 0, &size); + if (result != CURLE_OK) + break; if(post->more) { /* If used, this is a link to more file names, we must then do @@ -917,10 +944,12 @@ CURLcode Curl_getFormData(struct FormData **finalform, fileboundary = Curl_FormBoundary(); - size += AddFormDataf(&form, + result = AddFormDataf(&form, &size, "\r\nContent-Type: multipart/mixed," " boundary=%s\r\n", fileboundary); + if (result != CURLE_OK) + break; } file = post; @@ -933,35 +962,48 @@ CURLcode Curl_getFormData(struct FormData **finalform, if(post->more) { /* if multiple-file */ - size += AddFormDataf(&form, + result = AddFormDataf(&form, &size, "\r\n--%s\r\nContent-Disposition: " "attachment; filename=\"%s\"", fileboundary, (file->showfilename?file->showfilename: file->contents)); + if (result != CURLE_OK) + break; } else if((post->flags & HTTPPOST_FILENAME) || (post->flags & HTTPPOST_BUFFER)) { - size += AddFormDataf(&form, + result = AddFormDataf(&form, &size, "; filename=\"%s\"", (post->showfilename?post->showfilename: post->contents)); + if (result != CURLE_OK) + break; } if(file->contenttype) { /* we have a specified type */ - size += AddFormDataf(&form, + result = AddFormDataf(&form, &size, "\r\nContent-Type: %s", file->contenttype); + if (result != CURLE_OK) + break; } curList = file->contentheader; while( curList ) { /* Process the additional headers specified for this form */ - size += AddFormDataf( &form, "\r\n%s", curList->data ); + result = AddFormDataf( &form, &size, "\r\n%s", curList->data ); + if (result != CURLE_OK) + break; curList = curList->next; } + if (result != CURLE_OK) { + Curl_formclean(firstform); + free(boundary); + return result; + } #if 0 /* The header Content-Transfer-Encoding: seems to confuse some receivers @@ -977,7 +1019,9 @@ CURLcode Curl_getFormData(struct FormData **finalform, } #endif - size += AddFormData(&form, "\r\n\r\n", 0); + result = AddFormData(&form, "\r\n\r\n", 0, &size); + if (result != CURLE_OK) + break; if((post->flags & HTTPPOST_FILENAME) || (post->flags & HTTPPOST_READFILE)) { @@ -995,8 +1039,16 @@ CURLcode Curl_getFormData(struct FormData **finalform, */ if(fileread) { - while((nread = fread(buffer, 1, 1024, fileread))) - size += AddFormData(&form, buffer, nread); + while((nread = fread(buffer, 1, 1024, fileread))) { + result = AddFormData(&form, buffer, nread, &size); + if (result != CURLE_OK) + break; + } + if (result != CURLE_OK) { + Curl_formclean(firstform); + free(boundary); + return result; + } if(fileread != stdin) fclose(fileread); @@ -1011,30 +1063,53 @@ CURLcode Curl_getFormData(struct FormData **finalform, } else if (post->flags & HTTPPOST_BUFFER) { /* include contents of buffer */ - size += AddFormData(&form, post->buffer, post->bufferlength); + result = AddFormData(&form, post->buffer, post->bufferlength, + &size); + if (result != CURLE_OK) + break; } else { /* include the contents we got */ - size += AddFormData(&form, post->contents, post->contentslength); + result = AddFormData(&form, post->contents, post->contentslength, + &size); + if (result != CURLE_OK) + break; } } while((file = file->more)); /* for each specified file for this field */ + if (result != CURLE_OK) { + Curl_formclean(firstform); + free(boundary); + return result; + } if(post->more) { /* this was a multiple-file inclusion, make a termination file boundary: */ - size += AddFormDataf(&form, + result = AddFormDataf(&form, &size, "\r\n--%s--", fileboundary); free(fileboundary); + if (result != CURLE_OK) + break; } } while((post=post->next)); /* for each field */ + if (result != CURLE_OK) { + Curl_formclean(firstform); + free(boundary); + return result; + } /* end-boundary for everything */ - size += AddFormDataf(&form, + result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary); + if (result != CURLE_OK) { + Curl_formclean(firstform); + free(boundary); + return result; + } *sizep = size; -- cgit v1.2.1 From 5c592f7dd9164066be173fd01128abddac74f346 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 May 2004 11:29:02 +0000 Subject: Make this source code use our internal *printf(). Also some minor edits. --- lib/formdata.c | 100 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 5d258a965..8a20dc18f 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -107,18 +107,17 @@ Content-Disposition: form-data; name="FILECONTENT" #include #include #include - #include - #include #include "formdata.h" - #include "strequal.h" +#include "memory.h" + +#define _MPRINTF_REPLACE /* use our functions only */ +#include /* The last #include file should be: */ -#ifdef CURLDEBUG #include "memdebug.h" -#endif /* Length of the random boundary string. */ #define BOUNDARY_LENGTH 40 @@ -779,8 +778,8 @@ static CURLcode AddFormData(struct FormData **formp, */ static CURLcode AddFormDataf(struct FormData **formp, - size_t *size, - const char *fmt, ...) + size_t *size, + const char *fmt, ...) { char s[4096]; va_list ap; @@ -900,15 +899,16 @@ CURLcode Curl_getFormData(struct FormData **finalform, boundary = Curl_FormBoundary(); /* Make the first line of the output */ - result = AddFormDataf(&form, 0, - "Content-Type: multipart/form-data;" - " boundary=%s\r\n", - boundary); - if (result != CURLE_OK) { + result = AddFormDataf(&form, NULL, + "Content-Type: multipart/form-data;" + " boundary=%s\r\n", + boundary); + if (result) { free(boundary); return result; } - /* we DO NOT count that line since that'll be part of the header! */ + /* we DO NOT include that line in the total size of the POST, since it'll be + part of the header! */ firstform = form; @@ -916,26 +916,26 @@ CURLcode Curl_getFormData(struct FormData **finalform, if(size) { result = AddFormDataf(&form, &size, "\r\n"); - if (result != CURLE_OK) + if (result) break; } /* boundary */ result = AddFormDataf(&form, &size, "--%s\r\n", boundary); - if (result != CURLE_OK) + if (result) break; result = AddFormData(&form, - "Content-Disposition: form-data; name=\"", 0, &size); - if (result != CURLE_OK) + "Content-Disposition: form-data; name=\"", 0, &size); + if (result) break; result = AddFormData(&form, post->name, post->namelength, &size); - if (result != CURLE_OK) + if (result) break; size += AddFormData(&form, "\"", 0, &size); - if (result != CURLE_OK) + if (result) break; if(post->more) { @@ -945,10 +945,10 @@ CURLcode Curl_getFormData(struct FormData **finalform, fileboundary = Curl_FormBoundary(); result = AddFormDataf(&form, &size, - "\r\nContent-Type: multipart/mixed," - " boundary=%s\r\n", - fileboundary); - if (result != CURLE_OK) + "\r\nContent-Type: multipart/mixed," + " boundary=%s\r\n", + fileboundary); + if (result) break; } @@ -963,31 +963,31 @@ CURLcode Curl_getFormData(struct FormData **finalform, if(post->more) { /* if multiple-file */ result = AddFormDataf(&form, &size, - "\r\n--%s\r\nContent-Disposition: " - "attachment; filename=\"%s\"", - fileboundary, - (file->showfilename?file->showfilename: - file->contents)); - if (result != CURLE_OK) + "\r\n--%s\r\nContent-Disposition: " + "attachment; filename=\"%s\"", + fileboundary, + (file->showfilename?file->showfilename: + file->contents)); + if (result) break; } else if((post->flags & HTTPPOST_FILENAME) || (post->flags & HTTPPOST_BUFFER)) { result = AddFormDataf(&form, &size, - "; filename=\"%s\"", - (post->showfilename?post->showfilename: - post->contents)); - if (result != CURLE_OK) + "; filename=\"%s\"", + (post->showfilename?post->showfilename: + post->contents)); + if (result) break; } if(file->contenttype) { /* we have a specified type */ result = AddFormDataf(&form, &size, - "\r\nContent-Type: %s", - file->contenttype); - if (result != CURLE_OK) + "\r\nContent-Type: %s", + file->contenttype); + if (result) break; } @@ -995,11 +995,11 @@ CURLcode Curl_getFormData(struct FormData **finalform, while( curList ) { /* Process the additional headers specified for this form */ result = AddFormDataf( &form, &size, "\r\n%s", curList->data ); - if (result != CURLE_OK) + if (result) break; curList = curList->next; } - if (result != CURLE_OK) { + if (result) { Curl_formclean(firstform); free(boundary); return result; @@ -1020,7 +1020,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, #endif result = AddFormData(&form, "\r\n\r\n", 0, &size); - if (result != CURLE_OK) + if (result) break; if((post->flags & HTTPPOST_FILENAME) || @@ -1041,10 +1041,10 @@ CURLcode Curl_getFormData(struct FormData **finalform, if(fileread) { while((nread = fread(buffer, 1, 1024, fileread))) { result = AddFormData(&form, buffer, nread, &size); - if (result != CURLE_OK) + if (result) break; } - if (result != CURLE_OK) { + if (result) { Curl_formclean(firstform); free(boundary); return result; @@ -1062,10 +1062,10 @@ CURLcode Curl_getFormData(struct FormData **finalform, } else if (post->flags & HTTPPOST_BUFFER) { - /* include contents of buffer */ - result = AddFormData(&form, post->buffer, post->bufferlength, - &size); - if (result != CURLE_OK) + /* include contents of buffer */ + result = AddFormData(&form, post->buffer, post->bufferlength, + &size); + if (result) break; } @@ -1073,11 +1073,11 @@ CURLcode Curl_getFormData(struct FormData **finalform, /* include the contents we got */ result = AddFormData(&form, post->contents, post->contentslength, &size); - if (result != CURLE_OK) + if (result) break; } } while((file = file->more)); /* for each specified file for this field */ - if (result != CURLE_OK) { + if (result) { Curl_formclean(firstform); free(boundary); return result; @@ -1090,12 +1090,12 @@ CURLcode Curl_getFormData(struct FormData **finalform, "\r\n--%s--", fileboundary); free(fileboundary); - if (result != CURLE_OK) + if (result) break; } } while((post=post->next)); /* for each field */ - if (result != CURLE_OK) { + if (result) { Curl_formclean(firstform); free(boundary); return result; @@ -1105,7 +1105,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary); - if (result != CURLE_OK) { + if (result) { Curl_formclean(firstform); free(boundary); return result; -- cgit v1.2.1 From d3999e06d199a2538db69536bd9266666180ed68 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 May 2004 14:48:53 +0000 Subject: clear up memory on failure a little better --- lib/formdata.c | 74 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 32 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 8a20dc18f..ebf4d4e88 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -152,9 +152,8 @@ AddHttpPost(char * name, size_t namelength, struct curl_httppost **last_post) { struct curl_httppost *post; - post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost)); + post = (struct curl_httppost *)calloc(sizeof(struct curl_httppost), 1); if(post) { - memset(post, 0, sizeof(struct curl_httppost)); post->name = name; post->namelength = (long)(name?(namelength?namelength:strlen(name)):0); post->contents = value; @@ -283,34 +282,38 @@ static const char * ContentTypeForFilename (const char *filename, /*************************************************************************** * - * AllocAndCopy() + * memdup() * - * Copies the data currently available under *buffer using newly allocated - * buffer (that becomes *buffer). Uses buffer_length if not null, else - * uses strlen to determine the length of the buffer to be copied + * Copies the 'source' data to a newly allocated buffer buffer (that is + * returned). Uses buffer_length if not null, else uses strlen to determine + * the length of the buffer to be copied * - * Returns 0 on success and 1 if the malloc failed. + * Returns the new pointer or NULL on failure. * ***************************************************************************/ -static int AllocAndCopy(char **buffer, size_t buffer_length) +static char *memdup(const char *src, size_t buffer_length) { - const char *src = *buffer; size_t length; bool add = FALSE; + char *buffer; + if (buffer_length) length = buffer_length; else { - length = strlen(*buffer); + length = strlen(src); add = TRUE; } - *buffer = (char*)malloc(length+add); - if (!*buffer) - return 1; - memcpy(*buffer, src, length); + buffer = (char*)malloc(length+add); + if (!buffer) + return NULL; /* fail */ + + memcpy(buffer, src, length); + /* if length unknown do null termination */ if (add) - (*buffer)[length] = '\0'; - return 0; + buffer[length] = '\0'; + + return buffer; } /*************************************************************************** @@ -383,22 +386,16 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, /* * We need to allocate the first struct to fill in. */ - first_form = (FormInfo *)malloc(sizeof(struct FormInfo)); - if(first_form) { - memset(first_form, 0, sizeof(FormInfo)); - current_form = first_form; - } - else + first_form = (FormInfo *)calloc(sizeof(struct FormInfo), 1); + if(!first_form) return CURL_FORMADD_MEMORY; + current_form = first_form; + /* - * Loop through all the options set. + * Loop through all the options set. Break if we have an error to report. */ - while (1) { - - /* break if we have an error to report */ - if (return_value != CURL_FORMADD_OK) - break; + while (return_value == CURL_FORMADD_OK) { /* first see if we have more parts of the array param */ if ( array_state ) { @@ -670,21 +667,24 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if ( !(form->flags & HTTPPOST_PTRNAME) && (form == first_form) ) { /* copy name (without strdup; possibly contains null characters) */ - if (AllocAndCopy(&form->name, form->namelength)) { + form->name = memdup(form->name, form->namelength); + if (!form->name) { return_value = CURL_FORMADD_MEMORY; break; } + form->name_alloc = TRUE; } if ( !(form->flags & HTTPPOST_FILENAME) && !(form->flags & HTTPPOST_READFILE) && !(form->flags & HTTPPOST_PTRCONTENTS) && !(form->flags & HTTPPOST_PTRBUFFER) ) { - /* copy value (without strdup; possibly contains null characters) */ - if (AllocAndCopy(&form->value, form->contentslength)) { + form->value = memdup(form->value, form->contentslength); + if (!form->value) { return_value = CURL_FORMADD_MEMORY; break; } + form->value_alloc = TRUE; } post = AddHttpPost(form->name, form->namelength, form->value, form->contentslength, @@ -694,8 +694,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, post, httppost, last_post); - if(!post) + if(!post) { return_value = CURL_FORMADD_MEMORY; + break; + } if (form->contenttype) prevtype = form->contenttype; @@ -703,6 +705,14 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } } + if(return_value && form) { + /* we return on error, free possibly allocated fields */ + if(form->name_alloc) + free(form->name); + if(form->value_alloc) + free(form->value); + } + /* always delete the allocated memory before returning */ form = first_form; while (form != NULL) { -- cgit v1.2.1 From 939866faabe8b1827d990f68e15b9d12ceb7fb06 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 May 2004 06:27:40 +0000 Subject: Left-over from before the return-code fix. This is probably the code that causes xlc and gcc act differently on AIX. --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index ebf4d4e88..60971ffa4 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -944,7 +944,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, if (result) break; - size += AddFormData(&form, "\"", 0, &size); + result = AddFormData(&form, "\"", 0, &size); if (result) break; -- cgit v1.2.1 From 005042e973cb6e42b8bf76ae15a72f1482c43e6b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 May 2004 09:02:23 +0000 Subject: improved cleaning up in case of memory allocation failures --- lib/formdata.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 14 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 60971ffa4..80941655a 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -370,7 +370,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, struct curl_httppost **last_post, va_list params) { - FormInfo *first_form, *current_form, *form; + FormInfo *first_form, *current_form, *form = NULL; CURLFORMcode return_value = CURL_FORMADD_OK; const char *prevtype = NULL; struct curl_httppost *post = NULL; @@ -490,7 +490,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, array_value:va_arg(params, char *); if (filename) { current_form->value = strdup(filename); - current_form->flags |= HTTPPOST_READFILE; + if(!current_form->value) + return_value = CURL_FORMADD_MEMORY; + else + current_form->flags |= HTTPPOST_READFILE; } else return_value = CURL_FORMADD_NULL; @@ -517,11 +520,17 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_OPTION_TWICE; } else { - if (filename) + if (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 return_value = CURL_FORMADD_NULL; - current_form->flags |= HTTPPOST_FILENAME; } break; } @@ -545,8 +554,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_OPTION_TWICE; } else { - if (filename) + if (filename) { current_form->value = strdup(filename); + if(!current_form->value) + return_value = CURL_FORMADD_MEMORY; + } else return_value = CURL_FORMADD_NULL; current_form->flags |= HTTPPOST_BUFFER; @@ -595,8 +607,13 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_OPTION_TWICE; } else { - if (contenttype) + if (contenttype) { current_form->contenttype = strdup(contenttype); + if(!current_form->contenttype) + return_value = CURL_FORMADD_MEMORY; + else + current_form->contenttype_alloc = TRUE; + } else return_value = CURL_FORMADD_NULL; } @@ -623,8 +640,13 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, va_arg(params, char *); if( current_form->showfilename ) return_value = CURL_FORMADD_OPTION_TWICE; - else + else { current_form->showfilename = strdup(filename); + if(!current_form->showfilename) + return_value = CURL_FORMADD_MEMORY; + else + current_form->showfilename_alloc = TRUE; + } break; } default: @@ -663,6 +685,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, /* our contenttype is missing */ form->contenttype = strdup(ContentTypeForFilename(form->value, prevtype)); + if(!form->contenttype) { + return_value = CURL_FORMADD_MEMORY; + break; + } + form->contenttype_alloc = TRUE; } if ( !(form->flags & HTTPPOST_PTRNAME) && (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 */ - if(form->name_alloc) - free(form->name); - if(form->value_alloc) - free(form->value); + if(!form) + form = current_form; + if(form) { + if(form->name_alloc) + free(form->name); + if(form->value_alloc) + free(form->value); + if(form->contenttype_alloc) + free(form->contenttype); + if(form->showfilename_alloc) + free(form->showfilename); + } } /* always delete the allocated memory before returning */ @@ -840,6 +875,9 @@ void Curl_formclean(struct FormData *form) { struct FormData *next; + if(!form) + return; + do { next=form->next; /* the following form line */ free(form->line); /* free the line */ @@ -907,6 +945,8 @@ CURLcode Curl_getFormData(struct FormData **finalform, return result; /* no input => no output! */ boundary = Curl_FormBoundary(); + if(!boundary) + return CURLE_OUT_OF_MEMORY; /* Make the first line of the output */ result = AddFormDataf(&form, NULL, @@ -1054,14 +1094,14 @@ CURLcode Curl_getFormData(struct FormData **finalform, if (result) break; } + if(fileread != stdin) + fclose(fileread); if (result) { Curl_formclean(firstform); free(boundary); return result; } - if(fileread != stdin) - fclose(fileread); } else { Curl_formclean(firstform); -- cgit v1.2.1 From ccdcdb2a461839c9fd7f3306e24bd4a7a818a892 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 13 May 2004 14:13:12 +0000 Subject: mark a value as alloced when strdup()ed to prevent memory leaks --- lib/formdata.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 80941655a..671697aca 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -492,8 +492,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, current_form->value = strdup(filename); if(!current_form->value) return_value = CURL_FORMADD_MEMORY; - else + else { current_form->flags |= HTTPPOST_READFILE; + current_form->value_alloc = TRUE; + } } else return_value = CURL_FORMADD_NULL; -- cgit v1.2.1 From af33c6b5498f56a1434d1568b5721b402710369b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 3 Jun 2004 13:03:57 +0000 Subject: deleted trailing whitespace --- lib/formdata.c | 80 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 671697aca..49d09786e 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1,8 +1,8 @@ /*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. @@ -10,7 +10,7 @@ * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://curl.haxx.se/docs/copyright.html. - * + * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. @@ -132,7 +132,7 @@ Content-Disposition: form-data; name="FILECONTENT" /*************************************************************************** * * AddHttpPost() - * + * * Adds a HttpPost structure to the list, if parent_post is given becomes * a subpost of parent_post instead of a direct list element. * @@ -167,13 +167,13 @@ AddHttpPost(char * name, size_t namelength, } else return NULL; - + if (parent_post) { /* now, point our 'more' to the original 'more' */ post->more = parent_post->more; - + /* then move the original 'more' to point to ourselves */ - parent_post->more = post; + parent_post->more = post; } else { /* make the previous point to this */ @@ -181,8 +181,8 @@ AddHttpPost(char * name, size_t namelength, (*last_post)->next = post; else (*httppost) = post; - - (*last_post) = post; + + (*last_post) = post; } return post; } @@ -190,7 +190,7 @@ AddHttpPost(char * name, size_t namelength, /*************************************************************************** * * AddFormInfo() - * + * * Adds a FormInfo structure to the list presented by parent_form_info. * * Returns newly allocated FormInfo on success and NULL if malloc failed/ @@ -213,11 +213,11 @@ static FormInfo * AddFormInfo(char *value, } else return NULL; - + if (parent_form_info) { /* now, point our 'more' to the original 'more' */ form_info->more = parent_form_info->more; - + /* then move the original 'more' to point to ourselves */ parent_form_info->more = form_info; } @@ -230,7 +230,7 @@ static FormInfo * AddFormInfo(char *value, /*************************************************************************** * * ContentTypeForFilename() - * + * * Provides content type for filename if one of the known types (else * (either the prevtype or the default is returned). * @@ -257,7 +257,7 @@ static const char * ContentTypeForFilename (const char *filename, {".txt", "text/plain"}, {".html", "text/html"} }; - + if(prevtype) /* default to the previously set/used! */ contenttype = prevtype; @@ -265,7 +265,7 @@ static const char * ContentTypeForFilename (const char *filename, /* It seems RFC1867 defines no Content-Type to default to text/plain so we don't actually need to set this: */ contenttype = HTTPPOST_CONTENTTYPE_DEFAULT; - + for(i=0; i= strlen(ctts[i].extension)) { if(strequal(filename + @@ -273,7 +273,7 @@ static const char * ContentTypeForFilename (const char *filename, ctts[i].extension)) { contenttype = ctts[i].type; break; - } + } } } /* we have a contenttype by now */ @@ -283,7 +283,7 @@ static const char * ContentTypeForFilename (const char *filename, /*************************************************************************** * * memdup() - * + * * Copies the 'source' data to a newly allocated buffer buffer (that is * returned). Uses buffer_length if not null, else uses strlen to determine * the length of the buffer to be copied @@ -296,7 +296,7 @@ static char *memdup(const char *src, size_t buffer_length) size_t length; bool add = FALSE; char *buffer; - + if (buffer_length) length = buffer_length; else { @@ -306,7 +306,7 @@ static char *memdup(const char *src, size_t buffer_length) buffer = (char*)malloc(length+add); if (!buffer) return NULL; /* fail */ - + memcpy(buffer, src, length); /* if length unknown do null termination */ @@ -319,7 +319,7 @@ static char *memdup(const char *src, size_t buffer_length) /*************************************************************************** * * FormAdd() - * + * * Stores a formpost parameter and builds the appropriate linked list. * * Has two principal functionalities: using files and byte arrays as @@ -567,7 +567,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } break; } - + case CURLFORM_BUFFERPTR: current_form->flags |= HTTPPOST_PTRBUFFER; if (current_form->buffer) @@ -628,12 +628,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, struct curl_slist* list = array_state? (struct curl_slist*)array_value: va_arg(params, struct curl_slist*); - + if( current_form->contentheader ) return_value = CURL_FORMADD_OPTION_TWICE; else current_form->contentheader = list; - + break; } case CURLFORM_FILENAME: @@ -659,7 +659,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if(CURL_FORMADD_OK == return_value) { /* go through the list, check for copleteness and if everything is * alright add the HttpPost item otherwise set return_value accordingly */ - + post = NULL; for(form = first_form; form != NULL; @@ -704,7 +704,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, form->name_alloc = TRUE; } if ( !(form->flags & HTTPPOST_FILENAME) && - !(form->flags & HTTPPOST_READFILE) && + !(form->flags & HTTPPOST_READFILE) && !(form->flags & HTTPPOST_PTRCONTENTS) && !(form->flags & HTTPPOST_PTRBUFFER) ) { /* copy value (without strdup; possibly contains null characters) */ @@ -722,7 +722,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, form->contentheader, form->showfilename, post, httppost, last_post); - + if(!post) { return_value = CURL_FORMADD_MEMORY; break; @@ -754,7 +754,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, form = first_form; while (form != NULL) { FormInfo *delete_form; - + delete_form = form; form = form->more; free (delete_form); @@ -807,7 +807,7 @@ static CURLcode AddFormData(struct FormData **formp, memcpy(newform->line, line, length); newform->length = length; newform->line[length]=0; /* zero terminate for easier debugging */ - + if(*formp) { (*formp)->next = newform; *formp = newform; @@ -872,7 +872,7 @@ char *Curl_FormBoundary(void) /* * Curl_formclean() is used from http.c, this cleans a built FormData linked * list - */ + */ void Curl_formclean(struct FormData *form) { struct FormData *next; @@ -884,7 +884,7 @@ void Curl_formclean(struct FormData *form) next=form->next; /* the following form line */ free(form->line); /* free the line */ free(form); /* free the struct */ - + } while((form=next)); /* continue */ } @@ -949,7 +949,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, boundary = Curl_FormBoundary(); if(!boundary) return CURLE_OUT_OF_MEMORY; - + /* Make the first line of the output */ result = AddFormDataf(&form, NULL, "Content-Type: multipart/form-data;" @@ -963,7 +963,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, part of the header! */ firstform = form; - + do { if(size) { @@ -1033,7 +1033,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, if (result) break; } - + if(file->contenttype) { /* we have a specified type */ result = AddFormDataf(&form, &size, @@ -1063,7 +1063,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, * should, I can just as well skip this to the benefit of the users who * are using such confused receivers. */ - + if(file->contenttype && !checkprefix("text/", file->contenttype)) { /* this is not a text content, mention our binary encoding */ @@ -1112,7 +1112,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, return CURLE_READ_ERROR; } - } + } else if (post->flags & HTTPPOST_BUFFER) { /* include contents of buffer */ result = AddFormData(&form, post->buffer, post->bufferlength, @@ -1140,7 +1140,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, boundary: */ result = AddFormDataf(&form, &size, "\r\n--%s--", - fileboundary); + fileboundary); free(fileboundary); if (result) break; @@ -1208,7 +1208,7 @@ size_t Curl_FormReader(char *buffer, return 0; /* nothing, error, empty */ do { - + if( (form->data->length - form->sent ) > wantedsize - gotsize) { memcpy(buffer + gotsize , form->data->line + form->sent, @@ -1223,7 +1223,7 @@ size_t Curl_FormReader(char *buffer, form->data->line + form->sent, (form->data->length - form->sent) ); gotsize += form->data->length - form->sent; - + form->sent = 0; form->data = form->data->next; /* advance */ -- cgit v1.2.1 From 6ec145d4b451d51310f887ef01bb40b48004d131 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 9 Jun 2004 08:22:02 +0000 Subject: when built with HTTP disabled, provide a curl_formadd() function anyway to keep the API complete at all times --- lib/formdata.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 49d09786e..36eac7e17 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1458,4 +1458,14 @@ int main(int argc, char **argv) #endif -#endif /* CURL_DISABLE_HTTP */ +#else /* CURL_DISABLE_HTTP */ +CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...) +{ + (void)httppost; + (void)last_post; + return CURL_FORMADD_DISABLED; +} + +#endif /* CURL_DISABLE_HTTP */ -- cgit v1.2.1 From 20988715093810cde488cabe2b9f52fe5b300450 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 10 Jun 2004 07:46:24 +0000 Subject: build again with disabled http --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 36eac7e17..28837bc73 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -100,6 +100,7 @@ Content-Disposition: form-data; name="FILECONTENT" */ #include "setup.h" +#include #ifndef CURL_DISABLE_HTTP @@ -108,7 +109,6 @@ Content-Disposition: form-data; name="FILECONTENT" #include #include #include -#include #include "formdata.h" #include "strequal.h" #include "memory.h" -- cgit v1.2.1 From 8f1783b8a786a43d105b26fcac288fb3c3a45183 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 13 Jun 2004 08:59:37 +0000 Subject: provide curl_formfree() even when http is disabled, it does nothing then --- lib/formdata.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 28837bc73..8fb6d9cdd 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1468,4 +1468,10 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost, return CURL_FORMADD_DISABLED; } +void curl_formfree(struct curl_httppost *form) +{ + (void)form; + /* does nothing HTTP is disabled */ +} + #endif /* CURL_DISABLE_HTTP */ -- cgit v1.2.1 From 24572dacccd331bcdfe5baca20c56d85d5d77359 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 14 Jun 2004 08:51:43 +0000 Subject: Allow formposting of files larger than what fits in memory by not reading the file until it is actually being uploaded. Make sure we build and still work with HTTP disabled - the SSL code might use the boundary string for some random seeding. --- lib/formdata.c | 173 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 114 insertions(+), 59 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 8fb6d9cdd..ea5c4acd8 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -102,6 +102,9 @@ Content-Disposition: form-data; name="FILECONTENT" #include "setup.h" #include +/* Length of the random boundary string. */ +#define BOUNDARY_LENGTH 40 + #ifndef CURL_DISABLE_HTTP #include @@ -109,6 +112,7 @@ Content-Disposition: form-data; name="FILECONTENT" #include #include #include +#include #include "formdata.h" #include "strequal.h" #include "memory.h" @@ -119,9 +123,6 @@ Content-Disposition: form-data; name="FILECONTENT" /* The last #include file should be: */ #include "memdebug.h" -/* Length of the random boundary string. */ -#define BOUNDARY_LENGTH 40 - /* What kind of Content-Type to use on un-specified files with unrecognized extensions. */ #define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream" @@ -785,9 +786,10 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost, * size is incremented by the chunk length, unless it is NULL */ static CURLcode AddFormData(struct FormData **formp, + enum formtype type, const void *line, size_t length, - size_t *size) + curl_off_t *size) { struct FormData *newform = (struct FormData *) malloc(sizeof(struct FormData)); @@ -807,6 +809,7 @@ static CURLcode AddFormData(struct FormData **formp, memcpy(newform->line, line, length); newform->length = length; newform->line[length]=0; /* zero terminate for easier debugging */ + newform->type = type; if(*formp) { (*formp)->next = newform; @@ -815,8 +818,20 @@ static CURLcode AddFormData(struct FormData **formp, else *formp = newform; - if (size) - *size += length; + if (size) { + if(type == FORM_DATA) + *size += length; + else { + /* Since this is a file to be uploaded here, add the size of the actual + file */ + if(!strequal("-", newform->line)) { + struct stat file; + if(!stat(newform->line, &file)) { + *size += file.st_size; + } + } + } + } return CURLE_OK; } @@ -825,7 +840,7 @@ static CURLcode AddFormData(struct FormData **formp, */ static CURLcode AddFormDataf(struct FormData **formp, - size_t *size, + curl_off_t *size, const char *fmt, ...) { char s[4096]; @@ -834,39 +849,7 @@ static CURLcode AddFormDataf(struct FormData **formp, vsprintf(s, fmt, ap); va_end(ap); - return AddFormData(formp, s, 0, size); -} - -/* - * Curl_FormBoundary() creates a suitable boundary string and returns an - * allocated one. - */ -char *Curl_FormBoundary(void) -{ - char *retstring; - static int randomizer=0; /* this is just so that two boundaries within - the same form won't be identical */ - size_t i; - - static char table16[]="abcdef0123456789"; - - retstring = (char *)malloc(BOUNDARY_LENGTH+1); - - if(!retstring) - return NULL; /* failed */ - - srand(time(NULL)+randomizer++); /* seed */ - - strcpy(retstring, "----------------------------"); - - for(i=strlen(retstring); iname, post->namelength, &size); + result = AddFormData(&form, FORM_DATA, post->name, post->namelength, + &size); if (result) break; - result = AddFormData(&form, "\"", 0, &size); + result = AddFormDataf(&form, &size, "\""); if (result) break; @@ -1071,7 +1055,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, } #endif - result = AddFormData(&form, "\r\n\r\n", 0, &size); + result = AddFormDataf(&form, &size, "\r\n\r\n"); if (result) break; @@ -1079,11 +1063,10 @@ CURLcode Curl_getFormData(struct FormData **finalform, (post->flags & HTTPPOST_READFILE)) { /* we should include the contents from the specified file */ FILE *fileread; - char buffer[1024]; - size_t nread; fileread = strequal("-", file->contents)? stdin:fopen(file->contents, "rb"); /* binary read for win32 */ + /* * VMS: This only allows for stream files on VMS. Stream files are * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC, @@ -1091,13 +1074,27 @@ CURLcode Curl_getFormData(struct FormData **finalform, */ if(fileread) { - while((nread = fread(buffer, 1, 1024, fileread))) { - result = AddFormData(&form, buffer, nread, &size); - if (result) - break; - } - if(fileread != stdin) + if(fileread != stdin) { + /* close the file again */ fclose(fileread); + /* add the file name only - for later reading from this */ + result = AddFormData(&form, FORM_FILE, file->contents, 0, &size); + } + else { + /* When uploading from stdin, we can't know the size of the file, + * thus must read the full file as before. We *could* use chunked + * transfer-encoding, but that only works for HTTP 1.1 and we + * can't be sure we work with such a server. + */ + size_t nread; + char buffer[512]; + while((nread = fread(buffer, 1, sizeof(buffer), fileread))) { + result = AddFormData(&form, FORM_DATA, buffer, nread, &size); + if (result) + break; + } + } + if (result) { Curl_formclean(firstform); free(boundary); @@ -1115,16 +1112,16 @@ CURLcode Curl_getFormData(struct FormData **finalform, } else if (post->flags & HTTPPOST_BUFFER) { /* include contents of buffer */ - result = AddFormData(&form, post->buffer, post->bufferlength, - &size); + result = AddFormData(&form, FORM_DATA, post->buffer, + post->bufferlength, &size); if (result) break; } else { /* include the contents we got */ - result = AddFormData(&form, post->contents, post->contentslength, - &size); + result = AddFormData(&form, FORM_DATA, post->contents, + post->contentslength, &size); if (result) break; } @@ -1183,10 +1180,32 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata ) form->data = formdata; form->sent = 0; + form->fp = NULL; return 0; } +static size_t readfromfile(struct Form *form, char *buffer, size_t size) +{ + size_t nread; + if(!form->fp) { + /* this file hasn't yet been opened */ + form->fp = fopen(form->data->line, "rb"); /* b is for binary */ + if(!form->fp) + return -1; /* failure */ + } + nread = fread(buffer, 1, size, form->fp); + + if(nread != size) { + /* this is the last chunk form the file, move on */ + fclose(form->fp); + form->fp = NULL; + form->data = form->data->next; + } + + return nread; +} + /* * Curl_FormReader() is the fread() emulation function that will be used to * deliver the formdata to the transfer loop and then sent away to the peer. @@ -1207,6 +1226,9 @@ size_t Curl_FormReader(char *buffer, if(!form->data) return 0; /* nothing, error, empty */ + if(form->data->type == FORM_FILE) + return readfromfile(form, buffer, wantedsize); + do { if( (form->data->length - form->sent ) > wantedsize - gotsize) { @@ -1228,7 +1250,7 @@ size_t Curl_FormReader(char *buffer, form->data = form->data->next; /* advance */ - } while(form->data); + } while(form->data && (form->data->type == FORM_DATA)); /* If we got an empty line and we have more data, we proceed to the next line immediately to avoid returning zero before we've reached the end. This is the bug reported November 22 1999 on curl 6.3. (Daniel) */ @@ -1475,3 +1497,36 @@ void curl_formfree(struct curl_httppost *form) } #endif /* CURL_DISABLE_HTTP */ + +/* + * Curl_FormBoundary() creates a suitable boundary string and returns an + * allocated one. This is also used by SSL-code so it must be present even + * if HTTP is disabled! + */ +char *Curl_FormBoundary(void) +{ + char *retstring; + static int randomizer=0; /* this is just so that two boundaries within + the same form won't be identical */ + size_t i; + + static char table16[]="abcdef0123456789"; + + retstring = (char *)malloc(BOUNDARY_LENGTH+1); + + if(!retstring) + return NULL; /* failed */ + + srand(time(NULL)+randomizer++); /* seed */ + + strcpy(retstring, "----------------------------"); + + for(i=strlen(retstring); i Date: Thu, 24 Jun 2004 07:43:48 +0000 Subject: Source cleanups. The major one being that we now _always_ use a Curl_addrinfo linked list for name resolved data, even on hosts/systems with only IPv4 stacks as this simplifies a lot of code. --- lib/formdata.c | 54 ------------------------------------------------------ 1 file changed, 54 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index ea5c4acd8..c338052da 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1426,60 +1426,6 @@ int main() #endif -#ifdef _OLD_FORM_DEBUG - -int main(int argc, char **argv) -{ -#if 0 - char *testargs[]={ - "name1 = data in number one", - "name2 = number two data", - "test = @upload" - }; -#endif - int i; - char *nextarg; - struct curl_httppost *httppost=NULL; - struct curl_httppost *last_post=NULL; - struct curl_httppost *post; - int size; - int nread; - char buffer[4096]; - - struct FormData *form; - struct Form formread; - - for(i=1; i Date: Thu, 24 Jun 2004 11:54:11 +0000 Subject: Replaced all uses of sprintf() with the safer snprintf(). It is just a precaution to prevent mistakes to lead to buffer overflows. --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index c338052da..9c7fc8be2 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -846,7 +846,7 @@ static CURLcode AddFormDataf(struct FormData **formp, char s[4096]; va_list ap; va_start(ap, fmt); - vsprintf(s, fmt, ap); + vsnprintf(s, sizeof(s), fmt, ap); va_end(ap); return AddFormData(formp, FORM_DATA, s, 0, size); -- cgit v1.2.1 From 8e87223195bba350f7fab9575a3ea3de85a49166 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 1 Oct 2004 06:36:11 +0000 Subject: - Based on Fedor Karpelevitch's formpost path basename patch, file parts in formposts no longer include the path part. If you _really_ want them, you must provide your preferred full file name with CURLFORM_FILENAME. Added detection for libgen.h and basename() to configure. My custom basename() replacement function for systems without it, might be a bit too naive... Updated 6 test cases to make them work with the stripped paths. --- lib/formdata.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 9c7fc8be2..798303d3a 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -113,6 +113,9 @@ Content-Disposition: form-data; name="FILECONTENT" #include #include #include +#ifdef HAVE_LIBGEN_H +#include +#endif #include "formdata.h" #include "strequal.h" #include "memory.h" @@ -903,6 +906,67 @@ void curl_formfree(struct curl_httppost *form) } while((form=next)); /* continue */ } +#ifndef HAVE_BASENAME +/* + (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 + Edition) + + The basename() function shall take the pathname pointed to by path and + return a pointer to the final component of the pathname, deleting any + trailing '/' characters. + + If the string pointed to by path consists entirely of the '/' character, + basename() shall return a pointer to the string "/". If the string pointed + to by path is exactly "//", it is implementation-defined whether '/' or "//" + is returned. + + If path is a null pointer or points to an empty string, basename() shall + return a pointer to the string ".". + + The basename() function may modify the string pointed to by path, and may + return a pointer to static storage that may then be overwritten by a + subsequent call to basename(). + + The basename() function need not be reentrant. A function that is not + required to be reentrant is not required to be thread-safe. + +*/ +char *basename(char *path) +{ + /* Ignore all the details above for now and make a quick and simple + implementaion here */ + char *s1; + char *s2; + + s1=strrchr(path, '/'); + s2=strrchr(path, '\\'); + + if(s1 && s2) { + path = (s1 > s2? s1 : s2)+1; + } + else { + path = (s1 ? s1 : s2)+1; + } + + return path; +} +#endif + +static char *strippath(char *fullfile) +{ + char *filename; + char *base; + filename = strdup(fullfile); /* duplicate since basename() may ruin the + buffer it works on */ + if(!filename) + return NULL; + base = strdup(basename(filename)); + + free(filename); /* free temporary buffer */ + + return base; /* returns an allocated string! */ +} + /* * Curl_getFormData() converts a linked list of "meta data" into a complete * (possibly huge) multipart formdata. The input list is in 'post', while the @@ -998,22 +1062,33 @@ CURLcode Curl_getFormData(struct FormData **finalform, if(post->more) { /* if multiple-file */ + char *filebasename= + (!file->showfilename)?strippath(file->contents):NULL; + result = AddFormDataf(&form, &size, "\r\n--%s\r\nContent-Disposition: " "attachment; filename=\"%s\"", fileboundary, (file->showfilename?file->showfilename: - file->contents)); + filebasename)); + if (filebasename) + free(filebasename); if (result) break; } else if((post->flags & HTTPPOST_FILENAME) || (post->flags & HTTPPOST_BUFFER)) { + char *filebasename= + (!post->showfilename)?strippath(post->contents):NULL; + result = AddFormDataf(&form, &size, "; filename=\"%s\"", (post->showfilename?post->showfilename: - post->contents)); + filebasename)); + if (filebasename) + free(filebasename); + if (result) break; } -- cgit v1.2.1 From ec4da97a35fb285c4316f8b4017f84cba5d494b7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 1 Oct 2004 11:20:38 +0000 Subject: fixed the basename() replacement, reported by Gisle --- lib/formdata.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 798303d3a..affaf4b6d 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -944,9 +944,10 @@ char *basename(char *path) if(s1 && s2) { path = (s1 > s2? s1 : s2)+1; } - else { - path = (s1 ? s1 : s2)+1; - } + else if(s1) + path = s1 + 1; + else if(s2) + path = s1 + 1; return path; } -- cgit v1.2.1 From fd2aad1d9b3a2cbb3f9e2c90e7681c2f0516ec01 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 1 Oct 2004 11:27:14 +0000 Subject: someone should hit me --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index affaf4b6d..e03d75aea 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -947,7 +947,7 @@ char *basename(char *path) else if(s1) path = s1 + 1; else if(s2) - path = s1 + 1; + path = s2 + 1; return path; } -- cgit v1.2.1 From d5dd8e0fdc780777998c068dee4fd4ce3e5dffe0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Oct 2004 06:49:09 +0000 Subject: let our basename() be static --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index e03d75aea..91ad34c0a 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -931,7 +931,7 @@ void curl_formfree(struct curl_httppost *form) required to be reentrant is not required to be thread-safe. */ -char *basename(char *path) +static char *basename(char *path) { /* Ignore all the details above for now and make a quick and simple implementaion here */ -- cgit v1.2.1 From 121197bc8795480c7fea0619cc9f6ce38eb14913 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Oct 2004 06:55:09 +0000 Subject: Only include libgen.h if we have a basename as well. Mainly meant to deal with the IRIX case which seems to requrie a "-lgen" lib to find the basename function and thus without the gen lib, it finds the header but not the function and our replacement function has a prototype that doesn't match the IRIX one. A different approach would be to make configure detect and use -lgen for the systems that require it. --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 91ad34c0a..5297e68de 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -113,7 +113,7 @@ Content-Disposition: form-data; name="FILECONTENT" #include #include #include -#ifdef HAVE_LIBGEN_H +#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) #include #endif #include "formdata.h" -- cgit v1.2.1 From 39af394a1c3ae1d8ac71ad263a7c524988702c2e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 6 Oct 2004 07:50:18 +0000 Subject: removed tabs and trailing whitespace from source --- lib/formdata.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 5297e68de..d7c741938 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -242,7 +242,7 @@ static FormInfo * AddFormInfo(char *value, * ***************************************************************************/ static const char * ContentTypeForFilename (const char *filename, - const char *prevtype) + const char *prevtype) { const char *contenttype = NULL; unsigned int i; @@ -273,10 +273,10 @@ static const char * ContentTypeForFilename (const char *filename, for(i=0; i= strlen(ctts[i].extension)) { if(strequal(filename + - strlen(filename) - strlen(ctts[i].extension), - ctts[i].extension)) { - contenttype = ctts[i].type; - break; + strlen(filename) - strlen(ctts[i].extension), + ctts[i].extension)) { + contenttype = ctts[i].type; + break; } } } @@ -606,23 +606,23 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, current_form))) return_value = CURL_FORMADD_MEMORY; } - else - return_value = CURL_FORMADD_NULL; + else + return_value = CURL_FORMADD_NULL; } else return_value = CURL_FORMADD_OPTION_TWICE; } else { - if (contenttype) { - current_form->contenttype = strdup(contenttype); + if (contenttype) { + current_form->contenttype = strdup(contenttype); if(!current_form->contenttype) return_value = CURL_FORMADD_MEMORY; else current_form->contenttype_alloc = TRUE; } - else - return_value = CURL_FORMADD_NULL; - } + else + return_value = CURL_FORMADD_NULL; + } break; } case CURLFORM_CONTENTHEADER: @@ -1425,10 +1425,10 @@ int main() name3[1] = '\0'; value3[1] = '\0'; if (FormAddTest("PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH test", - &httppost, &last_post, + &httppost, &last_post, CURLFORM_PTRNAME, name3, CURLFORM_COPYCONTENTS, value3, CURLFORM_CONTENTSLENGTH, value3length, - CURLFORM_NAMELENGTH, name3length, CURLFORM_END)) + CURLFORM_NAMELENGTH, name3length, CURLFORM_END)) ++errors; if (FormAddTest("simple PTRCONTENTS test", &httppost, &last_post, CURLFORM_COPYNAME, name4, CURLFORM_PTRCONTENTS, value4, @@ -1529,7 +1529,7 @@ char *Curl_FormBoundary(void) { char *retstring; static int randomizer=0; /* this is just so that two boundaries within - the same form won't be identical */ + the same form won't be identical */ size_t i; static char table16[]="abcdef0123456789"; -- cgit v1.2.1 From 76637759713e97871d10da9c265a40410bdc672e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 8 Oct 2004 08:18:08 +0000 Subject: if basename was found, check for a prototype and if none was found, provide our own in the formdata.c file to prevent warnings on systems without it --- lib/formdata.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index d7c741938..171113485 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -126,6 +126,11 @@ Content-Disposition: form-data; name="FILECONTENT" /* The last #include file should be: */ #include "memdebug.h" +#if defined(HAVE_BASENAME) && defined(NEED_BASENAME_PROTO) +/* This system has a basename() but no prototype for it! */ +char *basename(char *path); +#endif + /* What kind of Content-Type to use on un-specified files with unrecognized extensions. */ #define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream" -- cgit v1.2.1 From beb61ef4298a91422679fec79475b70422095d40 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 24 Oct 2004 22:31:40 +0000 Subject: Mohun Biswas found out that formposting a zero-byte file didn't work very good. I fixed. --- lib/formdata.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 171113485..442c306f5 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1307,9 +1307,13 @@ size_t Curl_FormReader(char *buffer, if(!form->data) return 0; /* nothing, error, empty */ - if(form->data->type == FORM_FILE) - return readfromfile(form, buffer, wantedsize); + if(form->data->type == FORM_FILE) { + gotsize = readfromfile(form, buffer, wantedsize); + if(gotsize) + /* If positive or -1, return. If zero, continue! */ + return gotsize; + } do { if( (form->data->length - form->sent ) > wantedsize - gotsize) { -- cgit v1.2.1 From 24d47a6e07304cf0921f2d30734b3c64360773c3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Nov 2004 10:12:22 +0000 Subject: Paul Nolan fix to make libcurl build nicely on Windows CE --- lib/formdata.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 442c306f5..fa26ebbe5 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -112,7 +112,9 @@ Content-Disposition: form-data; name="FILECONTENT" #include #include #include +#ifdef HAVE_SYS_STAT_H #include +#endif #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) #include #endif -- cgit v1.2.1 From 1ba47e7af9edfa682faba73df8bf0dc240facb19 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 15 Dec 2004 01:38:25 +0000 Subject: Add 'const' to immutable arrays. --- lib/formdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index fa26ebbe5..07e5a0ddf 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -261,7 +261,7 @@ static const char * ContentTypeForFilename (const char *filename, const char *extension; const char *type; }; - static struct ContentType ctts[]={ + static const struct ContentType ctts[]={ {".gif", "image/gif"}, {".jpg", "image/jpeg"}, {".jpeg", "image/jpeg"}, @@ -1543,7 +1543,7 @@ char *Curl_FormBoundary(void) the same form won't be identical */ size_t i; - static char table16[]="abcdef0123456789"; + static const char table16[]="abcdef0123456789"; retstring = (char *)malloc(BOUNDARY_LENGTH+1); -- cgit v1.2.1 From 4f5a6a33b46f9c389e6cfcd822c6fc874a3a9752 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Dec 2004 18:09:27 +0000 Subject: moved the lseek() and stat() magic defines to setup.h and now take advantage of struct_stat in formdata.c as well, to support formpost uploads of large files on Windows too --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 07e5a0ddf..4f0845c3f 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -835,7 +835,7 @@ static CURLcode AddFormData(struct FormData **formp, /* Since this is a file to be uploaded here, add the size of the actual file */ if(!strequal("-", newform->line)) { - struct stat file; + struct_stat file; if(!stat(newform->line, &file)) { *size += file.st_size; } -- cgit v1.2.1 From 99befd3a155369280236b918dcf2739e599b5eaa Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 22 Dec 2004 20:12:15 +0000 Subject: C ensures that static variables are initialized to 0 --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 4f0845c3f..1d11bc939 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1539,7 +1539,7 @@ void curl_formfree(struct curl_httppost *form) char *Curl_FormBoundary(void) { char *retstring; - static int randomizer=0; /* this is just so that two boundaries within + static int randomizer; /* this is just so that two boundaries within the same form won't be identical */ size_t i; -- cgit v1.2.1 From 6b1220b61d5ed2481dbf31714a68be6ef6eed3da Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 26 Apr 2005 13:08:49 +0000 Subject: Cory Nelson's work on nuking compiler warnings when building on x64 with VS2005. --- lib/formdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 1d11bc939..8fe1556ba 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -464,7 +464,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_OPTION_TWICE; else current_form->namelength = - array_state?(long)array_value:va_arg(params, long); + array_state?(long)array_value:(long)va_arg(params, long); break; /* @@ -1550,7 +1550,7 @@ char *Curl_FormBoundary(void) if(!retstring) return NULL; /* failed */ - srand(time(NULL)+randomizer++); /* seed */ + srand((unsigned int)time(NULL)+randomizer++); /* seed */ strcpy(retstring, "----------------------------"); -- cgit v1.2.1 From 11bdba00075eb333d0d65067d5b79d2eff0d2f21 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 2 May 2005 14:33:07 +0000 Subject: corrected copyright year --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 8fe1556ba..5d66e0a91 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2005, 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 -- cgit v1.2.1 From d055b269ed8e515933b75d2ee482b0307cdf8a0e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 24 Nov 2005 20:38:20 +0000 Subject: Yang Tse: fix compilation errors when SSL is not disabled and HTTP is disabled --- lib/formdata.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 5d66e0a91..958e6cd2a 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -105,7 +105,7 @@ Content-Disposition: form-data; name="FILECONTENT" /* Length of the random boundary string. */ #define BOUNDARY_LENGTH 40 -#ifndef CURL_DISABLE_HTTP +#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) #include #include @@ -128,6 +128,10 @@ Content-Disposition: form-data; name="FILECONTENT" /* The last #include file should be: */ #include "memdebug.h" +#endif /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */ + +#ifndef CURL_DISABLE_HTTP + #if defined(HAVE_BASENAME) && defined(NEED_BASENAME_PROTO) /* This system has a basename() but no prototype for it! */ char *basename(char *path); @@ -1511,7 +1515,7 @@ int main() return 0; } -#endif +#endif /* _FORM_DEBUG */ #else /* CURL_DISABLE_HTTP */ CURLFORMcode curl_formadd(struct curl_httppost **httppost, @@ -1531,6 +1535,8 @@ void curl_formfree(struct curl_httppost *form) #endif /* CURL_DISABLE_HTTP */ +#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) + /* * Curl_FormBoundary() creates a suitable boundary string and returns an * allocated one. This is also used by SSL-code so it must be present even @@ -1563,3 +1569,5 @@ char *Curl_FormBoundary(void) return retstring; } + +#endif /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */ -- cgit v1.2.1 From 12db20be4e8b0130aba7342a1124eb85e3115822 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Wed, 26 Apr 2006 17:26:22 +0000 Subject: Fixed signed/unsigned convertion errors in Salford-C. #ifdef around WSAEDISCON in strerror.c. --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 958e6cd2a..86c297745 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1279,7 +1279,7 @@ static size_t readfromfile(struct Form *form, char *buffer, size_t size) /* this file hasn't yet been opened */ form->fp = fopen(form->data->line, "rb"); /* b is for binary */ if(!form->fp) - return -1; /* failure */ + return (size_t)-1; /* failure */ } nread = fread(buffer, 1, size, form->fp); -- cgit v1.2.1 From 37f4877e569cdd0d1afa6bb0d7cd3a463ee75ac9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 24 Jun 2006 21:46:41 +0000 Subject: Michael Wallner added curl_formget(), which allows an application to extract (serialise) a previously built formpost (as with curl_formadd()). --- lib/formdata.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 86c297745..0fbb23aa7 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, 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 @@ -137,6 +137,8 @@ Content-Disposition: form-data; name="FILECONTENT" char *basename(char *path); #endif +static size_t readfromfile(struct Form *form, char *buffer, size_t size); + /* What kind of Content-Type to use on un-specified files with unrecognized extensions. */ #define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream" @@ -885,6 +887,51 @@ void Curl_formclean(struct FormData *form) } while((form=next)); /* continue */ } +/* + * curl_formget() + * Serialize a curl_httppost struct. + * Returns 0 on success. + */ +int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append) +{ + CURLFORMcode rc; + curl_off_t size; + struct FormData *data, *ptr; + + if ((rc = Curl_getFormData(&data, form, &size))) { + return (int)rc; + } + + for (ptr = data; ptr; ptr = ptr->next) { + if (ptr->type == FORM_FILE) { + char buffer[8192]; + size_t read; + struct Form temp; + + Curl_FormInit(&temp, ptr); + + do { + read = readfromfile(&temp, buffer, sizeof(buffer)); + if ((read == (size_t) -1) || (read != append(arg, buffer, read))) { + if (temp.fp) { + fclose(temp.fp); + } + Curl_formclean(data); + return -1; + } + } while (read == sizeof(buffer)); + } else { + if (ptr->length != append(arg, ptr->line, ptr->length)) { + Curl_formclean(data); + return -1; + } + } + } + Curl_formclean(data); + return 0; +} + /* * curl_formfree() is an external function to free up a whole form post * chain @@ -1284,7 +1331,7 @@ static size_t readfromfile(struct Form *form, char *buffer, size_t size) nread = fread(buffer, 1, size, form->fp); if(nread != size) { - /* this is the last chunk form the file, move on */ + /* this is the last chunk from the file, move on */ fclose(form->fp); form->fp = NULL; form->data = form->data->next; @@ -1527,6 +1574,15 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost, return CURL_FORMADD_DISABLED; } +CURLFORMCode curl_formget(struct curl_httppost *post, void *arg, + curl_formget_callback append) +{ + (void) post; + (void) arg; + (void) append; + return CURL_FORMADD_DISABLED; +} + void curl_formfree(struct curl_httppost *form) { (void)form; -- cgit v1.2.1 From 856114d05c8429f63ac8c2fe415362fd7406799e Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 28 Jun 2006 02:45:27 +0000 Subject: fix minor compiler warning --- lib/formdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 0fbb23aa7..a42ea5390 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -895,11 +895,11 @@ void Curl_formclean(struct FormData *form) int curl_formget(struct curl_httppost *form, void *arg, curl_formget_callback append) { - CURLFORMcode rc; + CURLcode rc; curl_off_t size; struct FormData *data, *ptr; - if ((rc = Curl_getFormData(&data, form, &size))) { + if ((rc = Curl_getFormData(&data, form, &size)) != CURLE_OK) { return (int)rc; } -- cgit v1.2.1 From 27c0b438976d0f964b3b6ee126d985759da06662 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 20 Jul 2006 20:04:52 +0000 Subject: David McCreedy fixed a build error when building libcurl with HTTP disabled, problem added with the curl_formget() patch. --- lib/formdata.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index a42ea5390..6094e8e81 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1574,10 +1574,10 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost, return CURL_FORMADD_DISABLED; } -CURLFORMCode curl_formget(struct curl_httppost *post, void *arg, - curl_formget_callback append) +int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append) { - (void) post; + (void) form; (void) arg; (void) append; return CURL_FORMADD_DISABLED; -- cgit v1.2.1 From a88deadd6f85a6ac3b7f9d574bbb7eaab3115700 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 27 Jul 2006 22:35:09 +0000 Subject: Yves Lejeune fixed so that replacing Content-Type: when doing multipart formposts work exactly the way you want it (and the way you'd assume it works) --- lib/formdata.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 6094e8e81..201bdcaa5 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -899,9 +899,9 @@ int curl_formget(struct curl_httppost *form, void *arg, curl_off_t size; struct FormData *data, *ptr; - if ((rc = Curl_getFormData(&data, form, &size)) != CURLE_OK) { + rc = Curl_getFormData(&data, form, NULL, &size); + if (rc != CURLE_OK) return (int)rc; - } for (ptr = data; ptr; ptr = ptr->next) { if (ptr->type == FORM_FILE) { @@ -1031,10 +1031,13 @@ static char *strippath(char *fullfile) * (possibly huge) multipart formdata. The input list is in 'post', while the * output resulting linked lists gets stored in '*finalform'. *sizep will get * the total size of the whole POST. + * A multipart/form_data content-type is built, unless a custom content-type + * is passed in 'custom_content_type'. */ CURLcode Curl_getFormData(struct FormData **finalform, struct curl_httppost *post, + const char *custom_content_type, curl_off_t *sizep) { struct FormData *form = NULL; @@ -1058,9 +1061,11 @@ CURLcode Curl_getFormData(struct FormData **finalform, /* Make the first line of the output */ result = AddFormDataf(&form, NULL, - "Content-Type: multipart/form-data;" - " boundary=%s\r\n", + "%s; boundary=%s\r\n", + custom_content_type?custom_content_type: + "Content-Type: multipart/form-data", boundary); + if (result) { free(boundary); return result; @@ -1083,6 +1088,10 @@ CURLcode Curl_getFormData(struct FormData **finalform, if (result) break; + /* Maybe later this should be disabled when a custom_content_type is + passed, since Content-Disposition is not meaningful for all multipart + types. + */ result = AddFormDataf(&form, &size, "Content-Disposition: form-data; name=\""); if (result) -- cgit v1.2.1 From 4031eb1d91936610ccff8df0e92a51d1ec11d3b5 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Tue, 29 Aug 2006 21:11:55 +0000 Subject: Avoid Metaware's High-C warning "'=' encountered where '==' may have been intended." --- lib/formdata.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 201bdcaa5..4c53045f2 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -528,8 +528,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if (current_form->value) { if (current_form->flags & HTTPPOST_FILENAME) { if (filename) { - if (!(current_form = AddFormInfo(strdup(filename), - NULL, current_form))) + if ((current_form = AddFormInfo(strdup(filename), + NULL, current_form)) == NULL) return_value = CURL_FORMADD_MEMORY; } else @@ -562,8 +562,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if (current_form->value) { if (current_form->flags & HTTPPOST_BUFFER) { if (filename) { - if (!(current_form = AddFormInfo(strdup(filename), - NULL, current_form))) + if ((current_form = AddFormInfo(strdup(filename), + NULL, current_form)) == NULL) return_value = CURL_FORMADD_MEMORY; } else @@ -614,9 +614,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if (current_form->contenttype) { if (current_form->flags & HTTPPOST_FILENAME) { if (contenttype) { - if (!(current_form = AddFormInfo(NULL, - strdup(contenttype), - current_form))) + if ((current_form = AddFormInfo(NULL, + strdup(contenttype), + current_form)) == NULL) return_value = CURL_FORMADD_MEMORY; } else @@ -884,7 +884,7 @@ void Curl_formclean(struct FormData *form) free(form->line); /* free the line */ free(form); /* free the struct */ - } while((form=next)); /* continue */ + } while ((form = next) != NULL); /* continue */ } /* @@ -961,7 +961,7 @@ void curl_formfree(struct curl_httppost *form) free(form->showfilename); /* free the faked file name */ free(form); /* free the struct */ - } while((form=next)); /* continue */ + } while ((form = next) != NULL); /* continue */ } #ifndef HAVE_BASENAME @@ -1231,7 +1231,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, */ size_t nread; char buffer[512]; - while((nread = fread(buffer, 1, sizeof(buffer), fileread))) { + while ((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) { result = AddFormData(&form, FORM_DATA, buffer, nread, &size); if (result) break; @@ -1268,7 +1268,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, if (result) break; } - } while((file = file->more)); /* for each specified file for this field */ + } while ((file = file->more) != NULL); /* for each specified file for this field */ if (result) { Curl_formclean(firstform); free(boundary); @@ -1286,7 +1286,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, break; } - } while((post=post->next)); /* for each field */ + } while ((post = post->next) != NULL); /* for each field */ if (result) { Curl_formclean(firstform); free(boundary); -- cgit v1.2.1 From 0fb5a65a58130da7882f0a8d396e24b95c25064f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 14 Jan 2007 14:57:51 +0000 Subject: - David McCreedy provided libcurl changes for doing HTTP communication on non-ASCII platforms. It does add some complexity, most notably with more #ifdefs, but I want to see this supported added and I can't see how we can add it without the extra stuff added. --- lib/formdata.c | 106 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 81 insertions(+), 25 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 4c53045f2..2d98870e0 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -24,7 +24,7 @@ /* Debug the form generator stand-alone by compiling this source file with: - gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c strequal.c + gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -DCURLDEBUG -o formdata -I../include formdata.c strequal.c memdebug.c mprintf.c strerror.c run the 'formdata' executable the output should end with: All Tests seem to have worked ... @@ -63,7 +63,7 @@ Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz Content-Disposition: attachment; filename="inet_ntoa_r.h" Content-Type: text/plain ... -Content-Disposition: attachment; filename="Makefile.b32.resp" +Content-Disposition: attachment; filename="Makefile.b32" Content-Type: text/plain ... @@ -73,7 +73,7 @@ Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 Content-Disposition: attachment; filename="inet_ntoa_r.h" Content-Type: text/plain ... -Content-Disposition: attachment; filename="Makefile.b32.resp" +Content-Disposition: attachment; filename="Makefile.b32" Content-Type: text/plain ... Content-Disposition: attachment; filename="inet_ntoa_r.h" @@ -87,7 +87,7 @@ Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 Content-Disposition: attachment; filename="inet_ntoa_r.h" Content-Type: text/plain ... -Content-Disposition: attachment; filename="Makefile.b32.resp" +Content-Disposition: attachment; filename="Makefile.b32" Content-Type: text/plain ... Content-Disposition: attachment; filename="inet_ntoa_r.h" @@ -118,6 +118,8 @@ Content-Disposition: form-data; name="FILECONTENT" #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) #include #endif +#include "urldata.h" /* for struct SessionHandle */ +#include "easyif.h" /* for Curl_convert_... prototypes */ #include "formdata.h" #include "strequal.h" #include "memory.h" @@ -452,7 +454,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, * Set the Name property. */ case CURLFORM_PTRNAME: +#ifdef CURL_DOES_CONVERSIONS + /* treat CURLFORM_PTR like CURLFORM_COPYNAME so we'll + have safe memory for the eventual conversion */ +#else current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ +#endif case CURLFORM_COPYNAME: if (current_form->name) return_value = CURL_FORMADD_OPTION_TWICE; @@ -835,7 +842,7 @@ static CURLcode AddFormData(struct FormData **formp, *formp = newform; if (size) { - if(type == FORM_DATA) + if((type == FORM_DATA) || (type == FORM_CONTENT)) *size += length; else { /* Since this is a file to be uploaded here, add the size of the actual @@ -872,10 +879,11 @@ static CURLcode AddFormDataf(struct FormData **formp, * Curl_formclean() is used from http.c, this cleans a built FormData linked * list */ -void Curl_formclean(struct FormData *form) +void Curl_formclean(struct FormData **form_ptr) { - struct FormData *next; + struct FormData *next, *form; + form = *form_ptr; if(!form) return; @@ -885,8 +893,40 @@ void Curl_formclean(struct FormData *form) free(form); /* free the struct */ } while ((form = next) != NULL); /* continue */ + + *form_ptr = NULL; } +#ifdef CURL_DOES_CONVERSIONS +/* + * Curl_formcovert() is used from http.c, this converts any + form items that need to be sent in the network encoding. + Returns CURLE_OK on success. + */ +CURLcode Curl_formconvert(struct SessionHandle *data, struct FormData *form) +{ + struct FormData *next; + CURLcode rc; + + if(!form) + return CURLE_OK; + + if(!data) + return CURLE_BAD_FUNCTION_ARGUMENT; + + do { + next=form->next; /* the following form line */ + if (form->type == FORM_DATA) { + rc = Curl_convert_to_network(data, form->line, form->length); + /* Curl_convert_to_network calls failf if unsuccessful */ + if (rc != CURLE_OK) + return rc; + } + } while ((form = next) != NULL); /* continue */ + return CURLE_OK; +} +#endif /* CURL_DOES_CONVERSIONS */ + /* * curl_formget() * Serialize a curl_httppost struct. @@ -917,18 +957,18 @@ int curl_formget(struct curl_httppost *form, void *arg, if (temp.fp) { fclose(temp.fp); } - Curl_formclean(data); + Curl_formclean(&data); return -1; } } while (read == sizeof(buffer)); } else { if (ptr->length != append(arg, ptr->line, ptr->length)) { - Curl_formclean(data); + Curl_formclean(&data); return -1; } } } - Curl_formclean(data); + Curl_formclean(&data); return 0; } @@ -1179,7 +1219,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, curList = curList->next; } if (result) { - Curl_formclean(firstform); + Curl_formclean(&firstform); free(boundary); return result; } @@ -1194,7 +1234,10 @@ CURLcode Curl_getFormData(struct FormData **finalform, if(file->contenttype && !checkprefix("text/", file->contenttype)) { /* this is not a text content, mention our binary encoding */ - size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); + result = AddFormDataf(&form, &size, + "\r\nContent-Transfer-Encoding: binary"); + if (result) + break; } #endif @@ -1232,21 +1275,26 @@ CURLcode Curl_getFormData(struct FormData **finalform, size_t nread; char buffer[512]; while ((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) { - result = AddFormData(&form, FORM_DATA, buffer, nread, &size); + result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size); if (result) break; } } if (result) { - Curl_formclean(firstform); + Curl_formclean(&firstform); free(boundary); return result; } } else { - Curl_formclean(firstform); +#ifdef _FORM_DEBUG + fprintf(stderr, + "\n==> Curl_getFormData couldn't open/read \"%s\"\n", + file->contents); +#endif + Curl_formclean(&firstform); free(boundary); *finalform = NULL; return CURLE_READ_ERROR; @@ -1255,7 +1303,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, } else if (post->flags & HTTPPOST_BUFFER) { /* include contents of buffer */ - result = AddFormData(&form, FORM_DATA, post->buffer, + result = AddFormData(&form, FORM_CONTENT, post->buffer, post->bufferlength, &size); if (result) break; @@ -1263,14 +1311,14 @@ CURLcode Curl_getFormData(struct FormData **finalform, else { /* include the contents we got */ - result = AddFormData(&form, FORM_DATA, post->contents, + result = AddFormData(&form, FORM_CONTENT, post->contents, post->contentslength, &size); if (result) break; } } while ((file = file->more) != NULL); /* for each specified file for this field */ if (result) { - Curl_formclean(firstform); + Curl_formclean(&firstform); free(boundary); return result; } @@ -1288,7 +1336,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, } while ((post = post->next) != NULL); /* for each field */ if (result) { - Curl_formclean(firstform); + Curl_formclean(&firstform); free(boundary); return result; } @@ -1298,7 +1346,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, "\r\n--%s--\r\n", boundary); if (result) { - Curl_formclean(firstform); + Curl_formclean(&firstform); free(boundary); return result; } @@ -1397,7 +1445,7 @@ size_t Curl_FormReader(char *buffer, form->data = form->data->next; /* advance */ - } while(form->data && (form->data->type == FORM_DATA)); + } while(form->data && (form->data->type != FORM_FILE)); /* If we got an empty line and we have more data, we proceed to the next line immediately to avoid returning zero before we've reached the end. This is the bug reported November 22 1999 on curl 6.3. (Daniel) */ @@ -1464,7 +1512,7 @@ int main() char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH"; char value6[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE"; char value7[] = "inet_ntoa_r.h"; - char value8[] = "Makefile.b32.resp"; + char value8[] = "Makefile.b32"; char type2[] = "image/gif"; char type6[] = "text/plain"; char type7[] = "text/html"; @@ -1473,7 +1521,8 @@ int main() int value5length = strlen(value4); int value6length = strlen(value5); int errors = 0; - int size; + CURLcode rc; + size_t size; size_t nread; char buffer[4096]; struct curl_httppost *httppost=NULL; @@ -1549,7 +1598,14 @@ int main() CURLFORM_END)) ++errors; - form=Curl_getFormData(httppost, &size); + rc = Curl_getFormData(&form, httppost, NULL, &size); + if(rc != CURLE_OK) { + if(rc != CURLE_READ_ERROR) { + const char *errortext = curl_easy_strerror(rc); + fprintf(stdout, "\n==> Curl_getFormData error: %s\n", errortext); + } + return 0; + } Curl_FormInit(&formread, form); @@ -1557,7 +1613,7 @@ int main() nread = Curl_FormReader(buffer, 1, sizeof(buffer), (FILE *)&formread); - if(-1 == nread) + if(nread < 1) break; fwrite(buffer, nread, 1, stdout); } while(1); -- cgit v1.2.1 From b6f889085ddaecd2f13ce287615a9e1527a21d59 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 27 Jan 2007 03:43:05 +0000 Subject: update copyright year notice --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 2d98870e0..f10c6c70e 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, 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 -- cgit v1.2.1 From c514a2a89aa1c1e06b70405eedb4e1f70b27fd10 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Mon, 26 Feb 2007 04:24:26 +0000 Subject: Removed inclusion of and in .c-files since they're already included through "setup.h". --- lib/formdata.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index f10c6c70e..a5118b389 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -112,9 +112,6 @@ Content-Disposition: form-data; name="FILECONTENT" #include #include #include -#ifdef HAVE_SYS_STAT_H -#include -#endif #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) #include #endif -- cgit v1.2.1 From 4d9e24d1e48280b4dd25489a501d65e71fff476b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 31 Mar 2007 21:01:18 +0000 Subject: Better deal with NULL pointers. CID 3 and 4 from the coverity.com scan. --- lib/formdata.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index a5118b389..e9db070c9 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -282,13 +282,15 @@ static const char * ContentTypeForFilename (const char *filename, text/plain so we don't actually need to set this: */ contenttype = HTTPPOST_CONTENTTYPE_DEFAULT; - for(i=0; i= strlen(ctts[i].extension)) { - if(strequal(filename + - strlen(filename) - strlen(ctts[i].extension), - ctts[i].extension)) { - contenttype = ctts[i].type; - break; + if(filename) { /* in case a NULL was passed in */ + for(i=0; i= strlen(ctts[i].extension)) { + if(strequal(filename + + strlen(filename) - strlen(ctts[i].extension), + ctts[i].extension)) { + contenttype = ctts[i].type; + break; + } } } } @@ -315,10 +317,14 @@ static char *memdup(const char *src, size_t buffer_length) if (buffer_length) length = buffer_length; - else { + else if(src) { length = strlen(src); add = TRUE; } + else + /* no length and a NULL src pointer! */ + return strdup((char *)""); + buffer = (char*)malloc(length+add); if (!buffer) return NULL; /* fail */ -- cgit v1.2.1 From 26af759732259030bd90400037005d0faeac5b28 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 5 Aug 2007 21:33:31 +0000 Subject: Patrick Monnerat updated the _FORM_DEBUG-enabled code, and I updated comments based on his comments/suggestions. --- lib/formdata.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index e9db070c9..e4d0922bb 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -24,7 +24,10 @@ /* Debug the form generator stand-alone by compiling this source file with: - gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -DCURLDEBUG -o formdata -I../include formdata.c strequal.c memdebug.c mprintf.c strerror.c + gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -DCURLDEBUG -o formdata \ + -I../include formdata.c strequal.c memdebug.c mprintf.c strerror.c + + (depending on circumstances you may need further externals added) run the 'formdata' executable the output should end with: All Tests seem to have worked ... @@ -49,8 +52,8 @@ vlue for PTRCONTENTS + CONTENTSLENGTH (or you might see v^@lue at the start) Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE" -Content-Type: text/plain -vlue for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE +Content-Type: application/octet-stream +vlue for PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE (or you might see v^@lue at the start) Content-Disposition: form-data; name="FILE1_+_CONTENTTYPE"; filename="inet_ntoa_r.h" @@ -61,23 +64,23 @@ Content-Disposition: form-data; name="FILE1_+_FILE2" Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz ... Content-Disposition: attachment; filename="inet_ntoa_r.h" -Content-Type: text/plain +Content-Type: application/octet-stream ... Content-Disposition: attachment; filename="Makefile.b32" -Content-Type: text/plain +Content-Type: application/octet-stream ... Content-Disposition: form-data; name="FILE1_+_FILE2_+_FILE3" Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 ... Content-Disposition: attachment; filename="inet_ntoa_r.h" -Content-Type: text/plain +Content-Type: application/octet-stream ... Content-Disposition: attachment; filename="Makefile.b32" -Content-Type: text/plain +Content-Type: application/octet-stream ... Content-Disposition: attachment; filename="inet_ntoa_r.h" -Content-Type: text/plain +Content-Type: application/octet-stream ... @@ -85,13 +88,13 @@ Content-Disposition: form-data; name="ARRAY: FILE1_+_FILE2_+_FILE3" Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 ... Content-Disposition: attachment; filename="inet_ntoa_r.h" -Content-Type: text/plain +Content-Type: application/octet-stream ... Content-Disposition: attachment; filename="Makefile.b32" -Content-Type: text/plain +Content-Type: application/octet-stream ... Content-Disposition: attachment; filename="inet_ntoa_r.h" -Content-Type: text/plain +Content-Type: application/octet-stream ... Content-Disposition: form-data; name="FILECONTENT" @@ -278,8 +281,6 @@ static const char * ContentTypeForFilename (const char *filename, /* default to the previously set/used! */ contenttype = prevtype; else - /* It seems RFC1867 defines no Content-Type to default to - text/plain so we don't actually need to set this: */ contenttype = HTTPPOST_CONTENTTYPE_DEFAULT; if(filename) { /* in case a NULL was passed in */ @@ -1495,7 +1496,7 @@ int FormAddTest(const char * errormsg, } -int main() +int main(int argc, argv_item_t argv[]) { char name1[] = "simple_COPYCONTENTS"; char name2[] = "COPYCONTENTS_+_CONTENTTYPE"; @@ -1513,7 +1514,7 @@ int main() char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH"; char value4[] = "value for simple PTRCONTENTS"; char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH"; - char value6[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE"; + char value6[] = "value for PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE"; char value7[] = "inet_ntoa_r.h"; char value8[] = "Makefile.b32"; char type2[] = "image/gif"; @@ -1521,11 +1522,11 @@ int main() char type7[] = "text/html"; int name3length = strlen(name3); int value3length = strlen(value3); - int value5length = strlen(value4); - int value6length = strlen(value5); + int value5length = strlen(value5); + int value6length = strlen(value6); int errors = 0; CURLcode rc; - size_t size; + curl_off_t size; size_t nread; char buffer[4096]; struct curl_httppost *httppost=NULL; @@ -1535,6 +1536,9 @@ int main() struct FormData *form; struct Form formread; + (void) argc; + (void) argv; + if (FormAddTest("simple COPYCONTENTS test", &httppost, &last_post, CURLFORM_COPYNAME, name1, CURLFORM_COPYCONTENTS, value1, CURLFORM_END)) @@ -1621,7 +1625,9 @@ int main() fwrite(buffer, nread, 1, stdout); } while(1); - fprintf(stdout, "size: %d\n", size); + fprintf(stdout, "size: "); + fprintf(stdout, CURL_FORMAT_OFF_T, size); + fprintf(stdout, "\n"); if (errors) fprintf(stdout, "\n==> %d Test(s) failed!\n", errors); else -- cgit v1.2.1 From 8cf0814a143d99de813fbd1653b785252b4c58a6 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Mon, 27 Aug 2007 06:31:28 +0000 Subject: Fixed some minor type mismatches and missing consts mainly found by splint. --- lib/formdata.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index e4d0922bb..64414f57b 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -481,7 +481,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_OPTION_TWICE; else current_form->namelength = - array_state?(long)array_value:(long)va_arg(params, long); + array_state?(size_t)array_value:(size_t)va_arg(params, long); break; /* @@ -506,7 +506,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_OPTION_TWICE; else current_form->contentslength = - array_state?(long)array_value:va_arg(params, long); + array_state?(size_t)array_value:(size_t)va_arg(params, long); break; /* Get contents from a given file name */ @@ -514,7 +514,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if (current_form->flags != 0) return_value = CURL_FORMADD_OPTION_TWICE; else { - char *filename = array_state? + const char *filename = array_state? array_value:va_arg(params, char *); if (filename) { current_form->value = strdup(filename); @@ -533,7 +533,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, /* We upload a file */ case CURLFORM_FILE: { - char *filename = array_state?array_value: + const char *filename = array_state?array_value: va_arg(params, char *); if (current_form->value) { @@ -567,7 +567,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, case CURLFORM_BUFFER: { - char *filename = array_state?array_value: + const char *filename = array_state?array_value: va_arg(params, char *); if (current_form->value) { @@ -615,12 +615,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_OPTION_TWICE; else current_form->bufferlength = - array_state?(long)array_value:va_arg(params, long); + array_state?(size_t)array_value:(size_t)va_arg(params, long); break; case CURLFORM_CONTENTTYPE: { - char *contenttype = + const char *contenttype = array_state?array_value:va_arg(params, char *); if (current_form->contenttype) { if (current_form->flags & HTTPPOST_FILENAME) { @@ -666,7 +666,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } case CURLFORM_FILENAME: { - char *filename = array_state?array_value: + const char *filename = array_state?array_value: va_arg(params, char *); if( current_form->showfilename ) return_value = CURL_FORMADD_OPTION_TWICE; @@ -1055,7 +1055,7 @@ static char *basename(char *path) } #endif -static char *strippath(char *fullfile) +static char *strippath(const char *fullfile) { char *filename; char *base; -- cgit v1.2.1 From 16b95fc77316fdd3866f7de4ebb5d14bd136ac11 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 27 Sep 2007 01:45:22 +0000 Subject: Enabled a few more gcc warnings with --enable-debug. Renamed a few variables to avoid shadowing global declarations. --- lib/formdata.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 64414f57b..05cfd3cc8 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -950,21 +950,21 @@ int curl_formget(struct curl_httppost *form, void *arg, for (ptr = data; ptr; ptr = ptr->next) { if (ptr->type == FORM_FILE) { char buffer[8192]; - size_t read; + size_t nread; struct Form temp; Curl_FormInit(&temp, ptr); do { - read = readfromfile(&temp, buffer, sizeof(buffer)); - if ((read == (size_t) -1) || (read != append(arg, buffer, read))) { + nread = readfromfile(&temp, buffer, sizeof(buffer)); + if ((nread == (size_t) -1) || (nread != append(arg, buffer, nread))) { if (temp.fp) { fclose(temp.fp); } Curl_formclean(&data); return -1; } - } while (read == sizeof(buffer)); + } while (nread == sizeof(buffer)); } else { if (ptr->length != append(arg, ptr->line, ptr->length)) { Curl_formclean(&data); -- cgit v1.2.1 From ad6e28073c985a42e8b15d2234baa7ef67ffcb35 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Nov 2007 09:45:09 +0000 Subject: removed space after if and while before the parenthesis for better source code consistency --- lib/formdata.c | 202 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 101 insertions(+), 101 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 05cfd3cc8..d80dc3d14 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -187,7 +187,7 @@ AddHttpPost(char * name, size_t namelength, else return NULL; - if (parent_post) { + if(parent_post) { /* now, point our 'more' to the original 'more' */ post->more = parent_post->more; @@ -224,16 +224,16 @@ static FormInfo * AddFormInfo(char *value, form_info = (FormInfo *)malloc(sizeof(FormInfo)); if(form_info) { memset(form_info, 0, sizeof(FormInfo)); - if (value) + if(value) form_info->value = value; - if (contenttype) + if(contenttype) form_info->contenttype = contenttype; form_info->flags = HTTPPOST_FILENAME; } else return NULL; - if (parent_form_info) { + if(parent_form_info) { /* now, point our 'more' to the original 'more' */ form_info->more = parent_form_info->more; @@ -316,7 +316,7 @@ static char *memdup(const char *src, size_t buffer_length) bool add = FALSE; char *buffer; - if (buffer_length) + if(buffer_length) length = buffer_length; else if(src) { length = strlen(src); @@ -327,13 +327,13 @@ static char *memdup(const char *src, size_t buffer_length) return strdup((char *)""); buffer = (char*)malloc(length+add); - if (!buffer) + if(!buffer) return NULL; /* fail */ memcpy(buffer, src, length); /* if length unknown do null termination */ - if (add) + if(add) buffer[length] = '\0'; return buffer; @@ -418,16 +418,16 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, /* * Loop through all the options set. Break if we have an error to report. */ - while (return_value == CURL_FORMADD_OK) { + while(return_value == CURL_FORMADD_OK) { /* first see if we have more parts of the array param */ - if ( array_state ) { + if( array_state ) { /* get the upcoming option from the given array */ option = forms->option; array_value = (char *)forms->value; forms++; /* advance this to next entry */ - if (CURLFORM_END == option) { + if(CURLFORM_END == option) { /* end of array state */ array_state = FALSE; continue; @@ -436,7 +436,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, else { /* This is not array-state, get next option */ option = va_arg(params, CURLformoption); - if (CURLFORM_END == option) + if(CURLFORM_END == option) break; } @@ -447,7 +447,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_ILLEGAL_ARRAY; else { forms = va_arg(params, struct curl_forms *); - if (forms) + if(forms) array_state = TRUE; else return_value = CURL_FORMADD_NULL; @@ -465,19 +465,19 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ #endif case CURLFORM_COPYNAME: - if (current_form->name) + if(current_form->name) return_value = CURL_FORMADD_OPTION_TWICE; else { char *name = array_state? array_value:va_arg(params, char *); - if (name) + if(name) current_form->name = name; /* store for the moment */ else return_value = CURL_FORMADD_NULL; } break; case CURLFORM_NAMELENGTH: - if (current_form->namelength) + if(current_form->namelength) return_value = CURL_FORMADD_OPTION_TWICE; else current_form->namelength = @@ -490,19 +490,19 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, case CURLFORM_PTRCONTENTS: current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ case CURLFORM_COPYCONTENTS: - if (current_form->value) + if(current_form->value) return_value = CURL_FORMADD_OPTION_TWICE; else { char *value = array_state?array_value:va_arg(params, char *); - if (value) + if(value) current_form->value = value; /* store for the moment */ else return_value = CURL_FORMADD_NULL; } break; case CURLFORM_CONTENTSLENGTH: - if (current_form->contentslength) + if(current_form->contentslength) return_value = CURL_FORMADD_OPTION_TWICE; else current_form->contentslength = @@ -511,12 +511,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, /* Get contents from a given file name */ case CURLFORM_FILECONTENT: - if (current_form->flags != 0) + if(current_form->flags != 0) return_value = CURL_FORMADD_OPTION_TWICE; else { const char *filename = array_state? array_value:va_arg(params, char *); - if (filename) { + if(filename) { current_form->value = strdup(filename); if(!current_form->value) return_value = CURL_FORMADD_MEMORY; @@ -536,10 +536,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, const char *filename = array_state?array_value: va_arg(params, char *); - if (current_form->value) { - if (current_form->flags & HTTPPOST_FILENAME) { - if (filename) { - if ((current_form = AddFormInfo(strdup(filename), + if(current_form->value) { + if(current_form->flags & HTTPPOST_FILENAME) { + if(filename) { + if((current_form = AddFormInfo(strdup(filename), NULL, current_form)) == NULL) return_value = CURL_FORMADD_MEMORY; } @@ -550,7 +550,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_OPTION_TWICE; } else { - if (filename) { + if(filename) { current_form->value = strdup(filename); if(!current_form->value) return_value = CURL_FORMADD_MEMORY; @@ -570,10 +570,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, const char *filename = array_state?array_value: va_arg(params, char *); - if (current_form->value) { - if (current_form->flags & HTTPPOST_BUFFER) { - if (filename) { - if ((current_form = AddFormInfo(strdup(filename), + if(current_form->value) { + if(current_form->flags & HTTPPOST_BUFFER) { + if(filename) { + if((current_form = AddFormInfo(strdup(filename), NULL, current_form)) == NULL) return_value = CURL_FORMADD_MEMORY; } @@ -584,7 +584,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_OPTION_TWICE; } else { - if (filename) { + if(filename) { current_form->value = strdup(filename); if(!current_form->value) return_value = CURL_FORMADD_MEMORY; @@ -598,12 +598,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, case CURLFORM_BUFFERPTR: current_form->flags |= HTTPPOST_PTRBUFFER; - if (current_form->buffer) + if(current_form->buffer) return_value = CURL_FORMADD_OPTION_TWICE; else { char *buffer = array_state?array_value:va_arg(params, char *); - if (buffer) + if(buffer) current_form->buffer = buffer; /* store for the moment */ else return_value = CURL_FORMADD_NULL; @@ -611,7 +611,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, break; case CURLFORM_BUFFERLENGTH: - if (current_form->bufferlength) + if(current_form->bufferlength) return_value = CURL_FORMADD_OPTION_TWICE; else current_form->bufferlength = @@ -622,10 +622,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, { const char *contenttype = array_state?array_value:va_arg(params, char *); - if (current_form->contenttype) { - if (current_form->flags & HTTPPOST_FILENAME) { - if (contenttype) { - if ((current_form = AddFormInfo(NULL, + if(current_form->contenttype) { + if(current_form->flags & HTTPPOST_FILENAME) { + if(contenttype) { + if((current_form = AddFormInfo(NULL, strdup(contenttype), current_form)) == NULL) return_value = CURL_FORMADD_MEMORY; @@ -637,7 +637,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, return_value = CURL_FORMADD_OPTION_TWICE; } else { - if (contenttype) { + if(contenttype) { current_form->contenttype = strdup(contenttype); if(!current_form->contenttype) return_value = CURL_FORMADD_MEMORY; @@ -692,7 +692,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, for(form = first_form; form != NULL; form = form->more) { - if ( ((!form->name || !form->value) && !post) || + if( ((!form->name || !form->value) && !post) || ( (form->contentslength) && (form->flags & HTTPPOST_FILENAME) ) || ( (form->flags & HTTPPOST_FILENAME) && @@ -709,7 +709,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, break; } else { - if ( ((form->flags & HTTPPOST_FILENAME) || + if( ((form->flags & HTTPPOST_FILENAME) || (form->flags & HTTPPOST_BUFFER)) && !form->contenttype ) { /* our contenttype is missing */ @@ -721,23 +721,23 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } form->contenttype_alloc = TRUE; } - if ( !(form->flags & HTTPPOST_PTRNAME) && + if( !(form->flags & HTTPPOST_PTRNAME) && (form == first_form) ) { /* copy name (without strdup; possibly contains null characters) */ form->name = memdup(form->name, form->namelength); - if (!form->name) { + if(!form->name) { return_value = CURL_FORMADD_MEMORY; break; } form->name_alloc = TRUE; } - if ( !(form->flags & HTTPPOST_FILENAME) && + if( !(form->flags & HTTPPOST_FILENAME) && !(form->flags & HTTPPOST_READFILE) && !(form->flags & HTTPPOST_PTRCONTENTS) && !(form->flags & HTTPPOST_PTRBUFFER) ) { /* copy value (without strdup; possibly contains null characters) */ form->value = memdup(form->value, form->contentslength); - if (!form->value) { + if(!form->value) { return_value = CURL_FORMADD_MEMORY; break; } @@ -756,7 +756,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, break; } - if (form->contenttype) + if(form->contenttype) prevtype = form->contenttype; } } @@ -780,7 +780,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, /* always delete the allocated memory before returning */ form = first_form; - while (form != NULL) { + while(form != NULL) { FormInfo *delete_form; delete_form = form; @@ -820,7 +820,7 @@ static CURLcode AddFormData(struct FormData **formp, { struct FormData *newform = (struct FormData *) malloc(sizeof(struct FormData)); - if (!newform) + if(!newform) return CURLE_OUT_OF_MEMORY; newform->next = NULL; @@ -829,7 +829,7 @@ static CURLcode AddFormData(struct FormData **formp, length = strlen((char *)line); newform->line = (char *)malloc(length+1); - if (!newform->line) { + if(!newform->line) { free(newform); return CURLE_OUT_OF_MEMORY; } @@ -845,7 +845,7 @@ static CURLcode AddFormData(struct FormData **formp, else *formp = newform; - if (size) { + if(size) { if((type == FORM_DATA) || (type == FORM_CONTENT)) *size += length; else { @@ -896,7 +896,7 @@ void Curl_formclean(struct FormData **form_ptr) free(form->line); /* free the line */ free(form); /* free the struct */ - } while ((form = next) != NULL); /* continue */ + } while((form = next) != NULL); /* continue */ *form_ptr = NULL; } @@ -920,13 +920,13 @@ CURLcode Curl_formconvert(struct SessionHandle *data, struct FormData *form) do { next=form->next; /* the following form line */ - if (form->type == FORM_DATA) { + if(form->type == FORM_DATA) { rc = Curl_convert_to_network(data, form->line, form->length); /* Curl_convert_to_network calls failf if unsuccessful */ - if (rc != CURLE_OK) + if(rc != CURLE_OK) return rc; } - } while ((form = next) != NULL); /* continue */ + } while((form = next) != NULL); /* continue */ return CURLE_OK; } #endif /* CURL_DOES_CONVERSIONS */ @@ -944,11 +944,11 @@ int curl_formget(struct curl_httppost *form, void *arg, struct FormData *data, *ptr; rc = Curl_getFormData(&data, form, NULL, &size); - if (rc != CURLE_OK) + if(rc != CURLE_OK) return (int)rc; for (ptr = data; ptr; ptr = ptr->next) { - if (ptr->type == FORM_FILE) { + if(ptr->type == FORM_FILE) { char buffer[8192]; size_t nread; struct Form temp; @@ -957,16 +957,16 @@ int curl_formget(struct curl_httppost *form, void *arg, do { nread = readfromfile(&temp, buffer, sizeof(buffer)); - if ((nread == (size_t) -1) || (nread != append(arg, buffer, nread))) { - if (temp.fp) { + if((nread == (size_t) -1) || (nread != append(arg, buffer, nread))) { + if(temp.fp) { fclose(temp.fp); } Curl_formclean(&data); return -1; } - } while (nread == sizeof(buffer)); + } while(nread == sizeof(buffer)); } else { - if (ptr->length != append(arg, ptr->line, ptr->length)) { + if(ptr->length != append(arg, ptr->line, ptr->length)) { Curl_formclean(&data); return -1; } @@ -1005,7 +1005,7 @@ void curl_formfree(struct curl_httppost *form) free(form->showfilename); /* free the faked file name */ free(form); /* free the struct */ - } while ((form = next) != NULL); /* continue */ + } while((form = next) != NULL); /* continue */ } #ifndef HAVE_BASENAME @@ -1110,7 +1110,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, "Content-Type: multipart/form-data", boundary); - if (result) { + if(result) { free(boundary); return result; } @@ -1123,13 +1123,13 @@ CURLcode Curl_getFormData(struct FormData **finalform, if(size) { result = AddFormDataf(&form, &size, "\r\n"); - if (result) + if(result) break; } /* boundary */ result = AddFormDataf(&form, &size, "--%s\r\n", boundary); - if (result) + if(result) break; /* Maybe later this should be disabled when a custom_content_type is @@ -1138,16 +1138,16 @@ CURLcode Curl_getFormData(struct FormData **finalform, */ result = AddFormDataf(&form, &size, "Content-Disposition: form-data; name=\""); - if (result) + if(result) break; result = AddFormData(&form, FORM_DATA, post->name, post->namelength, &size); - if (result) + if(result) break; result = AddFormDataf(&form, &size, "\""); - if (result) + if(result) break; if(post->more) { @@ -1160,7 +1160,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, "\r\nContent-Type: multipart/mixed," " boundary=%s\r\n", fileboundary); - if (result) + if(result) break; } @@ -1183,9 +1183,9 @@ CURLcode Curl_getFormData(struct FormData **finalform, fileboundary, (file->showfilename?file->showfilename: filebasename)); - if (filebasename) + if(filebasename) free(filebasename); - if (result) + if(result) break; } else if((post->flags & HTTPPOST_FILENAME) || @@ -1198,10 +1198,10 @@ CURLcode Curl_getFormData(struct FormData **finalform, "; filename=\"%s\"", (post->showfilename?post->showfilename: filebasename)); - if (filebasename) + if(filebasename) free(filebasename); - if (result) + if(result) break; } @@ -1210,7 +1210,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, result = AddFormDataf(&form, &size, "\r\nContent-Type: %s", file->contenttype); - if (result) + if(result) break; } @@ -1218,11 +1218,11 @@ CURLcode Curl_getFormData(struct FormData **finalform, while( curList ) { /* Process the additional headers specified for this form */ result = AddFormDataf( &form, &size, "\r\n%s", curList->data ); - if (result) + if(result) break; curList = curList->next; } - if (result) { + if(result) { Curl_formclean(&firstform); free(boundary); return result; @@ -1240,13 +1240,13 @@ CURLcode Curl_getFormData(struct FormData **finalform, /* this is not a text content, mention our binary encoding */ result = AddFormDataf(&form, &size, "\r\nContent-Transfer-Encoding: binary"); - if (result) + if(result) break; } #endif result = AddFormDataf(&form, &size, "\r\n\r\n"); - if (result) + if(result) break; if((post->flags & HTTPPOST_FILENAME) || @@ -1278,14 +1278,14 @@ CURLcode Curl_getFormData(struct FormData **finalform, */ size_t nread; char buffer[512]; - while ((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) { + while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) { result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size); - if (result) + if(result) break; } } - if (result) { + if(result) { Curl_formclean(&firstform); free(boundary); return result; @@ -1305,11 +1305,11 @@ CURLcode Curl_getFormData(struct FormData **finalform, } } - else if (post->flags & HTTPPOST_BUFFER) { + else if(post->flags & HTTPPOST_BUFFER) { /* include contents of buffer */ result = AddFormData(&form, FORM_CONTENT, post->buffer, post->bufferlength, &size); - if (result) + if(result) break; } @@ -1317,11 +1317,11 @@ CURLcode Curl_getFormData(struct FormData **finalform, /* include the contents we got */ result = AddFormData(&form, FORM_CONTENT, post->contents, post->contentslength, &size); - if (result) + if(result) break; } - } while ((file = file->more) != NULL); /* for each specified file for this field */ - if (result) { + } while((file = file->more) != NULL); /* for each specified file for this field */ + if(result) { Curl_formclean(&firstform); free(boundary); return result; @@ -1334,12 +1334,12 @@ CURLcode Curl_getFormData(struct FormData **finalform, "\r\n--%s--", fileboundary); free(fileboundary); - if (result) + if(result) break; } - } while ((post = post->next) != NULL); /* for each field */ - if (result) { + } while((post = post->next) != NULL); /* for each field */ + if(result) { Curl_formclean(&firstform); free(boundary); return result; @@ -1349,7 +1349,7 @@ CURLcode Curl_getFormData(struct FormData **finalform, result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary); - if (result) { + if(result) { Curl_formclean(&firstform); free(boundary); return result; @@ -1488,7 +1488,7 @@ int FormAddTest(const char * errormsg, int result; va_list arg; va_start(arg, last_post); - if ((result = FormAdd(httppost, last_post, arg))) + if((result = FormAdd(httppost, last_post, arg))) fprintf (stderr, "ERROR doing FormAdd ret: %d action: %s\n", result, errormsg); va_end(arg); @@ -1539,11 +1539,11 @@ int main(int argc, argv_item_t argv[]) (void) argc; (void) argv; - if (FormAddTest("simple COPYCONTENTS test", &httppost, &last_post, + if(FormAddTest("simple COPYCONTENTS test", &httppost, &last_post, CURLFORM_COPYNAME, name1, CURLFORM_COPYCONTENTS, value1, CURLFORM_END)) ++errors; - if (FormAddTest("COPYCONTENTS + CONTENTTYPE test", &httppost, &last_post, + if(FormAddTest("COPYCONTENTS + CONTENTTYPE test", &httppost, &last_post, CURLFORM_COPYNAME, name2, CURLFORM_COPYCONTENTS, value2, CURLFORM_CONTENTTYPE, type2, CURLFORM_END)) ++errors; @@ -1551,41 +1551,41 @@ int main(int argc, argv_item_t argv[]) correctly */ name3[1] = '\0'; value3[1] = '\0'; - if (FormAddTest("PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH test", + if(FormAddTest("PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH test", &httppost, &last_post, CURLFORM_PTRNAME, name3, CURLFORM_COPYCONTENTS, value3, CURLFORM_CONTENTSLENGTH, value3length, CURLFORM_NAMELENGTH, name3length, CURLFORM_END)) ++errors; - if (FormAddTest("simple PTRCONTENTS test", &httppost, &last_post, + if(FormAddTest("simple PTRCONTENTS test", &httppost, &last_post, CURLFORM_COPYNAME, name4, CURLFORM_PTRCONTENTS, value4, CURLFORM_END)) ++errors; /* make null character at start to check that contentslength works correctly */ value5[1] = '\0'; - if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH test", &httppost, &last_post, + if(FormAddTest("PTRCONTENTS + CONTENTSLENGTH test", &httppost, &last_post, CURLFORM_COPYNAME, name5, CURLFORM_PTRCONTENTS, value5, CURLFORM_CONTENTSLENGTH, value5length, CURLFORM_END)) ++errors; /* make null character at start to check that contentslength works correctly */ value6[1] = '\0'; - if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE test", + if(FormAddTest("PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE test", &httppost, &last_post, CURLFORM_COPYNAME, name6, CURLFORM_PTRCONTENTS, value6, CURLFORM_CONTENTSLENGTH, value6length, CURLFORM_CONTENTTYPE, type6, CURLFORM_END)) ++errors; - if (FormAddTest("FILE + CONTENTTYPE test", &httppost, &last_post, + if(FormAddTest("FILE + CONTENTTYPE test", &httppost, &last_post, CURLFORM_COPYNAME, name7, CURLFORM_FILE, value7, CURLFORM_CONTENTTYPE, type7, CURLFORM_END)) ++errors; - if (FormAddTest("FILE1 + FILE2 test", &httppost, &last_post, + if(FormAddTest("FILE1 + FILE2 test", &httppost, &last_post, CURLFORM_COPYNAME, name8, CURLFORM_FILE, value7, CURLFORM_FILE, value8, CURLFORM_END)) ++errors; - if (FormAddTest("FILE1 + FILE2 + FILE3 test", &httppost, &last_post, + if(FormAddTest("FILE1 + FILE2 + FILE3 test", &httppost, &last_post, CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7, CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END)) ++errors; @@ -1596,11 +1596,11 @@ int main(int argc, argv_item_t argv[]) forms[2].option = CURLFORM_FILE; forms[2].value = value7; forms[3].option = CURLFORM_END; - if (FormAddTest("FILE1 + FILE2 + FILE3 ARRAY test", &httppost, &last_post, + if(FormAddTest("FILE1 + FILE2 + FILE3 ARRAY test", &httppost, &last_post, CURLFORM_COPYNAME, name10, CURLFORM_ARRAY, forms, CURLFORM_END)) ++errors; - if (FormAddTest("FILECONTENT test", &httppost, &last_post, + if(FormAddTest("FILECONTENT test", &httppost, &last_post, CURLFORM_COPYNAME, name11, CURLFORM_FILECONTENT, value7, CURLFORM_END)) ++errors; @@ -1628,7 +1628,7 @@ int main(int argc, argv_item_t argv[]) fprintf(stdout, "size: "); fprintf(stdout, CURL_FORMAT_OFF_T, size); fprintf(stdout, "\n"); - if (errors) + if(errors) fprintf(stdout, "\n==> %d Test(s) failed!\n", errors); else fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n"); -- cgit v1.2.1 From a2314225e02ea2f3bd49dc8557f2452846e49b19 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 31 Mar 2008 10:02:23 +0000 Subject: - Added CURLFORM_STREAM as a supported option to curl_formadd() to allow an application to provide data for a multipart with the read callback. Note that the size needs to be provided with CURLFORM_CONTENTSLENGTH when the stream option is used. This feature is verified by the new test case 554. This feature was sponsored by Xponaut. --- lib/formdata.c | 156 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 54 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index d80dc3d14..420f85f17 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2008, 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 @@ -159,13 +159,13 @@ static size_t readfromfile(struct Form *form, char *buffer, size_t size); * ***************************************************************************/ static struct curl_httppost * -AddHttpPost(char * name, size_t namelength, - char * value, size_t contentslength, - char * buffer, size_t bufferlength, +AddHttpPost(char *name, size_t namelength, + char *value, size_t contentslength, + char *buffer, size_t bufferlength, char *contenttype, long flags, struct curl_slist* contentHeader, - char *showfilename, + char *showfilename, char *userp, struct curl_httppost *parent_post, struct curl_httppost **httppost, struct curl_httppost **last_post) @@ -182,6 +182,7 @@ AddHttpPost(char * name, size_t namelength, post->contenttype = contenttype; post->contentheader = contentHeader; post->showfilename = showfilename; + post->userp = userp, post->flags = flags; } else @@ -597,7 +598,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } case CURLFORM_BUFFERPTR: - current_form->flags |= HTTPPOST_PTRBUFFER; + current_form->flags |= HTTPPOST_PTRBUFFER; if(current_form->buffer) return_value = CURL_FORMADD_OPTION_TWICE; else { @@ -618,6 +619,25 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, array_state?(size_t)array_value:(size_t)va_arg(params, long); break; + case CURLFORM_STREAM: + current_form->flags |= HTTPPOST_CALLBACK; + if(current_form->userp) + return_value = CURL_FORMADD_OPTION_TWICE; + else { + char *userp = + array_state?array_value:va_arg(params, char *); + if(userp) { + current_form->userp = userp; + current_form->value = userp; /* this isn't strictly true but we + derive a value from this later on + and we need this non-NULL to be + accepted as a fine form part */ + } + else + return_value = CURL_FORMADD_NULL; + } + break; + case CURLFORM_CONTENTTYPE: { const char *contenttype = @@ -693,18 +713,18 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, form != NULL; form = form->more) { if( ((!form->name || !form->value) && !post) || - ( (form->contentslength) && - (form->flags & HTTPPOST_FILENAME) ) || - ( (form->flags & HTTPPOST_FILENAME) && - (form->flags & HTTPPOST_PTRCONTENTS) ) || - - ( (!form->buffer) && - (form->flags & HTTPPOST_BUFFER) && - (form->flags & HTTPPOST_PTRBUFFER) ) || - - ( (form->flags & HTTPPOST_READFILE) && - (form->flags & HTTPPOST_PTRCONTENTS) ) - ) { + ( (form->contentslength) && + (form->flags & HTTPPOST_FILENAME) ) || + ( (form->flags & HTTPPOST_FILENAME) && + (form->flags & HTTPPOST_PTRCONTENTS) ) || + + ( (!form->buffer) && + (form->flags & HTTPPOST_BUFFER) && + (form->flags & HTTPPOST_PTRBUFFER) ) || + + ( (form->flags & HTTPPOST_READFILE) && + (form->flags & HTTPPOST_PTRCONTENTS) ) + ) { return_value = CURL_FORMADD_INCOMPLETE; break; } @@ -731,10 +751,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } form->name_alloc = TRUE; } - if( !(form->flags & HTTPPOST_FILENAME) && - !(form->flags & HTTPPOST_READFILE) && - !(form->flags & HTTPPOST_PTRCONTENTS) && - !(form->flags & HTTPPOST_PTRBUFFER) ) { + if( !(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE | + HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER | + HTTPPOST_CALLBACK)) ) { /* copy value (without strdup; possibly contains null characters) */ form->value = memdup(form->value, form->contentslength); if(!form->value) { @@ -748,6 +767,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, form->buffer, form->bufferlength, form->contenttype, form->flags, form->contentheader, form->showfilename, + form->userp, post, httppost, last_post); @@ -824,18 +844,25 @@ static CURLcode AddFormData(struct FormData **formp, return CURLE_OUT_OF_MEMORY; newform->next = NULL; - /* we make it easier for plain strings: */ - if(!length) - length = strlen((char *)line); + if(type <= FORM_CONTENT) { + /* we make it easier for plain strings: */ + if(!length) + length = strlen((char *)line); - newform->line = (char *)malloc(length+1); - if(!newform->line) { - free(newform); - return CURLE_OUT_OF_MEMORY; + newform->line = (char *)malloc(length+1); + if(!newform->line) { + free(newform); + return CURLE_OUT_OF_MEMORY; + } + memcpy(newform->line, line, length); + newform->length = length; + newform->line[length]=0; /* zero terminate for easier debugging */ } - memcpy(newform->line, line, length); - newform->length = length; - newform->line[length]=0; /* zero terminate for easier debugging */ + else + /* For callbacks and files we don't have any actual data so we just keep a + pointer to whatever this points to */ + newform->line = (char *)line; + newform->type = type; if(*formp) { @@ -846,7 +873,9 @@ static CURLcode AddFormData(struct FormData **formp, *formp = newform; if(size) { - if((type == FORM_DATA) || (type == FORM_CONTENT)) + if(type != FORM_FILE) + /* for static content as well as callback data we add the size given + as input argument */ *size += length; else { /* Since this is a file to be uploaded here, add the size of the actual @@ -893,7 +922,8 @@ void Curl_formclean(struct FormData **form_ptr) do { next=form->next; /* the following form line */ - free(form->line); /* free the line */ + if(form->type <= FORM_CONTENT) + free(form->line); /* free the line */ free(form); /* free the struct */ } while((form = next) != NULL); /* continue */ @@ -997,7 +1027,8 @@ void curl_formfree(struct curl_httppost *form) if( !(form->flags & HTTPPOST_PTRNAME) && form->name) free(form->name); /* free the name */ - if( !(form->flags & HTTPPOST_PTRCONTENTS) && form->contents) + if( !(form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_CALLBACK)) && + form->contents) free(form->contents); /* free the contents */ if(form->contenttype) free(form->contenttype); /* free the content type */ @@ -1188,9 +1219,11 @@ CURLcode Curl_getFormData(struct FormData **finalform, if(result) break; } - else if((post->flags & HTTPPOST_FILENAME) || - (post->flags & HTTPPOST_BUFFER)) { - + else if(post->flags & (HTTPPOST_FILENAME|HTTPPOST_BUFFER| + HTTPPOST_CALLBACK)) { + /* it should be noted that for the HTTPPOST_FILENAME and + HTTPPOST_CALLBACK cases the ->showfilename struct member is always + assigned at this point */ char *filebasename= (!post->showfilename)?strippath(post->contents):NULL; @@ -1312,7 +1345,14 @@ CURLcode Curl_getFormData(struct FormData **finalform, if(result) break; } - + else if(post->flags & HTTPPOST_CALLBACK) { + /* the contents should be read with the callback and the size + is set with the contentslength */ + result = AddFormData(&form, FORM_CALLBACK, post->userp, + post->contentslength, &size); + if(result) + break; + } else { /* include the contents we got */ result = AddFormData(&form, FORM_CONTENT, post->contents, @@ -1380,21 +1420,29 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata ) return 0; } -static size_t readfromfile(struct Form *form, char *buffer, size_t size) +static size_t readfromfile(struct Form *form, char *buffer, + size_t size) { size_t nread; - if(!form->fp) { - /* this file hasn't yet been opened */ - form->fp = fopen(form->data->line, "rb"); /* b is for binary */ - if(!form->fp) - return (size_t)-1; /* failure */ - } - nread = fread(buffer, 1, size, form->fp); + bool callback = (bool)(form->data->type == FORM_CALLBACK); - if(nread != size) { + if(callback) + nread = form->fread_func(buffer, 1, size, form->data->line); + else { + if(!form->fp) { + /* this file hasn't yet been opened */ + form->fp = fopen(form->data->line, "rb"); /* b is for binary */ + if(!form->fp) + return (size_t)-1; /* failure */ + } + nread = fread(buffer, 1, size, form->fp); + } + if(!nread || nread > size) { /* this is the last chunk from the file, move on */ - fclose(form->fp); - form->fp = NULL; + if(!callback) { + fclose(form->fp); + form->fp = NULL; + } form->data = form->data->next; } @@ -1421,7 +1469,8 @@ size_t Curl_FormReader(char *buffer, if(!form->data) return 0; /* nothing, error, empty */ - if(form->data->type == FORM_FILE) { + if((form->data->type == FORM_FILE) || + (form->data->type == FORM_CALLBACK)) { gotsize = readfromfile(form, buffer, wantedsize); if(gotsize) @@ -1449,10 +1498,9 @@ size_t Curl_FormReader(char *buffer, form->data = form->data->next; /* advance */ - } while(form->data && (form->data->type != FORM_FILE)); + } while(form->data && (form->data->type < FORM_CALLBACK)); /* If we got an empty line and we have more data, we proceed to the next - line immediately to avoid returning zero before we've reached the end. - This is the bug reported November 22 1999 on curl 6.3. (Daniel) */ + line immediately to avoid returning zero before we've reached the end. */ return gotsize; } -- cgit v1.2.1 From 60f0b4fffe3de8eb1a1fc3015c2f6643fdccb57a Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 8 Jul 2008 21:16:18 +0000 Subject: Fixed test 554 to pass the torture test. --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 420f85f17..bf00a40ac 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -705,7 +705,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } if(CURL_FORMADD_OK == return_value) { - /* go through the list, check for copleteness 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 */ post = NULL; -- cgit v1.2.1 From 66fb9ca5f6de6eb74c2c3ade7ee651a299247749 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 15 Aug 2008 02:58:15 +0000 Subject: For congruency sake with the naming of other CURL_XXXXXX_CURL_OFF_T macros, the names of the curl_off_t formatting string directives now become CURL_FORMAT_CURL_OFF_T and CURL_FORMAT_CURL_OFF_TU. CURL_FMT_OFF_T -> CURL_FORMAT_CURL_OFF_T CURL_FMT_OFF_TU -> CURL_FORMAT_CURL_OFF_TU Remove the use of an internal name for the curl_off_t formatting string directives and use the common one available from the inside and outside of the library. FORMAT_OFF_T -> CURL_FORMAT_CURL_OFF_T FORMAT_OFF_TU -> CURL_FORMAT_CURL_OFF_TU --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index bf00a40ac..637e37ed4 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1674,7 +1674,7 @@ int main(int argc, argv_item_t argv[]) } while(1); fprintf(stdout, "size: "); - fprintf(stdout, CURL_FORMAT_OFF_T, size); + fprintf(stdout, "%" CURL_FORMAT_CURL_OFF_T, size); fprintf(stdout, "\n"); if(errors) fprintf(stdout, "\n==> %d Test(s) failed!\n", errors); -- cgit v1.2.1 From ad638da2c29a61babb50fdced0333393416a199a Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 16 Aug 2008 01:33:59 +0000 Subject: Library internal only C preprocessor macros FORMAT_OFF_T and FORMAT_OFF_TU remain in use as internal curl_off_t print formatting strings for the internal *printf functions which still cannot handle print formatting string directives such as "I64d", "I64u", and others available on MSVC, MinGW, Intel's ICC, and other DOS/Windows compilers. This reverts previous commit part which did: FORMAT_OFF_T -> CURL_FORMAT_CURL_OFF_T FORMAT_OFF_TU -> CURL_FORMAT_CURL_OFF_TU --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 637e37ed4..c5b305a59 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1674,7 +1674,7 @@ int main(int argc, argv_item_t argv[]) } while(1); fprintf(stdout, "size: "); - fprintf(stdout, "%" CURL_FORMAT_CURL_OFF_T, size); + fprintf(stdout, "%" FORMAT_OFF_T, size); fprintf(stdout, "\n"); if(errors) fprintf(stdout, "\n==> %d Test(s) failed!\n", errors); -- cgit v1.2.1 From 934708d950617688c7d294ea1ab583667f383ab1 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 2 Sep 2008 17:41:20 +0000 Subject: Made some variables const which eliminated some casts --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index c5b305a59..54eabb2f8 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -325,7 +325,7 @@ static char *memdup(const char *src, size_t buffer_length) } else /* no length and a NULL src pointer! */ - return strdup((char *)""); + return strdup(""); buffer = (char*)malloc(length+add); if(!buffer) -- cgit v1.2.1 From a622fd90b4c563a4fced20c5b88cb57537e809b0 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 6 Sep 2008 04:47:14 +0000 Subject: remove unnecessary typecasting of calloc() --- lib/formdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 54eabb2f8..2ab1d1af1 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -171,7 +171,7 @@ AddHttpPost(char *name, size_t namelength, struct curl_httppost **last_post) { struct curl_httppost *post; - post = (struct curl_httppost *)calloc(sizeof(struct curl_httppost), 1); + post = calloc(sizeof(struct curl_httppost), 1); if(post) { post->name = name; post->namelength = (long)(name?(namelength?namelength:strlen(name)):0); @@ -410,7 +410,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, /* * We need to allocate the first struct to fill in. */ - first_form = (FormInfo *)calloc(sizeof(struct FormInfo), 1); + first_form = calloc(sizeof(struct FormInfo), 1); if(!first_form) return CURL_FORMADD_MEMORY; -- cgit v1.2.1 From 59e378f48fed849e8e41f0bc6a10bf7a1732ae8a Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 6 Sep 2008 05:29:05 +0000 Subject: remove unnecessary typecasting of malloc() --- lib/formdata.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 2ab1d1af1..e017cb7f3 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -222,7 +222,7 @@ static FormInfo * AddFormInfo(char *value, FormInfo *parent_form_info) { FormInfo *form_info; - form_info = (FormInfo *)malloc(sizeof(FormInfo)); + form_info = malloc(sizeof(FormInfo)); if(form_info) { memset(form_info, 0, sizeof(FormInfo)); if(value) @@ -327,7 +327,7 @@ static char *memdup(const char *src, size_t buffer_length) /* no length and a NULL src pointer! */ return strdup(""); - buffer = (char*)malloc(length+add); + buffer = malloc(length+add); if(!buffer) return NULL; /* fail */ @@ -838,8 +838,7 @@ static CURLcode AddFormData(struct FormData **formp, size_t length, curl_off_t *size) { - struct FormData *newform = (struct FormData *) - malloc(sizeof(struct FormData)); + struct FormData *newform = malloc(sizeof(struct FormData)); if(!newform) return CURLE_OUT_OF_MEMORY; newform->next = NULL; @@ -849,7 +848,7 @@ static CURLcode AddFormData(struct FormData **formp, if(!length) length = strlen((char *)line); - newform->line = (char *)malloc(length+1); + newform->line = malloc(length+1); if(!newform->line) { free(newform); return CURLE_OUT_OF_MEMORY; @@ -1729,7 +1728,7 @@ char *Curl_FormBoundary(void) static const char table16[]="abcdef0123456789"; - retstring = (char *)malloc(BOUNDARY_LENGTH+1); + retstring = malloc(BOUNDARY_LENGTH+1); if(!retstring) return NULL; /* failed */ -- cgit v1.2.1 From 4e909ee8b1e7e9f174af629615224180568a7e92 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 24 Sep 2008 12:22:16 +0000 Subject: ntoa() and inet_ntoa_r() no longer used --- lib/formdata.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index e017cb7f3..62409ec41 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -56,14 +56,14 @@ Content-Type: application/octet-stream vlue for PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE (or you might see v^@lue at the start) -Content-Disposition: form-data; name="FILE1_+_CONTENTTYPE"; filename="inet_ntoa_r.h" +Content-Disposition: form-data; name="FILE1_+_CONTENTTYPE"; filename="formdata.h" Content-Type: text/html ... Content-Disposition: form-data; name="FILE1_+_FILE2" Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz ... -Content-Disposition: attachment; filename="inet_ntoa_r.h" +Content-Disposition: attachment; filename="formdata.h" Content-Type: application/octet-stream ... Content-Disposition: attachment; filename="Makefile.b32" @@ -73,13 +73,13 @@ Content-Type: application/octet-stream Content-Disposition: form-data; name="FILE1_+_FILE2_+_FILE3" Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 ... -Content-Disposition: attachment; filename="inet_ntoa_r.h" +Content-Disposition: attachment; filename="formdata.h" Content-Type: application/octet-stream ... Content-Disposition: attachment; filename="Makefile.b32" Content-Type: application/octet-stream ... -Content-Disposition: attachment; filename="inet_ntoa_r.h" +Content-Disposition: attachment; filename="formdata.h" Content-Type: application/octet-stream ... @@ -87,13 +87,13 @@ Content-Type: application/octet-stream Content-Disposition: form-data; name="ARRAY: FILE1_+_FILE2_+_FILE3" Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 ... -Content-Disposition: attachment; filename="inet_ntoa_r.h" +Content-Disposition: attachment; filename="formdata.h" Content-Type: application/octet-stream ... Content-Disposition: attachment; filename="Makefile.b32" Content-Type: application/octet-stream ... -Content-Disposition: attachment; filename="inet_ntoa_r.h" +Content-Disposition: attachment; filename="formdata.h" Content-Type: application/octet-stream ... @@ -1562,7 +1562,7 @@ int main(int argc, argv_item_t argv[]) char value4[] = "value for simple PTRCONTENTS"; char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH"; char value6[] = "value for PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE"; - char value7[] = "inet_ntoa_r.h"; + char value7[] = "formdata.h"; char value8[] = "Makefile.b32"; char type2[] = "image/gif"; char type6[] = "text/plain"; -- cgit v1.2.1 From 0bb91218c51e7ae04975b9993ec0a5e67da75137 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 20 Oct 2008 21:56:35 +0000 Subject: added a NULL pointer check for the name field as it can in fact be NULL when dereferenced here, if the app passes in a funny combo. Detected by coverity.com --- lib/formdata.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 62409ec41..e035271b3 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -743,8 +743,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } if( !(form->flags & HTTPPOST_PTRNAME) && (form == first_form) ) { - /* copy name (without strdup; possibly contains null characters) */ - form->name = memdup(form->name, form->namelength); + /* Note that there's small risk that form->name is NULL here if the + app passed in a bad combo, so we better check for that first. */ + if(form->name) + /* copy name (without strdup; possibly contains null characters) */ + form->name = memdup(form->name, form->namelength); if(!form->name) { return_value = CURL_FORMADD_MEMORY; break; -- cgit v1.2.1 From 2249c12a3c2737e50d81962040dd36990aa16600 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 14 Nov 2008 16:26:39 +0000 Subject: fix an OOM problem detected by Jim Meyering --- lib/formdata.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index e035271b3..a370e65a4 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1100,7 +1100,7 @@ static char *strippath(const char *fullfile) free(filename); /* free temporary buffer */ - return base; /* returns an allocated string! */ + return base; /* returns an allocated string or NULL ! */ } /* @@ -1207,8 +1207,12 @@ CURLcode Curl_getFormData(struct FormData **finalform, if(post->more) { /* if multiple-file */ - char *filebasename= - (!file->showfilename)?strippath(file->contents):NULL; + char *filebasename= NULL; + if(!file->showfilename) { + filebasename = strippath(file->contents); + if(!filebasename) + return CURLE_OUT_OF_MEMORY; + } result = AddFormDataf(&form, &size, "\r\n--%s\r\nContent-Disposition: " -- cgit v1.2.1 From 9b033e1b8a9eb81ff9468faa0e4839187ecdc568 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 14 Nov 2008 19:22:40 +0000 Subject: Added .xml as one of the few common file extensions known by the multipart form generator. Made the extensions part of the MIME type struct to reduce the size and run-time relocations necessary to build the table. --- lib/formdata.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index a370e65a4..483c9f82e 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -267,7 +267,7 @@ static const char * ContentTypeForFilename (const char *filename, * extensions and pick the first we match! */ struct ContentType { - const char *extension; + char extension[6]; const char *type; }; static const struct ContentType ctts[]={ @@ -275,7 +275,8 @@ static const char * ContentTypeForFilename (const char *filename, {".jpg", "image/jpeg"}, {".jpeg", "image/jpeg"}, {".txt", "text/plain"}, - {".html", "text/html"} + {".html", "text/html"}, + {".xml", "application/xml"} }; if(prevtype) @@ -1733,7 +1734,7 @@ char *Curl_FormBoundary(void) the same form won't be identical */ size_t i; - static const char table16[]="abcdef0123456789"; + static const char table16[]="0123456789abcdef"; retstring = malloc(BOUNDARY_LENGTH+1); -- cgit v1.2.1 From a028c69f48bb74e435d9313e152ce0b42ee351a8 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 18 Nov 2008 19:58:44 +0000 Subject: Avoid creating garbage on an OOM error --- lib/formdata.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 483c9f82e..08ccf4db3 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1211,8 +1211,11 @@ CURLcode Curl_getFormData(struct FormData **finalform, char *filebasename= NULL; if(!file->showfilename) { filebasename = strippath(file->contents); - if(!filebasename) + if(!filebasename) { + Curl_formclean(&firstform); + free(boundary); return CURLE_OUT_OF_MEMORY; + } } result = AddFormDataf(&form, &size, -- cgit v1.2.1 From 2a868173497c0b7ae251537903ee9941dddebeba Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 20 Dec 2008 22:51:57 +0000 Subject: malloc+memset => calloc --- lib/formdata.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 08ccf4db3..10f2caeac 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -222,9 +222,8 @@ static FormInfo * AddFormInfo(char *value, FormInfo *parent_form_info) { FormInfo *form_info; - form_info = malloc(sizeof(FormInfo)); + form_info = calloc(sizeof(FormInfo), 1); if(form_info) { - memset(form_info, 0, sizeof(FormInfo)); if(value) form_info->value = value; if(contenttype) -- cgit v1.2.1 From 33a3753c3f41d546ebf3350685eb7201d25783f4 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 21 Apr 2009 11:46:16 +0000 Subject: libcurl's memory.h renamed to curl_memory.h --- lib/formdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 10f2caeac..aa644ecb2 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2009, 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 @@ -122,7 +122,7 @@ Content-Disposition: form-data; name="FILECONTENT" #include "easyif.h" /* for Curl_convert_... prototypes */ #include "formdata.h" #include "strequal.h" -#include "memory.h" +#include "curl_memory.h" #define _MPRINTF_REPLACE /* use our functions only */ #include -- cgit v1.2.1 From 16ae283fb46a852a70a4ef73bb3254239e59ea1e Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 9 Jun 2009 00:49:34 +0000 Subject: initialize fread callback pointer to avoid compiler warning --- lib/formdata.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index aa644ecb2..f2a4892bf 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1425,6 +1425,7 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata ) form->data = formdata; form->sent = 0; form->fp = NULL; + form->fread_func = ZERO_NULL; return 0; } -- cgit v1.2.1 From c32cf33a16d31eeff9a66a1e73ce58b6791dd54d Mon Sep 17 00:00:00 2001 From: Patrick Monnerat Date: Mon, 15 Jun 2009 10:15:28 +0000 Subject: Replaced use of standard C library rand()/srand() by our own pseudo-random number generator. --- lib/formdata.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index f2a4892bf..8538e9f91 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -108,6 +108,12 @@ Content-Disposition: form-data; name="FILECONTENT" /* Length of the random boundary string. */ #define BOUNDARY_LENGTH 40 +/* Private pseudo-random number seed. Unsigned integer >= 32bit. Threads + mutual exclusion is not implemented to acess it since we do not require + high quality random numbers (only used in form boudary generation). */ + +static unsigned int randseed; + #if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) #include @@ -1597,6 +1603,8 @@ int main(int argc, argv_item_t argv[]) (void) argc; (void) argv; + Curl_srand(); /* Because we do not call curl_global_init() here. */ + if(FormAddTest("simple COPYCONTENTS test", &httppost, &last_post, CURLFORM_COPYNAME, name1, CURLFORM_COPYCONTENTS, value1, CURLFORM_END)) @@ -1733,8 +1741,6 @@ void curl_formfree(struct curl_httppost *form) char *Curl_FormBoundary(void) { char *retstring; - static int randomizer; /* this is just so that two boundaries within - the same form won't be identical */ size_t i; static const char table16[]="0123456789abcdef"; @@ -1744,12 +1750,10 @@ char *Curl_FormBoundary(void) if(!retstring) return NULL; /* failed */ - srand((unsigned int)time(NULL)+randomizer++); /* seed */ - strcpy(retstring, "----------------------------"); for(i=strlen(retstring); i> 16) & 0xFFFF); +} + +void Curl_srand(void) +{ + /* Randomize pseudo-random number sequence. */ + + randseed = (unsigned int) time(NULL); + Curl_rand(); + Curl_rand(); + Curl_rand(); +} -- cgit v1.2.1 From f2f45339dc378ed4d15b19ebf8d16e9f58d776e8 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 17 Sep 2009 14:23:27 +0000 Subject: Moved Curl_rand() and Curl_srand() code from formdata.c and formdata.h into curl_rand.c and curl_rand.h --- lib/formdata.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 8538e9f91..ab5f99118 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -108,12 +108,6 @@ Content-Disposition: form-data; name="FILECONTENT" /* Length of the random boundary string. */ #define BOUNDARY_LENGTH 40 -/* Private pseudo-random number seed. Unsigned integer >= 32bit. Threads - mutual exclusion is not implemented to acess it since we do not require - high quality random numbers (only used in form boudary generation). */ - -static unsigned int randseed; - #if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) #include @@ -127,6 +121,7 @@ static unsigned int randseed; #include "urldata.h" /* for struct SessionHandle */ #include "easyif.h" /* for Curl_convert_... prototypes */ #include "formdata.h" +#include "curl_rand.h" #include "strequal.h" #include "curl_memory.h" @@ -1763,24 +1758,3 @@ char *Curl_FormBoundary(void) } #endif /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */ - -/* Pseudo-random number support. This is always enabled, since called from - curl_global_init(). */ - -unsigned int Curl_rand(void) -{ - unsigned int r; - /* Return an unsigned 32-bit pseudo-random number. */ - r = randseed = randseed * 1103515245 + 12345; - return (r << 16) | ((r >> 16) & 0xFFFF); -} - -void Curl_srand(void) -{ - /* Randomize pseudo-random number sequence. */ - - randseed = (unsigned int) time(NULL); - Curl_rand(); - Curl_rand(); - Curl_rand(); -} -- cgit v1.2.1 From 0077a6d51bf9cd9153cdf76cbb14a3cc72ad7e8e Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 8 Oct 2009 12:44:25 +0000 Subject: Attempt to silence bogus compiler warning: "Potential null pointer dereference" --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index ab5f99118..9b458c0e2 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -423,7 +423,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, while(return_value == CURL_FORMADD_OK) { /* first see if we have more parts of the array param */ - if( array_state ) { + if( array_state && forms ) { /* get the upcoming option from the given array */ option = forms->option; array_value = (char *)forms->value; -- cgit v1.2.1 From 6d4e6cc8137ff2ebdbaf055e39ce1263ad634191 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 18 Oct 2009 03:37:39 +0000 Subject: Check for basename() is now done the same as other function checks --- lib/formdata.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 9b458c0e2..f2d556ff2 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -135,9 +135,9 @@ Content-Disposition: form-data; name="FILECONTENT" #ifndef CURL_DISABLE_HTTP -#if defined(HAVE_BASENAME) && defined(NEED_BASENAME_PROTO) -/* This system has a basename() but no prototype for it! */ -char *basename(char *path); +#ifndef HAVE_BASENAME +static char *Curl_basename(char *path); +#define basename(x) Curl_basename((x)) #endif static size_t readfromfile(struct Form *form, char *buffer, size_t size); @@ -1067,7 +1067,7 @@ void curl_formfree(struct curl_httppost *form) required to be reentrant is not required to be thread-safe. */ -static char *basename(char *path) +static char *Curl_basename(char *path) { /* Ignore all the details above for now and make a quick and simple implementaion here */ -- cgit v1.2.1 From 59939313f8452a9d817c178425c2ba3b91798ea9 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 18 Nov 2009 10:33:54 +0000 Subject: Make usage of calloc()'s arguments consistent with rest of code base --- lib/formdata.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index f2d556ff2..98058a5fa 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -172,7 +172,7 @@ AddHttpPost(char *name, size_t namelength, struct curl_httppost **last_post) { struct curl_httppost *post; - post = calloc(sizeof(struct curl_httppost), 1); + post = calloc(1, sizeof(struct curl_httppost)); if(post) { post->name = name; post->namelength = (long)(name?(namelength?namelength:strlen(name)):0); @@ -223,7 +223,7 @@ static FormInfo * AddFormInfo(char *value, FormInfo *parent_form_info) { FormInfo *form_info; - form_info = calloc(sizeof(FormInfo), 1); + form_info = calloc(1, sizeof(struct FormInfo)); if(form_info) { if(value) form_info->value = value; @@ -411,7 +411,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, /* * We need to allocate the first struct to fill in. */ - first_form = calloc(sizeof(struct FormInfo), 1); + first_form = calloc(1, sizeof(struct FormInfo)); if(!first_form) return CURL_FORMADD_MEMORY; -- cgit v1.2.1 From 33ce0ec1f1951bc1a8f4d475381c1b7c95d4a03a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 22 Jan 2010 23:21:39 +0000 Subject: wrap long lines and do some indent policing --- lib/formdata.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 98058a5fa..025ff1274 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2010, 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 @@ -998,7 +998,8 @@ int curl_formget(struct curl_httppost *form, void *arg, return -1; } } while(nread == sizeof(buffer)); - } else { + } + else { if(ptr->length != append(arg, ptr->line, ptr->length)) { Curl_formclean(&data); return -1; -- cgit v1.2.1 From 2309b4e330b96bc2e1f8e36b6184015e59544037 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 Mar 2010 11:02:54 +0100 Subject: remove the CVSish $Id$ lines --- lib/formdata.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 025ff1274..c98246e20 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -18,7 +18,6 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id$ ***************************************************************************/ /* -- cgit v1.2.1 From e8c442952d53d493e347a784d53d602359b4331c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Oct 2010 14:57:43 +0200 Subject: formdata: provide error message When failing to build form post due to an error, the code now does a proper failf(). Previously libcurl would report an error like "failed creating formpost data" when a file wasn't possible to open which was not easy for users to figure out. I also lower cased a function name to be named more curl-style and removed some unnecessary code. --- lib/formdata.c | 72 +++++++++++++++++----------------------------------------- 1 file changed, 21 insertions(+), 51 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index c98246e20..07d7a6b42 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -123,6 +123,7 @@ Content-Disposition: form-data; name="FILECONTENT" #include "curl_rand.h" #include "strequal.h" #include "curl_memory.h" +#include "sendf.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -975,7 +976,7 @@ int curl_formget(struct curl_httppost *form, void *arg, curl_off_t size; struct FormData *data, *ptr; - rc = Curl_getFormData(&data, form, NULL, &size); + rc = Curl_getformdata(NULL, &data, form, NULL, &size); if(rc != CURLE_OK) return (int)rc; @@ -1105,15 +1106,20 @@ static char *strippath(const char *fullfile) } /* - * Curl_getFormData() converts a linked list of "meta data" into a complete + * Curl_getformdata() converts a linked list of "meta data" into a complete * (possibly huge) multipart formdata. The input list is in 'post', while the * output resulting linked lists gets stored in '*finalform'. *sizep will get * the total size of the whole POST. * A multipart/form_data content-type is built, unless a custom content-type * is passed in 'custom_content_type'. + * + * This function will not do a failf() for the potential memory failures but + * should for all other errors it spots. Just note that this function MAY get + * a NULL pointer in the 'data' argument. */ -CURLcode Curl_getFormData(struct FormData **finalform, +CURLcode Curl_getformdata(struct SessionHandle *data, + struct FormData **finalform, struct curl_httppost *post, const char *custom_content_type, curl_off_t *sizep) @@ -1271,23 +1277,6 @@ CURLcode Curl_getFormData(struct FormData **finalform, return result; } -#if 0 - /* The header Content-Transfer-Encoding: seems to confuse some receivers - * (like the built-in PHP engine). While I can't see any reason why it - * should, I can just as well skip this to the benefit of the users who - * are using such confused receivers. - */ - - if(file->contenttype && - !checkprefix("text/", file->contenttype)) { - /* this is not a text content, mention our binary encoding */ - result = AddFormDataf(&form, &size, - "\r\nContent-Transfer-Encoding: binary"); - if(result) - break; - } -#endif - result = AddFormDataf(&form, &size, "\r\n\r\n"); if(result) break; @@ -1327,50 +1316,31 @@ CURLcode Curl_getFormData(struct FormData **finalform, break; } } - - if(result) { - Curl_formclean(&firstform); - free(boundary); - return result; - } - } else { -#ifdef _FORM_DEBUG - fprintf(stderr, - "\n==> Curl_getFormData couldn't open/read \"%s\"\n", - file->contents); -#endif - Curl_formclean(&firstform); - free(boundary); + if(data) + failf(data, "couldn't open file \"%s\"\n", file->contents); *finalform = NULL; - return CURLE_READ_ERROR; + result = CURLE_READ_ERROR; } - } - else if(post->flags & HTTPPOST_BUFFER) { + else if(post->flags & HTTPPOST_BUFFER) /* include contents of buffer */ result = AddFormData(&form, FORM_CONTENT, post->buffer, post->bufferlength, &size); - if(result) - break; - } - else if(post->flags & HTTPPOST_CALLBACK) { + else if(post->flags & HTTPPOST_CALLBACK) /* the contents should be read with the callback and the size is set with the contentslength */ result = AddFormData(&form, FORM_CALLBACK, post->userp, post->contentslength, &size); - if(result) - break; - } - else { + else /* include the contents we got */ result = AddFormData(&form, FORM_CONTENT, post->contents, post->contentslength, &size); - if(result) - break; - } - } while((file = file->more) != NULL); /* for each specified file for this field */ + + file = file->more; + } while(file && !result); /* for each specified file for this field */ + if(result) { Curl_formclean(&firstform); free(boundary); @@ -1666,11 +1636,11 @@ int main(int argc, argv_item_t argv[]) CURLFORM_END)) ++errors; - rc = Curl_getFormData(&form, httppost, NULL, &size); + rc = Curl_getformdata(NULL, &form, httppost, NULL, &size); if(rc != CURLE_OK) { if(rc != CURLE_READ_ERROR) { const char *errortext = curl_easy_strerror(rc); - fprintf(stdout, "\n==> Curl_getFormData error: %s\n", errortext); + fprintf(stdout, "\n==> Curl_getformdata error: %s\n", errortext); } return 0; } -- cgit v1.2.1 From dc3e7df1c99c2ee9dae06453adbb94fe9584bf75 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 8 Nov 2010 04:03:11 +0100 Subject: fix compiler warning --- lib/formdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 07d7a6b42..5ec3e384e 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1647,14 +1647,14 @@ int main(int argc, argv_item_t argv[]) Curl_FormInit(&formread, form); - do { + for(;;) { nread = Curl_FormReader(buffer, 1, sizeof(buffer), (FILE *)&formread); if(nread < 1) break; fwrite(buffer, nread, 1, stdout); - } while(1); + } fprintf(stdout, "size: "); fprintf(stdout, "%" FORMAT_OFF_T, size); -- cgit v1.2.1 From c828646f60b5bffb2bfcf924eba36da767bf08bf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Apr 2011 00:48:20 +0200 Subject: CURL_DOES_CONVERSIONS: cleanup Massively reduce #ifdefs all over (23 #ifdef lines less so far) Moved conversion-specific code to non-ascii.c --- lib/formdata.c | 39 +++++---------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 5ec3e384e..f221ae966 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2011, 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 @@ -118,7 +118,6 @@ Content-Disposition: form-data; name="FILECONTENT" #include #endif #include "urldata.h" /* for struct SessionHandle */ -#include "easyif.h" /* for Curl_convert_... prototypes */ #include "formdata.h" #include "curl_rand.h" #include "strequal.h" @@ -461,8 +460,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, */ case CURLFORM_PTRNAME: #ifdef CURL_DOES_CONVERSIONS - /* treat CURLFORM_PTR like CURLFORM_COPYNAME so we'll - have safe memory for the eventual conversion */ + /* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy + * the data in all cases so that we'll have safe memory for the eventual + * conversion. + */ #else current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ #endif @@ -934,36 +935,6 @@ void Curl_formclean(struct FormData **form_ptr) *form_ptr = NULL; } -#ifdef CURL_DOES_CONVERSIONS -/* - * Curl_formcovert() is used from http.c, this converts any - form items that need to be sent in the network encoding. - Returns CURLE_OK on success. - */ -CURLcode Curl_formconvert(struct SessionHandle *data, struct FormData *form) -{ - struct FormData *next; - CURLcode rc; - - if(!form) - return CURLE_OK; - - if(!data) - return CURLE_BAD_FUNCTION_ARGUMENT; - - do { - next=form->next; /* the following form line */ - if(form->type == FORM_DATA) { - rc = Curl_convert_to_network(data, form->line, form->length); - /* Curl_convert_to_network calls failf if unsuccessful */ - if(rc != CURLE_OK) - return rc; - } - } while((form = next) != NULL); /* continue */ - return CURLE_OK; -} -#endif /* CURL_DOES_CONVERSIONS */ - /* * curl_formget() * Serialize a curl_httppost struct. -- cgit v1.2.1 From b903186fa0189ff241d756d25d07fdfe9885ae49 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Apr 2011 15:17:42 +0200 Subject: source cleanup: unify look, style and indent levels By the use of a the new lib/checksrc.pl script that checks that our basic source style rules are followed. --- lib/formdata.c | 247 +-------------------------------------------------------- 1 file changed, 2 insertions(+), 245 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index f221ae966..a94dca521 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -20,87 +20,6 @@ * ***************************************************************************/ -/* - Debug the form generator stand-alone by compiling this source file with: - - gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -DCURLDEBUG -o formdata \ - -I../include formdata.c strequal.c memdebug.c mprintf.c strerror.c - - (depending on circumstances you may need further externals added) - - run the 'formdata' executable the output should end with: - All Tests seem to have worked ... - and the following parts should be there: - -Content-Disposition: form-data; name="simple_COPYCONTENTS" -value for simple COPYCONTENTS - -Content-Disposition: form-data; name="COPYCONTENTS_+_CONTENTTYPE" -Content-Type: image/gif -value for COPYCONTENTS + CONTENTTYPE - -Content-Disposition: form-data; name="PRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH" -vlue for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH -(or you might see P^@RNAME and v^@lue at the start) - -Content-Disposition: form-data; name="simple_PTRCONTENTS" -value for simple PTRCONTENTS - -Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH" -vlue for PTRCONTENTS + CONTENTSLENGTH -(or you might see v^@lue at the start) - -Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE" -Content-Type: application/octet-stream -vlue for PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE -(or you might see v^@lue at the start) - -Content-Disposition: form-data; name="FILE1_+_CONTENTTYPE"; filename="formdata.h" -Content-Type: text/html -... - -Content-Disposition: form-data; name="FILE1_+_FILE2" -Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz -... -Content-Disposition: attachment; filename="formdata.h" -Content-Type: application/octet-stream -... -Content-Disposition: attachment; filename="Makefile.b32" -Content-Type: application/octet-stream -... - -Content-Disposition: form-data; name="FILE1_+_FILE2_+_FILE3" -Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 -... -Content-Disposition: attachment; filename="formdata.h" -Content-Type: application/octet-stream -... -Content-Disposition: attachment; filename="Makefile.b32" -Content-Type: application/octet-stream -... -Content-Disposition: attachment; filename="formdata.h" -Content-Type: application/octet-stream -... - - -Content-Disposition: form-data; name="ARRAY: FILE1_+_FILE2_+_FILE3" -Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 -... -Content-Disposition: attachment; filename="formdata.h" -Content-Type: application/octet-stream -... -Content-Disposition: attachment; filename="Makefile.b32" -Content-Type: application/octet-stream -... -Content-Disposition: attachment; filename="formdata.h" -Content-Type: application/octet-stream -... - -Content-Disposition: form-data; name="FILECONTENT" -... - - */ - #include "setup.h" #include @@ -382,7 +301,7 @@ static char *memdup(const char *src, size_t buffer_length) * CURL_FORMADD_NULL if a null pointer was given for a char * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error) + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated * CURL_FORMADD_MEMORY if some allocation for string copying failed. * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array @@ -951,7 +870,7 @@ int curl_formget(struct curl_httppost *form, void *arg, if(rc != CURLE_OK) return (int)rc; - for (ptr = data; ptr; ptr = ptr->next) { + for(ptr = data; ptr; ptr = ptr->next) { if(ptr->type == FORM_FILE) { char buffer[8192]; size_t nread; @@ -1478,168 +1397,6 @@ char *Curl_formpostheader(void *formp, size_t *len) return header; } - -#ifdef _FORM_DEBUG -int FormAddTest(const char * errormsg, - struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...) -{ - int result; - va_list arg; - va_start(arg, last_post); - if((result = FormAdd(httppost, last_post, arg))) - fprintf (stderr, "ERROR doing FormAdd ret: %d action: %s\n", result, - errormsg); - va_end(arg); - return result; -} - - -int main(int argc, argv_item_t argv[]) -{ - char name1[] = "simple_COPYCONTENTS"; - char name2[] = "COPYCONTENTS_+_CONTENTTYPE"; - char name3[] = "PTRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH"; - char name4[] = "simple_PTRCONTENTS"; - char name5[] = "PTRCONTENTS_+_CONTENTSLENGTH"; - char name6[] = "PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE"; - char name7[] = "FILE1_+_CONTENTTYPE"; - char name8[] = "FILE1_+_FILE2"; - char name9[] = "FILE1_+_FILE2_+_FILE3"; - char name10[] = "ARRAY: FILE1_+_FILE2_+_FILE3"; - char name11[] = "FILECONTENT"; - char value1[] = "value for simple COPYCONTENTS"; - char value2[] = "value for COPYCONTENTS + CONTENTTYPE"; - char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH"; - char value4[] = "value for simple PTRCONTENTS"; - char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH"; - char value6[] = "value for PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE"; - char value7[] = "formdata.h"; - char value8[] = "Makefile.b32"; - char type2[] = "image/gif"; - char type6[] = "text/plain"; - char type7[] = "text/html"; - int name3length = strlen(name3); - int value3length = strlen(value3); - int value5length = strlen(value5); - int value6length = strlen(value6); - int errors = 0; - CURLcode rc; - curl_off_t size; - size_t nread; - char buffer[4096]; - struct curl_httppost *httppost=NULL; - struct curl_httppost *last_post=NULL; - struct curl_forms forms[4]; - - struct FormData *form; - struct Form formread; - - (void) argc; - (void) argv; - - Curl_srand(); /* Because we do not call curl_global_init() here. */ - - if(FormAddTest("simple COPYCONTENTS test", &httppost, &last_post, - CURLFORM_COPYNAME, name1, CURLFORM_COPYCONTENTS, value1, - CURLFORM_END)) - ++errors; - if(FormAddTest("COPYCONTENTS + CONTENTTYPE test", &httppost, &last_post, - CURLFORM_COPYNAME, name2, CURLFORM_COPYCONTENTS, value2, - CURLFORM_CONTENTTYPE, type2, CURLFORM_END)) - ++errors; - /* make null character at start to check that contentslength works - correctly */ - name3[1] = '\0'; - value3[1] = '\0'; - if(FormAddTest("PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH test", - &httppost, &last_post, - CURLFORM_PTRNAME, name3, CURLFORM_COPYCONTENTS, value3, - CURLFORM_CONTENTSLENGTH, value3length, - CURLFORM_NAMELENGTH, name3length, CURLFORM_END)) - ++errors; - if(FormAddTest("simple PTRCONTENTS test", &httppost, &last_post, - CURLFORM_COPYNAME, name4, CURLFORM_PTRCONTENTS, value4, - CURLFORM_END)) - ++errors; - /* make null character at start to check that contentslength works - correctly */ - value5[1] = '\0'; - if(FormAddTest("PTRCONTENTS + CONTENTSLENGTH test", &httppost, &last_post, - CURLFORM_COPYNAME, name5, CURLFORM_PTRCONTENTS, value5, - CURLFORM_CONTENTSLENGTH, value5length, CURLFORM_END)) - ++errors; - /* make null character at start to check that contentslength works - correctly */ - value6[1] = '\0'; - if(FormAddTest("PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE test", - &httppost, &last_post, - CURLFORM_COPYNAME, name6, CURLFORM_PTRCONTENTS, value6, - CURLFORM_CONTENTSLENGTH, value6length, - CURLFORM_CONTENTTYPE, type6, CURLFORM_END)) - ++errors; - if(FormAddTest("FILE + CONTENTTYPE test", &httppost, &last_post, - CURLFORM_COPYNAME, name7, CURLFORM_FILE, value7, - CURLFORM_CONTENTTYPE, type7, CURLFORM_END)) - ++errors; - if(FormAddTest("FILE1 + FILE2 test", &httppost, &last_post, - CURLFORM_COPYNAME, name8, CURLFORM_FILE, value7, - CURLFORM_FILE, value8, CURLFORM_END)) - ++errors; - if(FormAddTest("FILE1 + FILE2 + FILE3 test", &httppost, &last_post, - CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7, - CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END)) - ++errors; - forms[0].option = CURLFORM_FILE; - forms[0].value = value7; - forms[1].option = CURLFORM_FILE; - forms[1].value = value8; - forms[2].option = CURLFORM_FILE; - forms[2].value = value7; - forms[3].option = CURLFORM_END; - if(FormAddTest("FILE1 + FILE2 + FILE3 ARRAY test", &httppost, &last_post, - CURLFORM_COPYNAME, name10, CURLFORM_ARRAY, forms, - CURLFORM_END)) - ++errors; - if(FormAddTest("FILECONTENT test", &httppost, &last_post, - CURLFORM_COPYNAME, name11, CURLFORM_FILECONTENT, value7, - CURLFORM_END)) - ++errors; - - rc = Curl_getformdata(NULL, &form, httppost, NULL, &size); - if(rc != CURLE_OK) { - if(rc != CURLE_READ_ERROR) { - const char *errortext = curl_easy_strerror(rc); - fprintf(stdout, "\n==> Curl_getformdata error: %s\n", errortext); - } - return 0; - } - - Curl_FormInit(&formread, form); - - for(;;) { - nread = Curl_FormReader(buffer, 1, sizeof(buffer), - (FILE *)&formread); - - if(nread < 1) - break; - fwrite(buffer, nread, 1, stdout); - } - - fprintf(stdout, "size: "); - fprintf(stdout, "%" FORMAT_OFF_T, size); - fprintf(stdout, "\n"); - if(errors) - fprintf(stdout, "\n==> %d Test(s) failed!\n", errors); - else - fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n"); - - return 0; -} - -#endif /* _FORM_DEBUG */ - #else /* CURL_DISABLE_HTTP */ CURLFORMcode curl_formadd(struct curl_httppost **httppost, struct curl_httppost **last_post, -- cgit v1.2.1 From 889d1e973fb718a77c5000141d724ce03863af23 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 22 Apr 2011 23:01:30 +0200 Subject: whitespace cleanup: no space first in conditionals "if(a)" is our style, not "if( a )" --- lib/formdata.c | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index a94dca521..a7d2a5f7c 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -341,7 +341,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, while(return_value == CURL_FORMADD_OK) { /* first see if we have more parts of the array param */ - if( array_state && forms ) { + if(array_state && forms) { /* get the upcoming option from the given array */ option = forms->option; array_value = (char *)forms->value; @@ -598,7 +598,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, (struct curl_slist*)array_value: va_arg(params, struct curl_slist*); - if( current_form->contentheader ) + if(current_form->contentheader) return_value = CURL_FORMADD_OPTION_TWICE; else current_form->contentheader = list; @@ -609,7 +609,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, { const char *filename = array_state?array_value: va_arg(params, char *); - if( current_form->showfilename ) + if(current_form->showfilename) return_value = CURL_FORMADD_OPTION_TWICE; else { current_form->showfilename = strdup(filename); @@ -633,26 +633,26 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, for(form = first_form; form != NULL; form = form->more) { - if( ((!form->name || !form->value) && !post) || - ( (form->contentslength) && - (form->flags & HTTPPOST_FILENAME) ) || - ( (form->flags & HTTPPOST_FILENAME) && - (form->flags & HTTPPOST_PTRCONTENTS) ) || - - ( (!form->buffer) && - (form->flags & HTTPPOST_BUFFER) && - (form->flags & HTTPPOST_PTRBUFFER) ) || - - ( (form->flags & HTTPPOST_READFILE) && - (form->flags & HTTPPOST_PTRCONTENTS) ) + if(((!form->name || !form->value) && !post) || + ( (form->contentslength) && + (form->flags & HTTPPOST_FILENAME) ) || + ( (form->flags & HTTPPOST_FILENAME) && + (form->flags & HTTPPOST_PTRCONTENTS) ) || + + ( (!form->buffer) && + (form->flags & HTTPPOST_BUFFER) && + (form->flags & HTTPPOST_PTRBUFFER) ) || + + ( (form->flags & HTTPPOST_READFILE) && + (form->flags & HTTPPOST_PTRCONTENTS) ) ) { return_value = CURL_FORMADD_INCOMPLETE; break; } else { - if( ((form->flags & HTTPPOST_FILENAME) || - (form->flags & HTTPPOST_BUFFER)) && - !form->contenttype ) { + if(((form->flags & HTTPPOST_FILENAME) || + (form->flags & HTTPPOST_BUFFER)) && + !form->contenttype ) { /* our contenttype is missing */ form->contenttype = strdup(ContentTypeForFilename(form->value, prevtype)); @@ -662,8 +662,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } form->contenttype_alloc = TRUE; } - if( !(form->flags & HTTPPOST_PTRNAME) && - (form == first_form) ) { + if(!(form->flags & HTTPPOST_PTRNAME) && + (form == first_form) ) { /* Note that there's small risk that form->name is NULL here if the app passed in a bad combo, so we better check for that first. */ if(form->name) @@ -675,9 +675,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } form->name_alloc = TRUE; } - if( !(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE | - HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER | - HTTPPOST_CALLBACK)) ) { + if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE | + HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER | + HTTPPOST_CALLBACK)) ) { /* copy value (without strdup; possibly contains null characters) */ form->value = memdup(form->value, form->contentslength); if(!form->value) { @@ -919,10 +919,10 @@ void curl_formfree(struct curl_httppost *form) if(form->more) curl_formfree(form->more); - if( !(form->flags & HTTPPOST_PTRNAME) && form->name) + if(!(form->flags & HTTPPOST_PTRNAME) && form->name) free(form->name); /* free the name */ - if( !(form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_CALLBACK)) && - form->contents) + if(!(form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_CALLBACK)) && + form->contents) free(form->contents); /* free the contents */ if(form->contenttype) free(form->contenttype); /* free the content type */ @@ -1154,7 +1154,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, } curList = file->contentheader; - while( curList ) { + while(curList) { /* Process the additional headers specified for this form */ result = AddFormDataf( &form, &size, "\r\n%s", curList->data ); if(result) @@ -1350,7 +1350,7 @@ size_t Curl_FormReader(char *buffer, } do { - if( (form->data->length - form->sent ) > wantedsize - gotsize) { + if((form->data->length - form->sent ) > wantedsize - gotsize) { memcpy(buffer + gotsize , form->data->line + form->sent, wantedsize - gotsize); -- cgit v1.2.1 From 0f7bea7c3a6ddb0bf43f890c764322faaa3ba561 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 10 Jun 2011 14:40:46 +0200 Subject: unittest: mark all unit tested functions With "@unittest: [num]" in the header comment for each tested function. Shows we have a log way to go still... --- lib/formdata.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index a7d2a5f7c..df4094c33 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -737,6 +737,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, /* * curl_formadd() is a public API to add a section to the multipart formpost. + * + * @unittest: 1308 */ CURLFORMcode curl_formadd(struct curl_httppost **httppost, @@ -858,6 +860,8 @@ void Curl_formclean(struct FormData **form_ptr) * curl_formget() * Serialize a curl_httppost struct. * Returns 0 on success. + * + * @unittest: 1308 */ int curl_formget(struct curl_httppost *form, void *arg, curl_formget_callback append) -- cgit v1.2.1 From 85881f9f35832dbd4ef28940267f8fa30cbb867e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 13 Jun 2011 22:05:13 +0200 Subject: curl_formget: treat CURLFORM_STREAM better If a piece is set to use a callback to get the data, it should not be treated as data. It unfortunately also requires that curl_easy_perform() or similar has been used as otherwise the callback function hasn't been figured out and curl_formget won't know how to get the content. --- lib/formdata.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index df4094c33..49e795453 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -875,7 +875,7 @@ int curl_formget(struct curl_httppost *form, void *arg, return (int)rc; for(ptr = data; ptr; ptr = ptr->next) { - if(ptr->type == FORM_FILE) { + if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) { char buffer[8192]; size_t nread; struct Form temp; @@ -1301,8 +1301,12 @@ static size_t readfromfile(struct Form *form, char *buffer, size_t nread; bool callback = (bool)(form->data->type == FORM_CALLBACK); - if(callback) - nread = form->fread_func(buffer, 1, size, form->data->line); + if(callback) { + if(form->fread_func == ZERO_NULL) + return 0; + else + nread = form->fread_func(buffer, 1, size, form->data->line); + } else { if(!form->fp) { /* this file hasn't yet been opened */ -- cgit v1.2.1 From 0aedccc18a33a7785350d8d622ef273c727690cf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 13 Jun 2011 22:32:00 +0200 Subject: curl_formget: fix FILE * leak Properly deal with the fact that the last fread() call most probably is a short read, and when using callbacks in fact all calls can be short reads. No longer consider a file read done until it returns a 0 from the read function. Reported by: Aaron Orenstein Bug: http://curl.haxx.se/mail/lib-2011-06/0048.html --- lib/formdata.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 49e795453..5419371de 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -891,7 +891,7 @@ int curl_formget(struct curl_httppost *form, void *arg, Curl_formclean(&data); return -1; } - } while(nread == sizeof(buffer)); + } while(nread); } else { if(ptr->length != append(arg, ptr->line, ptr->length)) { @@ -1306,6 +1306,11 @@ static size_t readfromfile(struct Form *form, char *buffer, return 0; else nread = form->fread_func(buffer, 1, size, form->data->line); + + if(nread > size) + /* the read callback can return a value larger than the buffer but + treat any such as no data in this case */ + nread = 0; } else { if(!form->fp) { @@ -1316,9 +1321,9 @@ static size_t readfromfile(struct Form *form, char *buffer, } nread = fread(buffer, 1, size, form->fp); } - if(!nread || nread > size) { + if(!nread) { /* this is the last chunk from the file, move on */ - if(!callback) { + if(form->fp) { fclose(form->fp); form->fp = NULL; } -- cgit v1.2.1 From f851f768578dc096c561d57ba07ffd1004d504c0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 17 Jun 2011 22:21:36 +0200 Subject: CURLFORM_STREAM: acknowledge CURLFORM_FILENAME The CURLFORM_STREAM is documented to only insert a file name (and thus look like a file upload) in the part if CURLFORM_FILENAME is set, but in reality it always inserted a filename="" and if CURLFORM_FILENAME wasn't set, it would insert insert rubbish (or possibly crash). This is now fixed to work as documented, and test 554 has been extended to verify this. Reported by: Sascha Swiercy Bug: http://curl.haxx.se/mail/lib-2011-06/0070.html --- lib/formdata.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 5419371de..aa5a79ac1 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1134,15 +1134,17 @@ CURLcode Curl_getformdata(struct SessionHandle *data, /* it should be noted that for the HTTPPOST_FILENAME and HTTPPOST_CALLBACK cases the ->showfilename struct member is always assigned at this point */ - char *filebasename= - (!post->showfilename)?strippath(post->contents):NULL; - - result = AddFormDataf(&form, &size, - "; filename=\"%s\"", - (post->showfilename?post->showfilename: - filebasename)); - if(filebasename) - free(filebasename); + if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) { + char *filebasename= + (!post->showfilename)?strippath(post->contents):NULL; + + result = AddFormDataf(&form, &size, + "; filename=\"%s\"", + (post->showfilename?post->showfilename: + filebasename)); + if(filebasename) + free(filebasename); + } if(result) break; -- cgit v1.2.1 From 0337b871975ab515c513d2c5d596feb9a489494d Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 25 Jul 2011 04:08:08 +0200 Subject: time.h and sys/time.h inclusion conditionally done in setup_once.h --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index aa5a79ac1..e6ab124aa 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -32,10 +32,10 @@ #include #include #include -#include #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) #include #endif + #include "urldata.h" /* for struct SessionHandle */ #include "formdata.h" #include "curl_rand.h" -- cgit v1.2.1 From f1586cb4775681810afd8e6626e7842d459f3b85 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 26 Jul 2011 17:23:27 +0200 Subject: stdio.h, stdlib.h, string.h, stdarg.h and ctype.h inclusion done in setup_once.h --- lib/formdata.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index e6ab124aa..9e3ed08e5 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -21,6 +21,7 @@ ***************************************************************************/ #include "setup.h" + #include /* Length of the random boundary string. */ @@ -28,10 +29,6 @@ #if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) -#include -#include -#include -#include #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) #include #endif -- cgit v1.2.1 From 45d883d88df76af778ce7024912d3fdd08d13859 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 8 Aug 2011 10:21:03 +0200 Subject: CURLFORM_BUFFER: insert filename as documented A regression where CURLFORM_BUFFER stopped to properly insert the file name part in the formpart. Bug introduced in commit f851f768578dc096. Added CURLFORM_BUFFER use to test 554 to verify this. Bug: http://curl.haxx.se/mail/lib-2011-07/0176.html Reported by: Henry Ludemann --- lib/formdata.c | 49 ++++++++++++------------------------------------- 1 file changed, 12 insertions(+), 37 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 9e3ed08e5..757d96561 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -459,7 +459,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if(current_form->flags & HTTPPOST_FILENAME) { if(filename) { if((current_form = AddFormInfo(strdup(filename), - NULL, current_form)) == NULL) + NULL, current_form)) == NULL) return_value = CURL_FORMADD_MEMORY; } else @@ -484,46 +484,18 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, break; } - case CURLFORM_BUFFER: - { - const char *filename = array_state?array_value: - va_arg(params, char *); - - if(current_form->value) { - if(current_form->flags & HTTPPOST_BUFFER) { - if(filename) { - if((current_form = AddFormInfo(strdup(filename), - NULL, current_form)) == NULL) - return_value = CURL_FORMADD_MEMORY; - } - else - return_value = CURL_FORMADD_NULL; - } - else - return_value = CURL_FORMADD_OPTION_TWICE; - } - else { - if(filename) { - current_form->value = strdup(filename); - if(!current_form->value) - return_value = CURL_FORMADD_MEMORY; - } - else - return_value = CURL_FORMADD_NULL; - current_form->flags |= HTTPPOST_BUFFER; - } - break; - } - case CURLFORM_BUFFERPTR: - current_form->flags |= HTTPPOST_PTRBUFFER; + current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER; if(current_form->buffer) return_value = CURL_FORMADD_OPTION_TWICE; else { char *buffer = array_state?array_value:va_arg(params, char *); - if(buffer) + if(buffer) { current_form->buffer = buffer; /* store for the moment */ + current_form->value = buffer; /* make it non-NULL to be accepted + as fine */ + } else return_value = CURL_FORMADD_NULL; } @@ -564,8 +536,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if(current_form->flags & HTTPPOST_FILENAME) { if(contenttype) { if((current_form = AddFormInfo(NULL, - strdup(contenttype), - current_form)) == NULL) + strdup(contenttype), + current_form)) == NULL) return_value = CURL_FORMADD_MEMORY; } else @@ -603,6 +575,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, break; } case CURLFORM_FILENAME: + case CURLFORM_BUFFER: { const char *filename = array_state?array_value: va_arg(params, char *); @@ -619,6 +592,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } default: return_value = CURL_FORMADD_UNKNOWN_OPTION; + break; } } @@ -922,7 +896,8 @@ void curl_formfree(struct curl_httppost *form) if(!(form->flags & HTTPPOST_PTRNAME) && form->name) free(form->name); /* free the name */ - if(!(form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_CALLBACK)) && + if(!(form->flags & + (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK)) && form->contents) free(form->contents); /* free the contents */ if(form->contenttype) -- cgit v1.2.1 From a50210710ab6fd772e2762ed36602c15adfb49e1 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 5 Sep 2011 20:46:09 +0200 Subject: fix bool variables checking and assignment --- lib/formdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 757d96561..edd35ede8 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1273,7 +1273,7 @@ static size_t readfromfile(struct Form *form, char *buffer, size_t size) { size_t nread; - bool callback = (bool)(form->data->type == FORM_CALLBACK); + bool callback = (form->data->type == FORM_CALLBACK)?TRUE:FALSE; if(callback) { if(form->fread_func == ZERO_NULL) -- cgit v1.2.1 From 840eff44f2bea71acaa2a227998a97d01aacdc1f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 16 Oct 2011 01:07:29 +0200 Subject: formdata: ack read callback abort When doing a multipart formpost with a read callback, and that callback returns CURL_READFUNC_ABORT, that return code must be properly propagated back and handled accordingly. Previously it would be handled as a zero byte read which would cause a hang! Added test case 587 to verify. It uses the lib554.c source code with a small ifdef. Reported by: Anton Bychkov Bug: http://curl.haxx.se/mail/lib-2011-10/0097.html --- lib/formdata.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index edd35ede8..cbef51171 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -855,10 +855,11 @@ int curl_formget(struct curl_httppost *form, void *arg, do { nread = readfromfile(&temp, buffer, sizeof(buffer)); - if((nread == (size_t) -1) || (nread != append(arg, buffer, nread))) { - if(temp.fp) { + if((nread == (size_t) -1) || + (nread > sizeof(buffer)) || + (nread != append(arg, buffer, nread))) { + if(temp.fp) fclose(temp.fp); - } Curl_formclean(&data); return -1; } @@ -1269,6 +1270,13 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata ) return 0; } +/* + * readfromfile() + * + * The read callback that this function may use can return a value larger than + * 'size' (which then this function returns) that indicates a problem and it + * must be properly dealt with + */ static size_t readfromfile(struct Form *form, char *buffer, size_t size) { @@ -1280,11 +1288,6 @@ static size_t readfromfile(struct Form *form, char *buffer, return 0; else nread = form->fread_func(buffer, 1, size, form->data->line); - - if(nread > size) - /* the read callback can return a value larger than the buffer but - treat any such as no data in this case */ - nread = 0; } else { if(!form->fp) { -- cgit v1.2.1 From 1afbccc67664d32a6d1f77a644e9142e19b37fb5 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 21 Dec 2011 15:38:47 +0100 Subject: formdata.c: OOM handling fixes --- lib/formdata.c | 176 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 111 insertions(+), 65 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index cbef51171..5349130ff 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -156,8 +156,6 @@ static FormInfo * AddFormInfo(char *value, /* then move the original 'more' to point to ourselves */ parent_form_info->more = form_info; } - else - return NULL; return form_info; } @@ -458,9 +456,21 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if(current_form->value) { if(current_form->flags & HTTPPOST_FILENAME) { if(filename) { - if((current_form = AddFormInfo(strdup(filename), - NULL, current_form)) == NULL) + char *fname = strdup(filename); + if(!fname) 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 return_value = CURL_FORMADD_NULL; @@ -535,10 +545,21 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if(current_form->contenttype) { if(current_form->flags & HTTPPOST_FILENAME) { if(contenttype) { - if((current_form = AddFormInfo(NULL, - strdup(contenttype), - current_form)) == NULL) + char *type = strdup(contenttype); + if(!type) 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 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) { /* go through the list, check for completeness and if everything is * alright add the HttpPost item otherwise set return_value accordingly */ @@ -675,32 +720,39 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, prevtype = form->contenttype; } } - } - - if(return_value) { - /* we return on error, free possibly allocated fields */ - if(!form) - form = current_form; - if(form) { - if(form->name_alloc) - free(form->name); - if(form->value_alloc) - free(form->value); - if(form->contenttype_alloc) - free(form->contenttype); - if(form->showfilename_alloc) - free(form->showfilename); + if(CURL_FORMADD_OK != return_value) { + /* On error, free allocated fields for nodes of the FormInfo linked + list which are not already owned by the httppost linked list + without deallocating nodes. List nodes are deallocated later on */ + FormInfo *ptr; + for(ptr = 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; + } + } } } - /* always delete the allocated memory before returning */ - form = first_form; - while(form != NULL) { - FormInfo *delete_form; - - delete_form = form; - form = form->more; - free (delete_form); + /* Always deallocate FormInfo linked list nodes without touching node + fields given that these have either been deallocated or are owned + now by the httppost linked list */ + while(first_form) { + FormInfo *ptr = first_form->more; + Curl_safefree(first_form); + first_form = ptr; } return return_value; @@ -996,12 +1048,12 @@ CURLcode Curl_getformdata(struct SessionHandle *data, struct curl_httppost *file; 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 *fileboundary=NULL; + char *fileboundary = NULL; struct curl_slist* curList; - *finalform=NULL; /* default form is empty */ + *finalform = NULL; /* default form is empty */ if(!post) return result; /* no input => no output! */ @@ -1018,7 +1070,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, boundary); if(result) { - free(boundary); + Curl_safefree(boundary); return result; } /* 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 the magic to include several files with the same field name */ + Curl_safefree(fileboundary); fileboundary = Curl_FormBoundary(); + if(!fileboundary) { + result = CURLE_OUT_OF_MEMORY; + break; + } result = AddFormDataf(&form, &size, "\r\nContent-Type: multipart/mixed," @@ -1081,13 +1138,12 @@ CURLcode Curl_getformdata(struct SessionHandle *data, if(post->more) { /* if multiple-file */ - char *filebasename= NULL; + char *filebasename = NULL; if(!file->showfilename) { filebasename = strippath(file->contents); if(!filebasename) { - Curl_formclean(&firstform); - free(boundary); - return CURLE_OUT_OF_MEMORY; + result = CURLE_OUT_OF_MEMORY; + break; } } @@ -1097,8 +1153,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, fileboundary, (file->showfilename?file->showfilename: filebasename)); - if(filebasename) - free(filebasename); + Curl_safefree(filebasename); if(result) break; } @@ -1115,8 +1170,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, "; filename=\"%s\"", (post->showfilename?post->showfilename: filebasename)); - if(filebasename) - free(filebasename); + Curl_safefree(filebasename); } if(result) @@ -1140,11 +1194,8 @@ CURLcode Curl_getformdata(struct SessionHandle *data, break; curList = curList->next; } - if(result) { - Curl_formclean(&firstform); - free(boundary); - return result; - } + if(result) + break; result = AddFormDataf(&form, &size, "\r\n\r\n"); if(result) @@ -1166,7 +1217,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, if(fileread) { if(fileread != stdin) { - /* close the file again */ + /* close the file */ fclose(fileread); /* add the file name only - for later reading from this */ result = AddFormData(&form, FORM_FILE, file->contents, 0, &size); @@ -1210,11 +1261,8 @@ CURLcode Curl_getformdata(struct SessionHandle *data, file = file->more; } while(file && !result); /* for each specified file for this field */ - if(result) { - Curl_formclean(&firstform); - free(boundary); - return result; - } + if(result) + break; if(post->more) { /* this was a multiple-file inclusion, make a termination file @@ -1222,33 +1270,31 @@ CURLcode Curl_getformdata(struct SessionHandle *data, result = AddFormDataf(&form, &size, "\r\n--%s--", fileboundary); - free(fileboundary); if(result) break; } } while((post = post->next) != NULL); /* for each field */ - if(result) { - Curl_formclean(&firstform); - free(boundary); - return result; - } /* end-boundary for everything */ - result = AddFormDataf(&form, &size, - "\r\n--%s--\r\n", - boundary); + if(CURLE_OK == result) + result = AddFormDataf(&form, &size, + "\r\n--%s--\r\n", + boundary); + if(result) { Curl_formclean(&firstform); - free(boundary); + Curl_safefree(fileboundary); + Curl_safefree(boundary); return result; } *sizep = size; - free(boundary); + Curl_safefree(fileboundary); + Curl_safefree(boundary); - *finalform=firstform; + *finalform = firstform; return result; } -- cgit v1.2.1 From 6085ca2aeddb38e4d5f24c47bd98111b236cf384 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 14 Jun 2012 13:32:05 +0200 Subject: Fix bad failf() and info() usage Calls to failf() are not supposed to provide trailing newline. Calls to infof() must provide trailing newline. Fixed 30 or so strings. --- lib/formdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/formdata.c') diff --git a/lib/formdata.c b/lib/formdata.c index 5349130ff..7bf883941 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2012, 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 @@ -1239,7 +1239,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, } else { if(data) - failf(data, "couldn't open file \"%s\"\n", file->contents); + failf(data, "couldn't open file \"%s\"", file->contents); *finalform = NULL; result = CURLE_READ_ERROR; } -- cgit v1.2.1