Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 46 additions & 10 deletions include/crow/multipart.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,27 +177,63 @@ namespace crow

void parse_body(std::string body)
{
std::string delimiter = dd + boundary;
std::string normal_delim = dd + boundary;
std::string final_delim = normal_delim + dd; // Create final delimiter to check against

bool is_final = false; // Create check for if final delimiter has been reached

// TODO(EDev): Exit on error
while (body != (crlf))
while (!is_final)
{
size_t found = body.find(delimiter);
if (found == std::string::npos)
// Find next regular and final delimiter
size_t next_normal = body.find(normal_delim);
size_t next_final = body.find(final_delim);

// Use the first boundary that appears
size_t found;

// If first boundary is final boundary, set is_final to true.
// Break ties between final and normal delimiter location by assigning priority to final
// This prevents treating final delim as a normal and then iterating again and producing an error
if (next_final != std::string::npos && (next_normal == std::string::npos || next_final <= next_normal))
{
found = next_final;
is_final = true;
}

else if (next_normal != std::string::npos)
{
found = next_normal;
}
else
{
// did not find delimiter; probably an ill-formed body; throw to indicate the issue to user
throw bad_request("Unable to find delimiter in multipart message. Probably ill-formed body");
}

// Extract the section before the boundary
std::string section = body.substr(0, found);
body.erase(0, found);

// Remove the matched delimiter
if (is_final)
{
body.erase(0, final_delim.length());
}
else
{
body.erase(0, normal_delim.length());
}

// Strip CRLF if present
if (body.compare(0, 2, crlf) == 0)
{
body.erase(0, 2);
}

// +2 is the CRLF.
// We don't check it and delete it so that the same delimiter can be used for The last delimiter (--delimiter--CRLF).
body.erase(0, found + delimiter.length() + 2);
if (!section.empty())
{
part parsed_section(parse_section(section));
part_map.emplace(
(get_header_object(parsed_section.headers, "Content-Disposition").params.find("name")->second),
get_header_object(parsed_section.headers, "Content-Disposition").params.at("name"),
parsed_section);
parts.push_back(std::move(parsed_section));
}
Expand Down
Loading