From 36b85a1017b967a1cbb1bcce4de9f207a6888b11 Mon Sep 17 00:00:00 2001 From: Gregor Jasny Date: Mon, 18 Dec 2023 23:34:56 +0100 Subject: [PATCH] fix(util): avoid sign extension in base64 encodesr --- util/include/prometheus/detail/base64.h | 14 +++++++------- util/tests/unit/base64_test.cc | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/util/include/prometheus/detail/base64.h b/util/include/prometheus/detail/base64.h index 4adf6100..21c3e31d 100644 --- a/util/include/prometheus/detail/base64.h +++ b/util/include/prometheus/detail/base64.h @@ -37,9 +37,9 @@ inline std::string base64_encode(const std::string& input) { auto it = input.begin(); for (std::size_t i = 0; i < input.size() / 3; ++i) { - temp = (*it++) << 16; - temp += (*it++) << 8; - temp += (*it++); + temp = static_cast(*it++) << 16; + temp += static_cast(*it++) << 8; + temp += static_cast(*it++); encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); encoded.append(1, kEncodeLookup[(temp & 0x00000FC0) >> 6]); @@ -48,14 +48,14 @@ inline std::string base64_encode(const std::string& input) { switch (input.size() % 3) { case 1: - temp = (*it++) << 16; + temp = static_cast(*it++) << 16; encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); encoded.append(2, kPadCharacter); break; case 2: - temp = (*it++) << 16; - temp += (*it++) << 8; + temp = static_cast(*it++) << 16; + temp += static_cast(*it++) << 8; encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); encoded.append(1, kEncodeLookup[(temp & 0x00000FC0) >> 6]); @@ -118,7 +118,7 @@ inline std::string base64_decode(const std::string& input) { decoded.push_back((temp >> 16) & 0x000000FF); decoded.push_back((temp >> 8) & 0x000000FF); - decoded.push_back((temp)&0x000000FF); + decoded.push_back((temp) & 0x000000FF); } return decoded; diff --git a/util/tests/unit/base64_test.cc b/util/tests/unit/base64_test.cc index 1f05410a..7efba320 100644 --- a/util/tests/unit/base64_test.cc +++ b/util/tests/unit/base64_test.cc @@ -13,6 +13,12 @@ struct TestVector { }; const TestVector testVector[] = { + // RFC 3548 examples + {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+"}, + {"\x14\xfb\x9c\x03\xd9", "FPucA9k="}, + {"\x14\xfb\x9c\x03", "FPucAw=="}, + + // RFC 4648 examples {"", ""}, {"f", "Zg=="}, {"fo", "Zm8="}, @@ -20,6 +26,16 @@ const TestVector testVector[] = { {"foob", "Zm9vYg=="}, {"fooba", "Zm9vYmE="}, {"foobar", "Zm9vYmFy"}, + + // Wikipedia examples + {"sure.", "c3VyZS4="}, + {"sure", "c3VyZQ=="}, + {"sur", "c3Vy"}, + {"su", "c3U="}, + {"leasure.", "bGVhc3VyZS4="}, + {"easure.", "ZWFzdXJlLg=="}, + {"asure.", "YXN1cmUu"}, + {"sure.", "c3VyZS4="}, }; using namespace testing;