Fix error detection in 'base64Decode()'
Fixed a bug in initialization of 'base64DecodeChars' variable. Currently decoder do not fail on invalid Base64 strings. Added test-case to verify the fix. Also have made 'base64DecodeChars' to be computed at compile time. And added a test case to encode/decode string with non-printable charactes.
This commit is contained in:
parent
130284b850
commit
64a3b045c1
|
@ -4,6 +4,8 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
/* ----------- tests for util.hh ------------------------------------------------*/
|
/* ----------- tests for util.hh ------------------------------------------------*/
|
||||||
|
@ -282,6 +284,17 @@ namespace nix {
|
||||||
ASSERT_EQ(decoded, s);
|
ASSERT_EQ(decoded, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(base64Encode, encodeAndDecodeNonPrintable) {
|
||||||
|
char s[256];
|
||||||
|
std::iota(std::rbegin(s), std::rend(s), 0);
|
||||||
|
|
||||||
|
auto encoded = base64Encode(s);
|
||||||
|
auto decoded = base64Decode(encoded);
|
||||||
|
|
||||||
|
EXPECT_EQ(decoded.length(), 255);
|
||||||
|
ASSERT_EQ(decoded, s);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* base64Decode
|
* base64Decode
|
||||||
* --------------------------------------------------------------------------*/
|
* --------------------------------------------------------------------------*/
|
||||||
|
@ -294,6 +307,10 @@ namespace nix {
|
||||||
ASSERT_EQ(base64Decode("cXVvZCBlcmF0IGRlbW9uc3RyYW5kdW0="), "quod erat demonstrandum");
|
ASSERT_EQ(base64Decode("cXVvZCBlcmF0IGRlbW9uc3RyYW5kdW0="), "quod erat demonstrandum");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(base64Decode, decodeThrowsOnInvalidChar) {
|
||||||
|
ASSERT_THROW(base64Decode("cXVvZCBlcm_0IGRlbW9uc3RyYW5kdW0="), Error);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* toLower
|
* toLower
|
||||||
* --------------------------------------------------------------------------*/
|
* --------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -1436,8 +1436,7 @@ std::string filterANSIEscapes(const std::string & s, bool filterAll, unsigned in
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
constexpr char base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
static std::array<char, 256> base64DecodeChars;
|
|
||||||
|
|
||||||
string base64Encode(std::string_view s)
|
string base64Encode(std::string_view s)
|
||||||
{
|
{
|
||||||
|
@ -1462,12 +1461,15 @@ string base64Encode(std::string_view s)
|
||||||
|
|
||||||
string base64Decode(std::string_view s)
|
string base64Decode(std::string_view s)
|
||||||
{
|
{
|
||||||
static std::once_flag flag;
|
constexpr char npos = -1;
|
||||||
std::call_once(flag, [](){
|
constexpr std::array<char, 256> base64DecodeChars = [&]() {
|
||||||
base64DecodeChars = { (char)-1 };
|
std::array<char, 256> result{};
|
||||||
|
for (auto& c : result)
|
||||||
|
c = npos;
|
||||||
for (int i = 0; i < 64; i++)
|
for (int i = 0; i < 64; i++)
|
||||||
base64DecodeChars[(int) base64Chars[i]] = i;
|
result[base64Chars[i]] = i;
|
||||||
});
|
return result;
|
||||||
|
}();
|
||||||
|
|
||||||
string res;
|
string res;
|
||||||
unsigned int d = 0, bits = 0;
|
unsigned int d = 0, bits = 0;
|
||||||
|
@ -1477,7 +1479,7 @@ string base64Decode(std::string_view s)
|
||||||
if (c == '\n') continue;
|
if (c == '\n') continue;
|
||||||
|
|
||||||
char digit = base64DecodeChars[(unsigned char) c];
|
char digit = base64DecodeChars[(unsigned char) c];
|
||||||
if (digit == -1)
|
if (digit == npos)
|
||||||
throw Error("invalid character in Base64 string: '%c'", c);
|
throw Error("invalid character in Base64 string: '%c'", c);
|
||||||
|
|
||||||
bits += 6;
|
bits += 6;
|
||||||
|
|
Loading…
Reference in a new issue