Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

libcurl formdata escape double-quote in filename by backslash.

  • Loading branch information...
commit fcca552b12b7f024546c1c18f88b50d3a08e6ff0 1 parent 850b14c
@ulion authored
Showing with 53 additions and 30 deletions.
  1. +45 −22 lib/formdata.c
  2. +5 −5 tests/data/test1133
  3. +3 −3 tests/data/test39
View
67 lib/formdata.c
@@ -1024,6 +1024,45 @@ static char *strippath(const char *fullfile)
return base; /* returns an allocated string or NULL ! */
}
+static CURLcode formdata_add_filename(const struct curl_httppost *file,
+ struct FormData **form,
+ curl_off_t *size)
+{
+ CURLcode result = CURLE_OK;
+ char *filename = file->showfilename;
+ char *filebasename = NULL;
+ if(!filename) {
+ filebasename = strippath(file->contents);
+ if (!filebasename)
+ return CURLE_OUT_OF_MEMORY;
+ filename = filebasename;
+ }
+ char *filename_escaped = NULL;
+
+ if (strchr(filename, '\\') || strchr(filename, '"')) {
+ /* filename need be escaped */
+ filename_escaped = malloc(strlen(filename)*2+1);
+ if (!filename_escaped)
+ return CURLE_OUT_OF_MEMORY;
+ char *p0, *p1;
+ p0 = filename_escaped;
+ p1 = filename;
+ while (*p1) {
+ if (*p1 == '\\' || *p1 == '"')
+ *p0++ = '\\';
+ *p0++ = *p1++;
+ }
+ *p0 = '\0';
+ filename = filename_escaped;
+ }
+ result = AddFormDataf(form, size,
+ "; filename=\"%s\"",
+ filename);
+ Curl_safefree(filename_escaped);
+ Curl_safefree(filebasename);
+ return result;
+}
+
/*
* Curl_getformdata() converts a linked list of "meta data" into a complete
* (possibly huge) multipart formdata. The input list is in 'post', while the
@@ -1138,22 +1177,13 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
if(post->more) {
/* if multiple-file */
- char *filebasename = NULL;
- if(!file->showfilename) {
- filebasename = strippath(file->contents);
- if(!filebasename) {
- result = CURLE_OUT_OF_MEMORY;
- break;
- }
- }
-
result = AddFormDataf(&form, &size,
"\r\n--%s\r\nContent-Disposition: "
- "attachment; filename=\"%s\"",
- fileboundary,
- (file->showfilename?file->showfilename:
- filebasename));
- Curl_safefree(filebasename);
+ "attachment",
+ fileboundary);
+ if(result)
+ break;
+ result = formdata_add_filename(file, &form, &size);
if(result)
break;
}
@@ -1163,14 +1193,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
HTTPPOST_CALLBACK cases the ->showfilename struct member is always
assigned at this point */
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));
- Curl_safefree(filebasename);
+ result = formdata_add_filename(post, &form, &size);
}
if(result)
View
10 tests/data/test1133
@@ -23,7 +23,7 @@ blablabla
http
</server>
<name>
-HTTP RFC1867-type formposting with filename contains ',' and ';'
+HTTP RFC1867-type formposting with filename 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"'
@@ -47,7 +47,7 @@ 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: 964
+Content-Length: 967
Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32
@@ -61,7 +61,7 @@ bar
foo
------------------------------24e78000bd32
-Content-Disposition: form-data; name="file2"; filename="test1133,a"nd;.txt"
+Content-Disposition: form-data; name="file2"; filename="test1133,a\"nd;.txt"
Content-Type: text/plain
foo bar
@@ -73,7 +73,7 @@ foo
Content-Disposition: form-data; name="file3"
Content-Type: multipart/mixed, boundary=----------------------------7f0e85a48b0b
-Content-Disposition: attachment; filename="test1133,a"nd;.txt"
+Content-Disposition: attachment; filename="test1133,a\"nd;.txt"
Content-Type: m/f
foo bar
@@ -81,7 +81,7 @@ This is a bar foo
bar
foo
-Content-Disposition: attachment; filename="test1133,a"nd;.txt"
+Content-Disposition: attachment; filename="test1133,a\"nd;.txt"
Content-Type: text/plain
foo bar
View
6 tests/data/test39
@@ -47,7 +47,7 @@ POST /we/want/39 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: 1172
+Content-Length: 1184
Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32
@@ -86,7 +86,7 @@ bar
foo
------------------------------24e78000bd32
-Content-Disposition: form-data; name="file3"; filename="f\\ak\\er,\an\d;.t"xt"
+Content-Disposition: form-data; name="file3"; filename="f\\\\ak\\\\er,\\an\\d;.t\"xt"
Content-Type: mo/foo
foo bar
@@ -95,7 +95,7 @@ bar
foo
------------------------------24e78000bd32
-Content-Disposition: form-data; name="file4"; filename="A\AA""\"ZZZ"
+Content-Disposition: form-data; name="file4"; filename="A\\AA\"\"\\\"ZZZ"
Content-Type: text/plain
foo bar
Please sign in to comment.
Something went wrong with that request. Please try again.