Use an unsigned accumulator in base64_encode (#2477)

* use an unsigned accumulator in base64_encode

* Forward-declare detail::base64_encode for split builds
This commit is contained in:
metsw24-max authored and GitHub committed 2026-07-01 20:12:00 -04:00
1 parent 9d159bb412
commit a7b886b9cb
2 files changed
+29 -1

No files matched your search

+3 -1
View File
@@ -4665,7 +4665,9 @@ inline std::string base64_encode(const std::string &in) {
std::string out; std::string out;
out.reserve(in.size()); out.reserve(in.size());
auto val = 0; // Unsigned: once four bytes are folded in the top bit is set, so the next
// `val << 8` would left-shift a negative int (undefined behaviour).
uint32_t val = 0;
auto valb = -6; auto valb = -6;
for (auto c : in) { for (auto c : in) {
+26
View File
@@ -420,6 +420,32 @@ TEST(SanitizeFilenameTest, VariousPatterns) {
EXPECT_EQ("", httplib::sanitize_filename(" ")); EXPECT_EQ("", httplib::sanitize_filename(" "));
} }
// Forward declaration: in split builds split.py strips `inline` and moves the
// definition into httplib.cc, so detail::base64_encode is not visible from the
// public httplib.h. Re-declaring it here lets the tests link against the symbol
// in both header-only and split builds.
namespace httplib {
namespace detail {
std::string base64_encode(const std::string &in);
} // namespace detail
} // namespace httplib
TEST(Base64EncodeTest, KnownAnswers) {
// RFC 4648 test vectors. Inputs of four bytes or more exercise the round
// where the accumulator's top bit is already set before the next shift.
EXPECT_EQ("", detail::base64_encode(""));
EXPECT_EQ("Zg==", detail::base64_encode("f"));
EXPECT_EQ("Zm8=", detail::base64_encode("fo"));
EXPECT_EQ("Zm9v", detail::base64_encode("foo"));
EXPECT_EQ("Zm9vYg==", detail::base64_encode("foob"));
EXPECT_EQ("Zm9vYmE=", detail::base64_encode("fooba"));
EXPECT_EQ("Zm9vYmFy", detail::base64_encode("foobar"));
// High bytes keep the top bit set across several rounds.
EXPECT_EQ("AAECA//+wIB/", detail::base64_encode(std::string(
"\x00\x01\x02\x03\xff\xfe\xc0\x80\x7f", 9)));
}
TEST(EncodeQueryParamTest, ParseUnescapedChararactersTest) { TEST(EncodeQueryParamTest, ParseUnescapedChararactersTest) {
string unescapedCharacters = "-_.!~*'()"; string unescapedCharacters = "-_.!~*'()";