Fixed #19
This commit is contained in:
parent
3dded8c3e3
commit
4fb2f51766
39
httplib.h
39
httplib.h
@ -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 += ' ';
|
||||||
|
31
test/test.cc
31
test/test.cc
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user