]> granicus.if.org Git - curl/commitdiff
David Houlder added --form-string
authorDaniel Stenberg <daniel@haxx.se>
Sat, 12 Mar 2005 19:39:27 +0000 (19:39 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 12 Mar 2005 19:39:27 +0000 (19:39 +0000)
docs/MANUAL
docs/curl.1
src/main.c
tests/data/test39

index 26bb8f65ad571bde9740a1f025b5f8e8922ac5c2..86449d7d343d4d55b9b8486e9fffa25e41b57b79 100644 (file)
@@ -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
index 3b6fb3ce11ba832cc741a01e48bb09f1ddbb587a..f216db68fa2e8488b6ee482d59b0adfc8c7da24e 100644 (file)
@@ -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
index 0565abd429eb7f277ca48dad9e9be84c6c551f8b..298d40153c9d37cd49f9fbdcbf76e3ee6558248b 100644 (file)
@@ -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",
@@ -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:
  *
@@ -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 */
@@ -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++;
@@ -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;
@@ -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++;
@@ -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},
@@ -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];
@@ -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;
index 29f6cc398baba82fca004d824399ad48f03ce1aa..7c0028762d47dc61dd2299ae22026eaf429b01e7 100644 (file)
@@ -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">
@@ -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\r
 Pragma: no-cache\r
 Accept: */*\r
-Content-Length: 594\r
+Content-Length: 810\r
 Expect: 100-continue\r
 Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32\r
 \r
@@ -54,6 +54,14 @@ Content-Disposition: form-data; name="tool"
 \r
 curl\r
 ------------------------------24e78000bd32\r
+Content-Disposition: form-data; name="str1"\r
+\r
+@literal\r
+------------------------------24e78000bd32\r
+Content-Disposition: form-data; name="str2"\r
+\r
+<verbatim;type=xxx/yyy\r
+------------------------------24e78000bd32\r
 Content-Disposition: form-data; name="file"; filename="fakerfile"\r
 Content-Type: moo/foobar\r
 \r