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;
}
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;
for (; s[i] && cnt; i++, cnt--) {
for (; cnt; i++, cnt--) {
if (!s[i]) {
return false;
}
int v = 0;
if (is_hex(s[i], v)) {
val = val * 16 + v;
} else {
break;
return false;
}
}
return --i;
return true;
}
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++) {
if (s[i] == '%') {
i++;
assert(s[i]);
if (s[i] == '%') {
result += s[i];
} else if (s[i] == 'u') {
// Unicode
i++;
assert(s[i]);
if (s[i + 1] && s[i + 1] == 'u') {
int val = 0;
i = from_hex_to_i(s, i, 4, val);
char buff[4];
size_t len = to_utf8(val, buff);
if (len > 0) {
result.append(buff, len);
if (from_hex_to_i(s, i + 2, 4, val)) {
// 4 digits Unicode codes
char buff[4];
size_t len = to_utf8(val, buff);
if (len > 0) {
result.append(buff, len);
}
i += 5; // 'u0000'
} else {
result += s[i];
}
} else {
// HEX
int val = 0;
i = from_hex_to_i(s, i, 2, val);
result += val;
if (from_hex_to_i(s, i + 1, 2, val)) {
// 2 digits hex codes
result += val;
i += 2; // '00'
} else {
result += s[i];
}
}
} else if (s[i] == '+') {
result += ' ';

View file

@ -151,6 +151,9 @@ protected:
svr_.get("/hi", [&](const Request& /*req*/, Response& res) {
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) {
res.set_redirect("/hi");
})
@ -427,6 +430,34 @@ TEST_F(ServerTest, TooLongHeader)
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 {
protected:
ServerTestWithAI_PASSIVE()