Skip to content

Commit

Permalink
Fix parseMultipartForm to accept unquoted strings
Browse files Browse the repository at this point in the history
Content-Disposition fields can be passed as an unquoted string in which case the current parser fails.
  • Loading branch information
tchaloupka committed Mar 27, 2017
1 parent 9acaf1a commit 6321174
Showing 1 changed file with 41 additions and 8 deletions.
49 changes: 41 additions & 8 deletions inet/vibe/inet/webform.d
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,33 @@ unittest { // issue #1220 - wrong handling of Content-Length
assert(files["files"].filename == "file1.txt");
}

unittest { // use of unquoted strings in Content-Disposition
import vibe.stream.memory;

auto content_type = "multipart/form-data; boundary=\"AaB03x\"";

auto input = createMemoryStream(cast(ubyte[])(
"--AaB03x\r\n" ~
"Content-Disposition: form-data; name=submitname\r\n" ~
"\r\n" ~
"Larry\r\n" ~
"--AaB03x\r\n" ~
"Content-Disposition: form-data; name=files; filename=file1.txt\r\n" ~
"Content-Type: text/plain\r\n" ~
"Content-Length: 29\r\n" ~
"\r\n" ~
"... contents of file1.txt ...\r\n" ~
"--AaB03x--\r\n").dup, false);

FormFields fields;
FilePartFormFields files;

parseMultiPartForm(fields, files, content_type, input, 4096);

assert(fields["submitname"] == "Larry");
assert(files["files"].filename == "file1.txt");
}

/**
Single part of a multipart form.
Expand All @@ -220,24 +247,30 @@ struct FilePart {
private bool parseMultipartFormPart(InputStream)(InputStream stream, ref FormFields form, ref FilePartFormFields files, const(ubyte)[] boundary, size_t max_line_length)
if (isInputStream!InputStream)
{
import std.algorithm : countUntil;

InetHeaderMap headers;
stream.parseRFC5322Header(headers);
auto pv = "Content-Disposition" in headers;
enforce(pv, "invalid multipart");
auto cd = *pv;
string name;
auto pos = cd.indexOf("name=\"");
auto pos = cd.indexOf("name=");
if (pos >= 0) {
cd = cd[pos+6 .. $];
pos = cd.indexOf("\"");
name = cd[0 .. pos];
cd = cd[pos+5 .. $];
pos = cd.countUntil(';');
if (pos < 0) pos = cd.length;
if (cd[0] == '"') name = cd[1 .. pos-1];
else name = cd[0 .. pos];
}
string filename;
pos = cd.indexOf("filename=\"");
pos = cd.indexOf("filename=");
if (pos >= 0) {
cd = cd[pos+10 .. $];
pos = cd.indexOf("\"");
filename = cd[0 .. pos];
cd = cd[pos+9 .. $];
pos = cd.countUntil(';');
if (pos < 0) pos = cd.length;
if (cd[0] == '"') filename = cd[1 .. pos-1];
else filename = cd[0 .. pos];
}

if (filename.length > 0) {
Expand Down

0 comments on commit 6321174

Please sign in to comment.