Skip to content

Commit

Permalink
libcurl formdata escape double-quote in filename by backslash.
Browse files Browse the repository at this point in the history
  • Loading branch information
ulion committed Jan 20, 2013
1 parent 850b14c commit fcca552
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 30 deletions.
67 changes: 45 additions & 22 deletions lib/formdata.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1024,6 +1024,45 @@ static char *strippath(const char *fullfile)
return base; /* returns an allocated string or NULL ! */ 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 * Curl_getformdata() converts a linked list of "meta data" into a complete
* (possibly huge) multipart formdata. The input list is in 'post', while the * (possibly huge) multipart formdata. The input list is in 'post', while the
Expand Down Expand Up @@ -1138,22 +1177,13 @@ CURLcode Curl_getformdata(struct SessionHandle *data,


if(post->more) { if(post->more) {
/* if multiple-file */ /* 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, result = AddFormDataf(&form, &size,
"\r\n--%s\r\nContent-Disposition: " "\r\n--%s\r\nContent-Disposition: "
"attachment; filename=\"%s\"", "attachment",
fileboundary, fileboundary);
(file->showfilename?file->showfilename: if(result)
filebasename)); break;
Curl_safefree(filebasename); result = formdata_add_filename(file, &form, &size);
if(result) if(result)
break; break;
} }
Expand All @@ -1163,14 +1193,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
HTTPPOST_CALLBACK cases the ->showfilename struct member is always HTTPPOST_CALLBACK cases the ->showfilename struct member is always
assigned at this point */ assigned at this point */
if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) { if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) {
char *filebasename= result = formdata_add_filename(post, &form, &size);
(!post->showfilename)?strippath(post->contents):NULL;

result = AddFormDataf(&form, &size,
"; filename=\"%s\"",
(post->showfilename?post->showfilename:
filebasename));
Curl_safefree(filebasename);
} }


if(result) if(result)
Expand Down
10 changes: 5 additions & 5 deletions tests/data/test1133
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ blablabla
http http
</server> </server>
<name> <name>
HTTP RFC1867-type formposting with filename contains ',' and ';' HTTP RFC1867-type formposting with filename contains ',', ';', '"'
</name> </name>
<command> <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"'
Expand All @@ -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 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 Host: %HOSTIP:%HTTPPORT
Accept: */* Accept: */*
Content-Length: 964 Content-Length: 967
Expect: 100-continue Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32 Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32


Expand All @@ -61,7 +61,7 @@ bar
foo foo


------------------------------24e78000bd32 ------------------------------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 Content-Type: text/plain


foo bar foo bar
Expand All @@ -73,15 +73,15 @@ foo
Content-Disposition: form-data; name="file3" Content-Disposition: form-data; name="file3"
Content-Type: multipart/mixed, boundary=----------------------------7f0e85a48b0b 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 Content-Type: m/f


foo bar foo bar
This is a bar foo This is a bar foo
bar bar
foo foo


Content-Disposition: attachment; filename="test1133,a"nd;.txt" Content-Disposition: attachment; filename="test1133,a\"nd;.txt"
Content-Type: text/plain Content-Type: text/plain


foo bar foo bar
Expand Down
6 changes: 3 additions & 3 deletions tests/data/test39
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -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 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 Host: %HOSTIP:%HTTPPORT
Accept: */* Accept: */*
Content-Length: 1172 Content-Length: 1184
Expect: 100-continue Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32 Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32


Expand Down Expand Up @@ -86,7 +86,7 @@ bar
foo foo


------------------------------24e78000bd32 ------------------------------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 Content-Type: mo/foo


foo bar foo bar
Expand All @@ -95,7 +95,7 @@ bar
foo foo


------------------------------24e78000bd32 ------------------------------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 Content-Type: text/plain


foo bar foo bar
Expand Down

0 comments on commit fcca552

Please sign in to comment.