Skip to content

Commit ab5d812

Browse files
committed
fix: encode_one signed char right-shift
1 parent fe4bdf6 commit ab5d812

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

include/boost/url/detail/impl/format_args.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,9 @@ encode_one(
212212
return;
213213
}
214214
*out++ = '%';
215-
*out++ = urls::detail::hexdigs[0][c>>4];
216-
*out++ = urls::detail::hexdigs[0][c&0xf];
215+
auto uc = static_cast<unsigned char>(c);
216+
*out++ = urls::detail::hexdigs[0][uc>>4];
217+
*out++ = urls::detail::hexdigs[0][uc&0xf];
217218
}
218219

219220
// get an unsigned value from format_args

test/unit/format.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,19 @@ struct format_test
954954
}
955955
}
956956

957+
void
958+
testHighByteEncode()
959+
{
960+
// signed char shift UB regression: encoding
961+
// a byte with the high bit set (e.g. 0x80)
962+
{
963+
url u = urls::format("/{}/",
964+
std::string(1, '\x80'));
965+
auto p = u.encoded_path();
966+
BOOST_TEST(p.find("%80") != core::string_view::npos);
967+
}
968+
}
969+
957970
void
958971
run()
959972
{
@@ -965,6 +978,7 @@ struct format_test
965978
testLLONGMIN();
966979
testCenterAlignPad();
967980
testColonInFirstSegment();
981+
testHighByteEncode();
968982
#endif
969983
}
970984
};

0 commit comments

Comments
 (0)