Loading docs/cmdline-opts/form.d +5 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,11 @@ or Note that if a filename/path is quoted by double-quotes, any double-quote or backslash within the filename must be escaped by backslash. Quoting must also be applied to non-file data if it contains semicolons, leading/trailing spaces or leading double quotes: curl -F 'colors="red; green; blue";type=text/x-myapp' example.com You can add custom headers to the field by setting headers=, like curl -F "submit=OK;headers=\\"X-submit-type: OK\\"" example.com Loading src/tool_formparse.c +18 −17 Original line number Diff line number Diff line Loading @@ -52,13 +52,12 @@ typedef struct { * after call get_parm_word, str either point to string end * or point to any of end chars. */ static char *get_param_word(char **str, char **end_pos) static char *get_param_word(char **str, char **end_pos, char endchar) { char *ptr = *str; char *word_begin = NULL; char *ptr2; char *escape = NULL; const char *end_chars = ";,"; /* the first non-space char is here */ word_begin = ptr; Loading Loading @@ -88,7 +87,7 @@ static char *get_param_word(char **str, char **end_pos) while(ptr < *end_pos); *end_pos = ptr2; } while(*ptr && NULL == strchr(end_chars, *ptr)) while(*ptr && *ptr != ';' && *ptr != endchar) ++ptr; *str = ptr; return word_begin + 1; Loading @@ -99,7 +98,7 @@ static char *get_param_word(char **str, char **end_pos) ptr = word_begin; } while(*ptr && NULL == strchr(end_chars, *ptr)) while(*ptr && *ptr != ';' && *ptr != endchar) ++ptr; *str = *end_pos = ptr; return word_begin; Loading Loading @@ -181,9 +180,10 @@ static int read_field_headers(struct OperationConfig *config, /* NOTREACHED */ } static int get_param_part(struct OperationConfig *config, char **str, char **pdata, char **ptype, char **pfilename, char **pencoder, struct curl_slist **pheaders) static int get_param_part(struct OperationConfig *config, char endchar, char **str, char **pdata, char **ptype, char **pfilename, char **pencoder, struct curl_slist **pheaders) { char *p = *str; char *type = NULL; Loading @@ -208,7 +208,7 @@ static int get_param_part(struct OperationConfig *config, char **str, while(ISSPACE(*p)) p++; tp = p; *pdata = get_param_word(&p, &endpos); *pdata = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(*pdata == tp) while(endpos > *pdata && ISSPACE(endpos[-1])) Loading Loading @@ -249,7 +249,7 @@ static int get_param_part(struct OperationConfig *config, char **str, for(p += 9; ISSPACE(*p); p++) ; tp = p; filename = get_param_word(&p, &endpos); filename = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(filename == tp) while(endpos > filename && ISSPACE(endpos[-1])) Loading @@ -272,7 +272,7 @@ static int get_param_part(struct OperationConfig *config, char **str, p++; } while(ISSPACE(*p)); tp = p; hdrfile = get_param_word(&p, &endpos); hdrfile = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(hdrfile == tp) while(endpos > hdrfile && ISSPACE(endpos[-1])) Loading Loading @@ -300,7 +300,7 @@ static int get_param_part(struct OperationConfig *config, char **str, while(ISSPACE(*p)) p++; tp = p; hdr = get_param_word(&p, &endpos); hdr = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(hdr == tp) while(endpos > hdr && ISSPACE(endpos[-1])) Loading @@ -322,7 +322,7 @@ static int get_param_part(struct OperationConfig *config, char **str, for(p += 8; ISSPACE(*p); p++) ; tp = p; encoder = get_param_word(&p, &endpos); encoder = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(encoder == tp) while(endpos > encoder && ISSPACE(endpos[-1])) Loading @@ -332,7 +332,7 @@ static int get_param_part(struct OperationConfig *config, char **str, } else { /* unknown prefix, skip to next block */ char *unknown = get_param_word(&p, &endpos); char *unknown = get_param_word(&p, &endpos, endchar); sep = *p; if(endct) Loading Loading @@ -598,7 +598,8 @@ int formparse(struct OperationConfig *config, curl_mime *subparts; /* Starting a multipart. */ sep = get_param_part(config, &contp, &data, &type, NULL, NULL, &headers); sep = get_param_part(config, '\0', &contp, &data, &type, NULL, NULL, &headers); if(sep < 0) { Curl_safefree(contents); return 3; Loading Loading @@ -657,7 +658,7 @@ int formparse(struct OperationConfig *config, /* since this was a file, it may have a content-type specifier at the end too, or a filename. Or both. */ ++contp; sep = get_param_part(config, &contp, sep = get_param_part(config, ',', &contp, &data, &type, &filename, &encoder, &headers); if(sep < 0) { if(subparts != *mimecurrent) Loading Loading @@ -767,7 +768,7 @@ int formparse(struct OperationConfig *config, if(*contp == '<' && !literal_value) { ++contp; sep = get_param_part(config, &contp, sep = get_param_part(config, '\0', &contp, &data, &type, NULL, &encoder, &headers); if(sep < 0) { Curl_safefree(contents); Loading Loading @@ -796,7 +797,7 @@ int formparse(struct OperationConfig *config, if(literal_value) data = contp; else { sep = get_param_part(config, &contp, sep = get_param_part(config, '\0', &contp, &data, &type, &filename, &encoder, &headers); if(sep < 0) { Curl_safefree(contents); Loading tests/data/test1133 +11 −3 Original line number Diff line number Diff line Loading @@ -23,10 +23,10 @@ blablabla http </server> <name> HTTP RFC1867-type formposting with filename contains ',', ';', '"' HTTP RFC1867-type formposting with filename/data contains ',', ';', '"' </name> <command> http://%HOSTIP:%HTTPPORT/we/want/1133 -F "file=@\"log/test1133,a\\\"nd;.txt\";type=mo/foo;filename=\"faker,and;.txt\"" -F 'file2=@"log/test1133,a\"nd;.txt"' -F 'file3=@"log/test1133,a\"nd;.txt";type=m/f,"log/test1133,a\"nd;.txt"' http://%HOSTIP:%HTTPPORT/we/want/1133 -F "file=@\"log/test1133,a\\\"nd;.txt\";type=mo/foo;filename=\"faker,and;.txt\"" -F 'file2=@"log/test1133,a\"nd;.txt"' -F 'file3=@"log/test1133,a\"nd;.txt";type=m/f,"log/test1133,a\"nd;.txt"' -F a="{\"field1\":\"value1\",\"field2\":\"value2\"}" -F 'b=" \\value1;type=\"whatever\" "; type=text/foo; charset=utf-8 ; filename=param_b' </command> # We create this file before the command is invoked! <file name=log/test1133,a"nd;.txt> Loading @@ -47,7 +47,8 @@ POST /we/want/1133 HTTP/1.1 User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3 Host: %HOSTIP:%HTTPPORT Accept: */* Content-Length: 969 Content-Length: 1270 Expect: 100-continue Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32 ------------------------------24e78000bd32 Loading Loading @@ -89,6 +90,13 @@ bar foo Content-Disposition: form-data; name="a" {"field1":"value1","field2":"value2"} Content-Disposition: form-data; name="b"; filename="param_b" Content-Type: text/foo; charset=utf-8 \value1;type="whatever" ------------------------------24e78000bd32-- </protocol> </verify> Loading Loading
docs/cmdline-opts/form.d +5 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,11 @@ or Note that if a filename/path is quoted by double-quotes, any double-quote or backslash within the filename must be escaped by backslash. Quoting must also be applied to non-file data if it contains semicolons, leading/trailing spaces or leading double quotes: curl -F 'colors="red; green; blue";type=text/x-myapp' example.com You can add custom headers to the field by setting headers=, like curl -F "submit=OK;headers=\\"X-submit-type: OK\\"" example.com Loading
src/tool_formparse.c +18 −17 Original line number Diff line number Diff line Loading @@ -52,13 +52,12 @@ typedef struct { * after call get_parm_word, str either point to string end * or point to any of end chars. */ static char *get_param_word(char **str, char **end_pos) static char *get_param_word(char **str, char **end_pos, char endchar) { char *ptr = *str; char *word_begin = NULL; char *ptr2; char *escape = NULL; const char *end_chars = ";,"; /* the first non-space char is here */ word_begin = ptr; Loading Loading @@ -88,7 +87,7 @@ static char *get_param_word(char **str, char **end_pos) while(ptr < *end_pos); *end_pos = ptr2; } while(*ptr && NULL == strchr(end_chars, *ptr)) while(*ptr && *ptr != ';' && *ptr != endchar) ++ptr; *str = ptr; return word_begin + 1; Loading @@ -99,7 +98,7 @@ static char *get_param_word(char **str, char **end_pos) ptr = word_begin; } while(*ptr && NULL == strchr(end_chars, *ptr)) while(*ptr && *ptr != ';' && *ptr != endchar) ++ptr; *str = *end_pos = ptr; return word_begin; Loading Loading @@ -181,9 +180,10 @@ static int read_field_headers(struct OperationConfig *config, /* NOTREACHED */ } static int get_param_part(struct OperationConfig *config, char **str, char **pdata, char **ptype, char **pfilename, char **pencoder, struct curl_slist **pheaders) static int get_param_part(struct OperationConfig *config, char endchar, char **str, char **pdata, char **ptype, char **pfilename, char **pencoder, struct curl_slist **pheaders) { char *p = *str; char *type = NULL; Loading @@ -208,7 +208,7 @@ static int get_param_part(struct OperationConfig *config, char **str, while(ISSPACE(*p)) p++; tp = p; *pdata = get_param_word(&p, &endpos); *pdata = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(*pdata == tp) while(endpos > *pdata && ISSPACE(endpos[-1])) Loading Loading @@ -249,7 +249,7 @@ static int get_param_part(struct OperationConfig *config, char **str, for(p += 9; ISSPACE(*p); p++) ; tp = p; filename = get_param_word(&p, &endpos); filename = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(filename == tp) while(endpos > filename && ISSPACE(endpos[-1])) Loading @@ -272,7 +272,7 @@ static int get_param_part(struct OperationConfig *config, char **str, p++; } while(ISSPACE(*p)); tp = p; hdrfile = get_param_word(&p, &endpos); hdrfile = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(hdrfile == tp) while(endpos > hdrfile && ISSPACE(endpos[-1])) Loading Loading @@ -300,7 +300,7 @@ static int get_param_part(struct OperationConfig *config, char **str, while(ISSPACE(*p)) p++; tp = p; hdr = get_param_word(&p, &endpos); hdr = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(hdr == tp) while(endpos > hdr && ISSPACE(endpos[-1])) Loading @@ -322,7 +322,7 @@ static int get_param_part(struct OperationConfig *config, char **str, for(p += 8; ISSPACE(*p); p++) ; tp = p; encoder = get_param_word(&p, &endpos); encoder = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(encoder == tp) while(endpos > encoder && ISSPACE(endpos[-1])) Loading @@ -332,7 +332,7 @@ static int get_param_part(struct OperationConfig *config, char **str, } else { /* unknown prefix, skip to next block */ char *unknown = get_param_word(&p, &endpos); char *unknown = get_param_word(&p, &endpos, endchar); sep = *p; if(endct) Loading Loading @@ -598,7 +598,8 @@ int formparse(struct OperationConfig *config, curl_mime *subparts; /* Starting a multipart. */ sep = get_param_part(config, &contp, &data, &type, NULL, NULL, &headers); sep = get_param_part(config, '\0', &contp, &data, &type, NULL, NULL, &headers); if(sep < 0) { Curl_safefree(contents); return 3; Loading Loading @@ -657,7 +658,7 @@ int formparse(struct OperationConfig *config, /* since this was a file, it may have a content-type specifier at the end too, or a filename. Or both. */ ++contp; sep = get_param_part(config, &contp, sep = get_param_part(config, ',', &contp, &data, &type, &filename, &encoder, &headers); if(sep < 0) { if(subparts != *mimecurrent) Loading Loading @@ -767,7 +768,7 @@ int formparse(struct OperationConfig *config, if(*contp == '<' && !literal_value) { ++contp; sep = get_param_part(config, &contp, sep = get_param_part(config, '\0', &contp, &data, &type, NULL, &encoder, &headers); if(sep < 0) { Curl_safefree(contents); Loading Loading @@ -796,7 +797,7 @@ int formparse(struct OperationConfig *config, if(literal_value) data = contp; else { sep = get_param_part(config, &contp, sep = get_param_part(config, '\0', &contp, &data, &type, &filename, &encoder, &headers); if(sep < 0) { Curl_safefree(contents); Loading
tests/data/test1133 +11 −3 Original line number Diff line number Diff line Loading @@ -23,10 +23,10 @@ blablabla http </server> <name> HTTP RFC1867-type formposting with filename contains ',', ';', '"' HTTP RFC1867-type formposting with filename/data contains ',', ';', '"' </name> <command> http://%HOSTIP:%HTTPPORT/we/want/1133 -F "file=@\"log/test1133,a\\\"nd;.txt\";type=mo/foo;filename=\"faker,and;.txt\"" -F 'file2=@"log/test1133,a\"nd;.txt"' -F 'file3=@"log/test1133,a\"nd;.txt";type=m/f,"log/test1133,a\"nd;.txt"' http://%HOSTIP:%HTTPPORT/we/want/1133 -F "file=@\"log/test1133,a\\\"nd;.txt\";type=mo/foo;filename=\"faker,and;.txt\"" -F 'file2=@"log/test1133,a\"nd;.txt"' -F 'file3=@"log/test1133,a\"nd;.txt";type=m/f,"log/test1133,a\"nd;.txt"' -F a="{\"field1\":\"value1\",\"field2\":\"value2\"}" -F 'b=" \\value1;type=\"whatever\" "; type=text/foo; charset=utf-8 ; filename=param_b' </command> # We create this file before the command is invoked! <file name=log/test1133,a"nd;.txt> Loading @@ -47,7 +47,8 @@ POST /we/want/1133 HTTP/1.1 User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3 Host: %HOSTIP:%HTTPPORT Accept: */* Content-Length: 969 Content-Length: 1270 Expect: 100-continue Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32 ------------------------------24e78000bd32 Loading Loading @@ -89,6 +90,13 @@ bar foo Content-Disposition: form-data; name="a" {"field1":"value1","field2":"value2"} Content-Disposition: form-data; name="b"; filename="param_b" Content-Type: text/foo; charset=utf-8 \value1;type="whatever" ------------------------------24e78000bd32-- </protocol> </verify> Loading