mirror of
https://github.com/yhirose/cpp-httplib
synced 2024-11-21 14:29:10 -07:00
Fixed #19
This commit is contained in:
parent
3dded8c3e3
commit
4fb2f51766
2 changed files with 56 additions and 24 deletions
49
httplib.h
49
httplib.h
|
@ -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 += ' ';
|
||||
|
|
31
test/test.cc
31
test/test.cc
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue