From e93ba25f2cd156a6544a3c9894cd667906146874 Mon Sep 17 00:00:00 2001 From: ipknHama Date: Mon, 18 Sep 2017 02:39:46 +0900 Subject: Fix cookie parsing: Cookie doesn't have escaping mechanism. --- include/crow/middleware.h | 85 ++++++++++++----------------------------------- tests/unittest.cpp | 10 ++++-- 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 jar; std::unordered_map 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(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(); } -- cgit v1.2.3-54-g00ecf