Skip to content

Commit 28d9593

Browse files
authored
use strict hex parsing in decode_query_component (#2472)
1 parent 7532932 commit 28d9593

2 files changed

Lines changed: 16 additions & 5 deletions

File tree

httplib.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9734,11 +9734,9 @@ inline std::string decode_query_component(const std::string &component,
97349734

97359735
for (size_t i = 0; i < component.size(); i++) {
97369736
if (component[i] == '%' && i + 2 < component.size()) {
9737-
std::string hex = component.substr(i + 1, 2);
9738-
char *end;
9739-
unsigned long value = std::strtoul(hex.c_str(), &end, 16);
9740-
if (end == hex.c_str() + 2) {
9741-
result += static_cast<char>(value);
9737+
auto val = 0;
9738+
if (detail::from_hex_to_i(component, i + 1, 2, val)) {
9739+
result += static_cast<char>(val);
97429740
i += 2;
97439741
} else {
97449742
result += component[i];

test/test.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,19 @@ TEST(DecodePathTest, UnicodeEncoding) {
386386
EXPECT_EQ("", decode_path_component("%uD800"));
387387
}
388388

389+
TEST(DecodeQueryTest, RejectsNonHexEscapes) {
390+
// A sign or whitespace inside the two-character escape window must not be
391+
// accepted as a valid percent-encoding; the sequence is passed through
392+
// literally, matching decode_uri_component / decode_path_component.
393+
EXPECT_EQ("%-1", decode_query_component("%-1", false));
394+
EXPECT_EQ("%-0", decode_query_component("%-0", false));
395+
EXPECT_EQ("%+5", decode_query_component("%+5", false));
396+
EXPECT_EQ("% 5", decode_query_component("% 5", false));
397+
// Well-formed escapes still decode.
398+
EXPECT_EQ("-", decode_query_component("%2D", false));
399+
EXPECT_EQ("A", decode_query_component("%41", false));
400+
}
401+
389402
TEST(SanitizeFilenameTest, VariousPatterns) {
390403
// Path traversal
391404
EXPECT_EQ("passwd", httplib::sanitize_filename("../../../etc/passwd"));

0 commit comments

Comments
 (0)