Skip to content

Commit 5eb32df

Browse files
Fix URL encoding for non-ASCII bytes (#738)
## Summary - Treat URL encoder input bytes as unsigned before splitting them into hex nibbles. - Add UTF-8 regression coverage for `café` encoding to `caf%C3%A9`. ## Why On platforms where `char` is signed, bytes >= 0x80 can become negative before the hex lookup. That can lead to undefined behavior or incorrect percent encoding for non-ASCII strings. ## Testing - `cmake -S . -B build -G Ninja -DICEBERG_BUILD_BUNDLE=OFF -DICEBERG_BUILD_REST=OFF -DICEBERG_BUILD_HIVE=OFF -DICEBERG_BUILD_SQL_CATALOG=OFF` - `cmake --build build --target util_test` - `ctest --test-dir build -R util_test --output-on-failure`
1 parent a68602c commit 5eb32df

2 files changed

Lines changed: 6 additions & 3 deletions

File tree

src/iceberg/test/url_encoder_test.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ TEST(UrlEncoderTest, Encode) {
4040
::testing::Eq("key%3Dvalue%26foo%3Dbar"));
4141
EXPECT_THAT(UrlEncoder::Encode("100%"), ::testing::Eq("100%25"));
4242
EXPECT_THAT(UrlEncoder::Encode("hello\x1fworld"), ::testing::Eq("hello%1Fworld"));
43+
EXPECT_THAT(UrlEncoder::Encode("caf\xC3\xA9"), ::testing::Eq("caf%C3%A9"));
4344
EXPECT_THAT(UrlEncoder::Encode(""), ::testing::Eq(""));
4445
}
4546

@@ -69,6 +70,7 @@ TEST(UrlEncoderTest, EncodeDecodeRoundTrip) {
6970
"key=value&foo=bar",
7071
"100%",
7172
"hello\x1Fworld",
73+
"caf\xC3\xA9",
7274
"special!@#$%^&*()chars",
7375
"mixed-123_test.file~ok",
7476
""};

src/iceberg/util/url_encoder.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ std::string UrlEncoder::Encode(std::string_view str_to_encode) {
4646
result.reserve(str_to_encode.size() * 3 / 2 /* Heuristic reservation */);
4747

4848
for (char c : str_to_encode) {
49-
if (IsUnreserved(c)) {
49+
auto b = static_cast<unsigned char>(c);
50+
if (IsUnreserved(b)) {
5051
result += c;
5152
} else {
5253
result += '%';
53-
result += kHexChars[c >> 4];
54-
result += kHexChars[c & 0xF];
54+
result += kHexChars[b >> 4];
55+
result += kHexChars[b & 0xF];
5556
}
5657
}
5758

0 commit comments

Comments
 (0)