Skip to content

Commit

Permalink
Fix base64 decode
Browse files Browse the repository at this point in the history
  • Loading branch information
rcaelers committed Mar 21, 2024
1 parent 23409b8 commit c1d28a3
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
15 changes: 13 additions & 2 deletions libs/utils/src/Base64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

#include "utils/Base64.hh"

#include <algorithm>
#include <string>

#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/transform_width.hpp>
Expand All @@ -32,8 +35,16 @@ Base64::decode(const std::string &val)
{
using namespace boost::archive::iterators;
using It = transform_width<binary_from_base64<std::string::const_iterator>, 8, 6>;
return boost::algorithm::trim_right_copy_if(std::string(It(std::begin(val)), It(std::end(val))),
[](char c) { return c == '\0'; });

// pad with '=' if input is not a multiple of 4
std::string input = val;
input.append(((4 - input.size() % 4) % 4), '=');

size_t num_padding_chars(std::count(input.begin(), input.end(), '='));
std::replace(input.begin(), input.end(), '=', 'A');
std::string output(It(input.begin()), It(input.end()));
output.erase(output.end() - static_cast<std::string::difference_type>(num_padding_chars), output.end());
return output;
}

std::string
Expand Down
43 changes: 43 additions & 0 deletions libs/utils/test/UnfoldTestUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#include "utils/Logging.hh"
#include "utils/StringUtils.hh"
#include "utils/Base64.hh"

#define BOOST_TEST_MODULE "unfold"
#include <boost/test/unit_test.hpp>
Expand Down Expand Up @@ -114,4 +115,46 @@ BOOST_AUTO_TEST_CASE(utils_empty_string_utf8_to_utf16)
BOOST_CHECK(s == L"");
}

BOOST_AUTO_TEST_CASE(utils_base64_encode)
{
std::string s = unfold::utils::Base64::encode("Hello World");
BOOST_CHECK_EQUAL(s, "SGVsbG8gV29ybGQ=");
}

BOOST_AUTO_TEST_CASE(utils_base64_decode)
{
std::string s = unfold::utils::Base64::decode("SGVsbG8gV29ybGQ=");
BOOST_CHECK_EQUAL(s, "Hello World");
}

BOOST_AUTO_TEST_CASE(utils_base64_decode_0_terminated)
{
std::string ref = {'\xe3', '\xeb', '\x54', '\x77', '\x79', '\x46', '\xba', '\x72', '\xfa', '\x85', '\x96', '\x60', '\x02',
'\x31', '\xb5', '\x85', '\xea', '\xe6', '\xaf', '\x8c', '\x43', '\x18', '\xf3', '\x5e', '\xaa', '\x52',
'\x0f', '\x40', '\xfb', '\xdd', '\xe2', '\x4f', '\xdc', '\xdd', '\x4c', '\xad', '\x19', '\x9d', '\x22',
'\x1f', '\xd4', '\x24', '\xb2', '\xbb', '\x2e', '\x27', '\xb3', '\x0d', '\xc3', '\xa5', '\xfc', '\x1c',
'\x76', '\xaf', '\x76', '\x10', '\xb0', '\xc5', '\xed', '\x83', '\x43', '\x3b', '\x55', '\x00'};

std::string decoded = unfold::utils::Base64::decode(
"4+tUd3lGunL6hZZgAjG1hermr4xDGPNeqlIPQPvd4k/c3UytGZ0iH9QksrsuJ7MNw6X8HHavdhCwxe2DQztVAA==");

BOOST_CHECK_EQUAL(decoded.size(), 64);
BOOST_CHECK_EQUAL(decoded, ref);
}

BOOST_AUTO_TEST_CASE(utils_base64_encode_0_terminated)
{
std::string ref = "4+tUd3lGunL6hZZgAjG1hermr4xDGPNeqlIPQPvd4k/c3UytGZ0iH9QksrsuJ7MNw6X8HHavdhCwxe2DQztVAA==";

std::string decoded = {'\xe3', '\xeb', '\x54', '\x77', '\x79', '\x46', '\xba', '\x72', '\xfa', '\x85', '\x96', '\x60', '\x02',
'\x31', '\xb5', '\x85', '\xea', '\xe6', '\xaf', '\x8c', '\x43', '\x18', '\xf3', '\x5e', '\xaa', '\x52',
'\x0f', '\x40', '\xfb', '\xdd', '\xe2', '\x4f', '\xdc', '\xdd', '\x4c', '\xad', '\x19', '\x9d', '\x22',
'\x1f', '\xd4', '\x24', '\xb2', '\xbb', '\x2e', '\x27', '\xb3', '\x0d', '\xc3', '\xa5', '\xfc', '\x1c',
'\x76', '\xaf', '\x76', '\x10', '\xb0', '\xc5', '\xed', '\x83', '\x43', '\x3b', '\x55', '\x00'};

std::string encoded = unfold::utils::Base64::encode(decoded);

BOOST_CHECK_EQUAL(encoded, ref);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit c1d28a3

Please sign in to comment.