aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoripknHama <ipknhama@gmail.com>2017-09-18 02:39:46 +0900
committeripknHama <ipknhama@gmail.com>2017-09-18 02:39:46 +0900
commite93ba25f2cd156a6544a3c9894cd667906146874 (patch)
treee3b4910792d079b703d3cf89ddbd7655e11051bf
parent9c26e1ebdea1c43ac1a30a8f2ab83debc923cd56 (diff)
downloadcrow-e93ba25f2cd156a6544a3c9894cd667906146874.tar.gz
crow-e93ba25f2cd156a6544a3c9894cd667906146874.zip
Fix cookie parsing: Cookie doesn't have escaping mechanism.
-rw-r--r--include/crow/middleware.h85
-rw-r--r--tests/unittest.cpp10
2 files changed, 29 insertions, 66 deletions
diff --git a/include/crow/middleware.h b/include/crow/middleware.h
index 5e3ea32..3858018 100644
--- a/include/crow/middleware.h
+++ b/include/crow/middleware.h
@@ -35,10 +35,11 @@ namespace crow
std::unordered_map<std::string, std::string> jar;
std::unordered_map<std::string, std::string> cookies_to_add;
- std::string get_cookie(const std::string& key)
+ std::string get_cookie(const std::string& key) const
{
- if (jar.count(key))
- return jar[key];
+ auto cookie = jar.find(key);
+ if (cookie != jar.end())
+ return cookie->second;
return {};
}
@@ -73,69 +74,22 @@ namespace crow
if (pos == cookies.size())
break;
- std::string value;
+ size_t pos_semicolon = cookies.find(';', pos);
+ std::string value = cookies.substr(pos, pos_semicolon-pos);
- if (cookies[pos] == '"')
+ boost::trim(value);
+ if (value[0] == '"' && value[value.size()-1] == '"')
{
- int dquote_meet_count = 0;
- pos ++;
- size_t pos_dquote = pos-1;
- do
- {
- pos_dquote = cookies.find('"', pos_dquote+1);
- dquote_meet_count ++;
- } while(pos_dquote < cookies.size() && cookies[pos_dquote-1] == '\\');
- if (pos_dquote == cookies.npos)
- break;
-
- if (dquote_meet_count == 1)
- value = cookies.substr(pos, pos_dquote - pos);
- else
- {
- value.clear();
- value.reserve(pos_dquote-pos);
- for(size_t p = pos; p < pos_dquote; p++)
- {
- // FIXME minimal escaping
- if (cookies[p] == '\\' && p + 1 < pos_dquote)
- {
- p++;
- if (cookies[p] == '\\' || cookies[p] == '"')
- value += cookies[p];
- else
- {
- value += '\\';
- value += cookies[p];
- }
- }
- else
- value += cookies[p];
- }
- }
-
- ctx.jar.emplace(std::move(name), std::move(value));
- pos = cookies.find(";", pos_dquote+1);
- if (pos == cookies.npos)
- break;
- pos++;
- while(pos < cookies.size() && cookies[pos] == ' ') pos++;
- if (pos == cookies.size())
- break;
- }
- else
- {
- size_t pos_semicolon = cookies.find(';', pos);
- value = cookies.substr(pos, pos_semicolon - pos);
- boost::trim(value);
- ctx.jar.emplace(std::move(name), std::move(value));
- pos = pos_semicolon;
- if (pos == cookies.npos)
- break;
- pos ++;
- while(pos < cookies.size() && cookies[pos] == ' ') pos++;
- if (pos == cookies.size())
- break;
+ value = value.substr(1, value.size()-2);
}
+
+ ctx.jar.emplace(std::move(name), std::move(value));
+
+ pos = pos_semicolon;
+ if (pos == cookies.npos)
+ break;
+ pos++;
+ while(pos < cookies.size() && cookies[pos] == ' ') pos++;
}
}
@@ -143,7 +97,10 @@ namespace crow
{
for(auto& cookie:ctx.cookies_to_add)
{
- res.add_header("Set-Cookie", cookie.first + "=" + cookie.second);
+ if (cookie.second.empty())
+ res.add_header("Set-Cookie", cookie.first + "=\"\"");
+ else
+ res.add_header("Set-Cookie", cookie.first + "=" + cookie.second);
}
}
};
diff --git a/tests/unittest.cpp b/tests/unittest.cpp
index a85f7bc..303fa72 100644
--- a/tests/unittest.cpp
+++ b/tests/unittest.cpp
@@ -856,12 +856,16 @@ TEST(middleware_cookieparser)
std::string value1;
std::string value2;
+ std::string value3;
+ std::string value4;
CROW_ROUTE(app, "/")([&](const request& req){
{
auto& ctx = app.get_context<CookieParser>(req);
value1 = ctx.get_cookie("key1");
value2 = ctx.get_cookie("key2");
+ value3 = ctx.get_cookie("key3");
+ value4 = ctx.get_cookie("key4");
}
return "";
@@ -869,7 +873,7 @@ TEST(middleware_cookieparser)
decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
auto _ = async(launch::async, [&]{server.run();});
- std::string sendmsg = "GET /\r\nCookie: key1=value1; key2=\"val\\\"ue2\"\r\n\r\n";
+ std::string sendmsg = "GET /\r\nCookie: key1=value1; key2=\"val=ue2\"; key3=\"val\"ue3\"; key4=\"val\"ue4\"\r\n\r\n";
asio::io_service is;
{
asio::ip::tcp::socket c(is);
@@ -882,7 +886,9 @@ TEST(middleware_cookieparser)
}
{
ASSERT_EQUAL("value1", value1);
- ASSERT_EQUAL("val\"ue2", value2);
+ ASSERT_EQUAL("val=ue2", value2);
+ ASSERT_EQUAL("val\"ue3", value3);
+ ASSERT_EQUAL("val\"ue4", value4);
}
server.stop();
}