Loading docs/MANUAL +7 −0 Original line number Diff line number Diff line Loading @@ -299,6 +299,13 @@ POST (HTTP) curl -F "docpicture=@dog.gif" -F "catpicture=@cat.gif" To send a field value literally without interpreting a leading '@' or '<', or an embedded ';type=', use --form-string instead of -F. This is recommended when the value is obtained from a user or some other unpredictable source. Under these circumstances, using -F instead of --form-string would allow a user to trick curl into uploading a file. REFERRER A HTTP request has the option to include information about which address Loading docs/curl.1 +6 −0 Original line number Diff line number Diff line Loading @@ -388,6 +388,12 @@ setting filename=, like this: See further examples and details in the MANUAL. This option can be used multiple times. .IP "--form-string <name=string>" (HTTP) Similar to \fI--form\fP except that the value string for the named parameter is used literally. Leading \&'@' and \&'<' characters, and the \&';type=' string in the value have no special meaning. Use this in preference to \fI--form\fP if there's any possibility that the string value may accidentally trigger the \&'@' or \&'<' features of \fI--form\f{. .IP "-g/--globoff" This option switches off the "URL globbing parser". When you set this option, you can specify URLs that contain the letters {}[] without having them being Loading src/main.c +15 −6 Original line number Diff line number Diff line Loading @@ -355,6 +355,7 @@ static void help(void) " --ftp-pasv Use PASV instead of PORT (F)", " --ftp-ssl Enable SSL/TLS for the ftp transfer (F)", " -F/--form <name=content> Specify HTTP multipart POST data (H)", " --form-string <name=string> Specify HTTP multipart POST data (H)", " -g/--globoff Disable URL sequences and ranges using {} and []", " -G/--get Send the -d data with a HTTP GET (H)", " -h/--help This help text", Loading Loading @@ -774,6 +775,9 @@ static void list_engines (const struct curl_slist *engines) * Specify files to upload with 'name=@filename'. Supports specified * given Content-Type of the files. Such as ';type=<content-type>'. * * If literal_value is set, any initial '@' or '<' in the value string * loses its special meaning, as does any embedded ';type='. * * You may specify more than one file for a single name (field). Specify * multiple files by writing it like: * Loading Loading @@ -804,7 +808,8 @@ static void list_engines (const struct curl_slist *engines) static int formparse(char *input, struct curl_httppost **httppost, struct curl_httppost **last_post) struct curl_httppost **last_post, bool literal_value) { /* nextarg MUST be a string in the format 'name=contents' and we'll build a linked list with the info */ Loading @@ -829,7 +834,7 @@ static int formparse(char *input, } contp = contents; if('@' == contp[0]) { if('@' == contp[0] && !literal_value) { struct multi_files *multi_start = NULL, *multi_current = NULL; /* we use the @-letter to indicate file name(s) */ contp++; Loading Loading @@ -974,7 +979,7 @@ static int formparse(char *input, else { struct curl_forms info[4]; int i = 0; char *ct = strstr(contp, ";type="); char *ct = literal_value? NULL: strstr(contp, ";type="); info[i].option = CURLFORM_COPYNAME; info[i].value = name; Loading @@ -987,7 +992,7 @@ static int formparse(char *input, ct[0]=0; /* zero terminate here */ } if( contp[0]=='<' ) { if( contp[0]=='<' && !literal_value) { info[i].option = CURLFORM_FILECONTENT; info[i].value = contp+1; i++; Loading Loading @@ -1280,6 +1285,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ {"Eg","capath ", TRUE}, {"f", "fail", FALSE}, {"F", "form", TRUE}, {"Fs","form-string", TRUE}, {"g", "globoff", FALSE}, {"G", "get", FALSE}, {"h", "help", FALSE}, Loading Loading @@ -1361,8 +1367,10 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ do { /* we can loop here if we have multiple single-letters */ if(!longopt) if(!longopt) { letter = parse?(char)*parse:'\0'; subletter='\0'; } else { letter = parse[0]; subletter = parse[1]; Loading Loading @@ -1833,7 +1841,8 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ to sort this out slowly and carefully */ if(formparse(nextarg, &config->httppost, &config->last_post)) &config->last_post, subletter=='s')) /* 's' means literal string */ return PARAM_BAD_USE; if(SetHTTPrequest(HTTPREQ_POST, &config->httpreq)) return PARAM_BAD_USE; Loading tests/data/test39 +10 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ http HTTP RFC1867-type formposting with filename= and type= </name> <command> http://%HOSTIP:%HTTPPORT/we/want/39 -F name=daniel -F tool=curl -F "file=@log/test39.txt;filename=fakerfile;type=moo/foobar" -F file2=@log/test39.txt http://%HOSTIP:%HTTPPORT/we/want/39 -F name=daniel -F tool=curl --form-string "str1=@literal" --form-string "str2=<verbatim;type=xxx/yyy" -F "file=@log/test39.txt;filename=fakerfile;type=moo/foobar" -F file2=@log/test39.txt </command> # We create this file before the command is invoked! <file name="log/test39.txt"> Loading @@ -41,7 +41,7 @@ User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 z Host: 127.0.0.1:%HTTPPORT Pragma: no-cache Accept: */* Content-Length: 594 Content-Length: 810 Expect: 100-continue Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32 Loading @@ -54,6 +54,14 @@ Content-Disposition: form-data; name="tool" curl ------------------------------24e78000bd32 Content-Disposition: form-data; name="str1" @literal ------------------------------24e78000bd32 Content-Disposition: form-data; name="str2" <verbatim;type=xxx/yyy ------------------------------24e78000bd32 Content-Disposition: form-data; name="file"; filename="fakerfile" Content-Type: moo/foobar Loading Loading
docs/MANUAL +7 −0 Original line number Diff line number Diff line Loading @@ -299,6 +299,13 @@ POST (HTTP) curl -F "docpicture=@dog.gif" -F "catpicture=@cat.gif" To send a field value literally without interpreting a leading '@' or '<', or an embedded ';type=', use --form-string instead of -F. This is recommended when the value is obtained from a user or some other unpredictable source. Under these circumstances, using -F instead of --form-string would allow a user to trick curl into uploading a file. REFERRER A HTTP request has the option to include information about which address Loading
docs/curl.1 +6 −0 Original line number Diff line number Diff line Loading @@ -388,6 +388,12 @@ setting filename=, like this: See further examples and details in the MANUAL. This option can be used multiple times. .IP "--form-string <name=string>" (HTTP) Similar to \fI--form\fP except that the value string for the named parameter is used literally. Leading \&'@' and \&'<' characters, and the \&';type=' string in the value have no special meaning. Use this in preference to \fI--form\fP if there's any possibility that the string value may accidentally trigger the \&'@' or \&'<' features of \fI--form\f{. .IP "-g/--globoff" This option switches off the "URL globbing parser". When you set this option, you can specify URLs that contain the letters {}[] without having them being Loading
src/main.c +15 −6 Original line number Diff line number Diff line Loading @@ -355,6 +355,7 @@ static void help(void) " --ftp-pasv Use PASV instead of PORT (F)", " --ftp-ssl Enable SSL/TLS for the ftp transfer (F)", " -F/--form <name=content> Specify HTTP multipart POST data (H)", " --form-string <name=string> Specify HTTP multipart POST data (H)", " -g/--globoff Disable URL sequences and ranges using {} and []", " -G/--get Send the -d data with a HTTP GET (H)", " -h/--help This help text", Loading Loading @@ -774,6 +775,9 @@ static void list_engines (const struct curl_slist *engines) * Specify files to upload with 'name=@filename'. Supports specified * given Content-Type of the files. Such as ';type=<content-type>'. * * If literal_value is set, any initial '@' or '<' in the value string * loses its special meaning, as does any embedded ';type='. * * You may specify more than one file for a single name (field). Specify * multiple files by writing it like: * Loading Loading @@ -804,7 +808,8 @@ static void list_engines (const struct curl_slist *engines) static int formparse(char *input, struct curl_httppost **httppost, struct curl_httppost **last_post) struct curl_httppost **last_post, bool literal_value) { /* nextarg MUST be a string in the format 'name=contents' and we'll build a linked list with the info */ Loading @@ -829,7 +834,7 @@ static int formparse(char *input, } contp = contents; if('@' == contp[0]) { if('@' == contp[0] && !literal_value) { struct multi_files *multi_start = NULL, *multi_current = NULL; /* we use the @-letter to indicate file name(s) */ contp++; Loading Loading @@ -974,7 +979,7 @@ static int formparse(char *input, else { struct curl_forms info[4]; int i = 0; char *ct = strstr(contp, ";type="); char *ct = literal_value? NULL: strstr(contp, ";type="); info[i].option = CURLFORM_COPYNAME; info[i].value = name; Loading @@ -987,7 +992,7 @@ static int formparse(char *input, ct[0]=0; /* zero terminate here */ } if( contp[0]=='<' ) { if( contp[0]=='<' && !literal_value) { info[i].option = CURLFORM_FILECONTENT; info[i].value = contp+1; i++; Loading Loading @@ -1280,6 +1285,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ {"Eg","capath ", TRUE}, {"f", "fail", FALSE}, {"F", "form", TRUE}, {"Fs","form-string", TRUE}, {"g", "globoff", FALSE}, {"G", "get", FALSE}, {"h", "help", FALSE}, Loading Loading @@ -1361,8 +1367,10 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ do { /* we can loop here if we have multiple single-letters */ if(!longopt) if(!longopt) { letter = parse?(char)*parse:'\0'; subletter='\0'; } else { letter = parse[0]; subletter = parse[1]; Loading Loading @@ -1833,7 +1841,8 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ to sort this out slowly and carefully */ if(formparse(nextarg, &config->httppost, &config->last_post)) &config->last_post, subletter=='s')) /* 's' means literal string */ return PARAM_BAD_USE; if(SetHTTPrequest(HTTPREQ_POST, &config->httpreq)) return PARAM_BAD_USE; Loading
tests/data/test39 +10 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ http HTTP RFC1867-type formposting with filename= and type= </name> <command> http://%HOSTIP:%HTTPPORT/we/want/39 -F name=daniel -F tool=curl -F "file=@log/test39.txt;filename=fakerfile;type=moo/foobar" -F file2=@log/test39.txt http://%HOSTIP:%HTTPPORT/we/want/39 -F name=daniel -F tool=curl --form-string "str1=@literal" --form-string "str2=<verbatim;type=xxx/yyy" -F "file=@log/test39.txt;filename=fakerfile;type=moo/foobar" -F file2=@log/test39.txt </command> # We create this file before the command is invoked! <file name="log/test39.txt"> Loading @@ -41,7 +41,7 @@ User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 z Host: 127.0.0.1:%HTTPPORT Pragma: no-cache Accept: */* Content-Length: 594 Content-Length: 810 Expect: 100-continue Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32 Loading @@ -54,6 +54,14 @@ Content-Disposition: form-data; name="tool" curl ------------------------------24e78000bd32 Content-Disposition: form-data; name="str1" @literal ------------------------------24e78000bd32 Content-Disposition: form-data; name="str2" <verbatim;type=xxx/yyy ------------------------------24e78000bd32 Content-Disposition: form-data; name="file"; filename="fakerfile" Content-Type: moo/foobar Loading