Skip to content

Commit

Permalink
GH-1461 Remove addition of invalid = character
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed Nov 13, 2023
1 parent 09e7fc2 commit 00b2f99
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 8 deletions.
17 changes: 10 additions & 7 deletions libraries/libfc/src/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ std::string variant::as_string()const
return *reinterpret_cast<const bool*>(this) ? "true" : "false";
case blob_type:
if( get_blob().data.size() )
return base64_encode( get_blob().data.data(), get_blob().data.size() ) + "=";
return base64_encode( get_blob().data.data(), get_blob().data.size() );
return std::string();
case null_type:
return std::string();
Expand Down Expand Up @@ -533,10 +533,14 @@ blob variant::as_blob()const
{
const std::string& str = get_string();
if( str.size() == 0 ) return blob();
if( str.back() == '=' )
{
std::string b64 = base64_decode( get_string() );
return blob( { std::vector<char>( b64.begin(), b64.end() ) } );
try {
// pre-5.0 versions of variant added `=` to end of base64 encoded string in as_string() above.
// fc version of base64_decode allows for extra `=` at the end of the string.
// Other base64 decoders will not accept the extra `=`.
std::vector<char> b64 = base64_decode( str );
return blob( { std::move(b64) } );
} catch(const std::exception&) {
// unable to decode, return the raw chars
}
return blob( { std::vector<char>( str.begin(), str.end() ) } );
}
Expand Down Expand Up @@ -758,8 +762,7 @@ void to_variant( const blob& b, variant& v ) {
}

void from_variant( const variant& v, blob& b ) {
std::string _s = base64_decode(v.as_string());
b.data = std::vector<char>(_s.begin(), _s.end());
b.data = base64_decode(v.as_string());
}

void to_variant( const UInt<8>& n, variant& v ) { v = uint64_t(n); }
Expand Down
78 changes: 77 additions & 1 deletion libraries/libfc/test/variant/test_variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,87 @@ BOOST_AUTO_TEST_CASE(variant_format_string_limited)
const string target_result = format_prefix + a_short_list + " " +
"{" + "\"b\":\"" + b_short_list + "\",\"c\":\"" + c_short_list + "\"}" + " " +
"[\"" + d_short_list + "\",\"" + e_short_list + "\"]" + " " +
base64_encode( a_blob.data.data(), a_blob.data.size() ) + "=" + " " +
base64_encode( a_blob.data.data(), a_blob.data.size() ) + " " +
g_short_list;

BOOST_CHECK_EQUAL( result, target_result);
BOOST_CHECK_LT(result.size(), 1024 + 3 * mu.size());
}
}

BOOST_AUTO_TEST_CASE(variant_blob)
{
// Some test cases from https://github.com/ReneNyffenegger/cpp-base64
{
std::string a17_orig = "aaaaaaaaaaaaaaaaa";
std::string a17_encoded = "YWFhYWFhYWFhYWFhYWFhYWE=";
fc::mutable_variant_object mu;
mu("blob", blob{{a17_orig.begin(), a17_orig.end()}});
mu("str", a17_encoded);

BOOST_CHECK_EQUAL(mu["blob"].as_string(), a17_encoded);
std::vector<char> b64 = mu["str"].as_blob().data;
std::string_view b64_str(b64.data(), b64.size());
BOOST_CHECK_EQUAL(b64_str, a17_orig);
}
{
std::string s_6364 = "\x03" "\xef" "\xff" "\xf9";
std::string s_6364_encoded = "A+//+Q==";
fc::mutable_variant_object mu;
mu("blob", blob{{s_6364.begin(), s_6364.end()}});
mu("str", s_6364_encoded);

BOOST_CHECK_EQUAL(mu["blob"].as_string(), s_6364_encoded);
std::vector<char> b64 = mu["str"].as_blob().data;
std::string_view b64_str(b64.data(), b64.size());
BOOST_CHECK_EQUAL(b64_str, s_6364);
}
{
std::string org = "abc";
std::string encoded = "YWJj";

fc::mutable_variant_object mu;
mu("blob", blob{{org.begin(), org.end()}});
mu("str", encoded);

BOOST_CHECK_EQUAL(mu["blob"].as_string(), encoded);
std::vector<char> b64 = mu["str"].as_blob().data;
std::string_view b64_str(b64.data(), b64.size());
BOOST_CHECK_EQUAL(b64_str, org);
}
}

BOOST_AUTO_TEST_CASE(variant_blob_backwards_compatibility)
{
// pre-5.0 variant would add an additional `=` as a flag that the blob data was base64 encoded
// verify variant can process encoded data with the extra `=`
{
std::string a17_orig = "aaaaaaaaaaaaaaaaa";
std::string a17_encoded = "YWFhYWFhYWFhYWFhYWFhYWE=";
std::string a17_encoded_old = a17_encoded + '=';
fc::mutable_variant_object mu;
mu("blob", blob{{a17_orig.begin(), a17_orig.end()}});
mu("str", a17_encoded_old);

BOOST_CHECK_EQUAL(mu["blob"].as_string(), a17_encoded);
std::vector<char> b64 = mu["str"].as_blob().data;
std::string_view b64_str(b64.data(), b64.size());
BOOST_CHECK_EQUAL(b64_str, a17_orig);
}
{
std::string org = "abc";
std::string encoded = "YWJj";
std::string encoded_old = encoded + '=';

fc::mutable_variant_object mu;
mu("blob", blob{{org.begin(), org.end()}});
mu("str", encoded_old);

BOOST_CHECK_EQUAL(mu["blob"].as_string(), encoded);
std::vector<char> b64 = mu["str"].as_blob().data;
std::string_view b64_str(b64.data(), b64.size());
BOOST_CHECK_EQUAL(b64_str, org);
}
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 00b2f99

Please sign in to comment.