1
0
mirror of synced 2025-04-20 11:47:43 +03:00
This commit is contained in:
yhirose 2017-12-03 22:31:00 -05:00
parent 3dded8c3e3
commit 4fb2f51766
2 changed files with 56 additions and 24 deletions

View File

@ -738,18 +738,21 @@ inline bool is_hex(char c, int& v)
return false; return false;
} }
inline int from_hex_to_i(const std::string& s, int i, int cnt, int& val) inline bool from_hex_to_i(const std::string& s, int i, int cnt, int& val)
{ {
val = 0; val = 0;
for (; s[i] && cnt; i++, cnt--) { for (; cnt; i++, cnt--) {
if (!s[i]) {
return false;
}
int v = 0; int v = 0;
if (is_hex(s[i], v)) { if (is_hex(s[i], v)) {
val = val * 16 + v; val = val * 16 + v;
} else { } else {
break; return false;
} }
} }
return --i; return true;
} }
inline size_t to_utf8(int code, char* buff) inline size_t to_utf8(int code, char* buff)
@ -791,30 +794,28 @@ inline std::string decode_url(const std::string& s)
for (int i = 0; s[i]; i++) { for (int i = 0; s[i]; i++) {
if (s[i] == '%') { if (s[i] == '%') {
i++; if (s[i + 1] && s[i + 1] == 'u') {
assert(s[i]);
if (s[i] == '%') {
result += s[i];
} else if (s[i] == 'u') {
// Unicode
i++;
assert(s[i]);
int val = 0; int val = 0;
i = from_hex_to_i(s, i, 4, val); if (from_hex_to_i(s, i + 2, 4, val)) {
// 4 digits Unicode codes
char buff[4]; char buff[4];
size_t len = to_utf8(val, buff); size_t len = to_utf8(val, buff);
if (len > 0) { if (len > 0) {
result.append(buff, len); result.append(buff, len);
} }
i += 5; // 'u0000'
} else {
result += s[i];
}
} else { } else {
// HEX
int val = 0; int val = 0;
i = from_hex_to_i(s, i, 2, val); if (from_hex_to_i(s, i + 1, 2, val)) {
// 2 digits hex codes
result += val; result += val;
i += 2; // '00'
} else {
result += s[i];
}
} }
} else if (s[i] == '+') { } else if (s[i] == '+') {
result += ' '; result += ' ';

View File

@ -151,6 +151,9 @@ protected:
svr_.get("/hi", [&](const Request& /*req*/, Response& res) { svr_.get("/hi", [&](const Request& /*req*/, Response& res) {
res.set_content("Hello World!", "text/plain"); res.set_content("Hello World!", "text/plain");
}) })
.get("/endwith%", [&](const Request& /*req*/, Response& res) {
res.set_content("Hello World!", "text/plain");
})
.get("/", [&](const Request& /*req*/, Response& res) { .get("/", [&](const Request& /*req*/, Response& res) {
res.set_redirect("/hi"); res.set_redirect("/hi");
}) })
@ -427,6 +430,34 @@ TEST_F(ServerTest, TooLongHeader)
EXPECT_EQ(400, res->status); EXPECT_EQ(400, res->status);
} }
TEST_F(ServerTest, PercentEncoding)
{
auto res = cli_.get("/e%6edwith%");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(200, res->status);
}
TEST_F(ServerTest, PercentEncodingUnicode)
{
auto res = cli_.get("/e%u006edwith%");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(200, res->status);
}
TEST_F(ServerTest, InvalidPercentEncoding)
{
auto res = cli_.get("/%endwith%");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(404, res->status);
}
TEST_F(ServerTest, InvalidPercentEncodingUnicode)
{
auto res = cli_.get("/%uendwith%");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(404, res->status);
}
class ServerTestWithAI_PASSIVE : public ::testing::Test { class ServerTestWithAI_PASSIVE : public ::testing::Test {
protected: protected:
ServerTestWithAI_PASSIVE() ServerTestWithAI_PASSIVE()