Skip to content

Commit

Permalink
Merge pull request #931 from Iuliean/master
Browse files Browse the repository at this point in the history
"crow::multipart::message throws when the boundary is empty or malformed
  • Loading branch information
The-EDev authored Oct 30, 2024
2 parents bd61a7d + 45a59c5 commit c10c20c
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 3 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ if(CROW_AMALGAMATE)
include/crow/ci_map.h
include/crow/common.h
include/crow/compression.h
include/crow/exceptions.h
include/crow/http_connection.h
include/crow/http_parser_merged.h
include/crow/http_request.h
Expand Down
14 changes: 14 additions & 0 deletions include/crow/exceptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once
#include <stdexcept>

namespace crow
{
struct bad_request : public std::runtime_error
{
bad_request(const std::string& what_arg)
: std::runtime_error(what_arg) {}

bad_request(const char* what_arg)
: std::runtime_error(what_arg) {}
};
}
13 changes: 10 additions & 3 deletions include/crow/multipart.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "crow/http_request.h"
#include "crow/returnable.h"
#include "crow/ci_map.h"
#include "crow/exceptions.h"

namespace crow
{
Expand Down Expand Up @@ -147,8 +148,14 @@ namespace crow
boundary(get_boundary(get_header_value("Content-Type")))
{
if (!boundary.empty())
{
content_type = "multipart/form-data; boundary=" + boundary;
parse_body(req.body);
parse_body(req.body);
}
else
{
throw bad_request("Empty boundary in multipart message");
}
}

private:
Expand Down Expand Up @@ -178,8 +185,8 @@ namespace crow
size_t found = body.find(delimiter);
if (found == std::string::npos)
{
// did not find delimiter; probably an ill-formed body; ignore the rest
break;
// 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");
}
std::string section = body.substr(0, found);

Expand Down
6 changes: 6 additions & 0 deletions include/crow/routing.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "crow/http_request.h"
#include "crow/utility.h"
#include "crow/logging.h"
#include "crow/exceptions.h"
#include "crow/websocket.h"
#include "crow/mustache.h"
#include "crow/middleware.h"
Expand Down Expand Up @@ -1813,6 +1814,11 @@ namespace crow // NOTE: Already documented in "crow/app.h"
{
throw;
}
catch (const bad_request& e)
{
res = response (400);
res.body = e.what();
}
catch (const std::exception& e)
{
CROW_LOG_ERROR << "An uncaught exception occurred: " << e.what();
Expand Down
48 changes: 48 additions & 0 deletions tests/unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2510,6 +2510,54 @@ TEST_CASE("multipart")

CHECK(test_string == res.body);
}

//Test against empty boundary
{
request req;
response res;
req.url = "/multipart";
req.add_header("Content-Type", "multipart/form-data; boundary=");
req.body = test_string;

app.handle_full(req, res);

CHECK(res.code == 400);
CHECK(res.body == "Empty boundary in multipart message");

}

//Boundary that differs from actual boundary
{
const char alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<std::mt19937::result_type> dist(0, sizeof(alphabet) - 2);
std::uniform_int_distribution<std::mt19937::result_type> boundary_sizes(1, 50);
std::array<std::string, 100> test_boundaries;

for (auto& boundary : test_boundaries)
{
const size_t boundary_size = boundary_sizes(rng);
boundary.reserve(boundary_size);
for (size_t idx = 0; idx < boundary_size; idx++)
boundary.push_back(alphabet[dist(rng)]);
}

for (const auto& boundary : test_boundaries)
{
request req;
response res;

req.url = "/multipart";
req.add_header("Content-Type", "multipart/form-data; boundary=" + boundary);
req.body = test_string;

app.handle_full(req, res);

CHECK(res.code == 400);
CHECK(res.body == "Unable to find delimiter in multipart message. Probably ill-formed body");
}
}
} // multipart

TEST_CASE("multipart_view")
Expand Down

0 comments on commit c10c20c

Please sign in to comment.