0

I'm trying to base64 decode a string, then convert that value to a char array for later use. The decode works fine, but then I get garbage data when converting.

Here's the code I have so far:

std::string encodedData = "VGVzdFN0cmluZw=="; //"TestString"
std::vector<BYTE> decodedData = base64_decode(encodedData);

char* decodedChar;
decodedChar = new char[decodedData.size() +1]; // +1 for the final 0
decodedChar[decodedData.size() + 1] = 0; // terminate the string
for (size_t i = 0; i < decodedData.size(); ++i) {
    decodedChar[i] = decodedData[i];
}

vector<BYTE> is a typedef of unsigned char BYTE, as taken from this SO answer. The base64 code is also from this answer (the most upvoted answer, not the accepted answer). When I run this code, I get the following value in the VisualStudio Text Visualiser:

TestStringÍ

I've also tried other conversion methods, such as:

char* decodedChar = reinterpret_cast< char *>(&decodedData[0]);

Which gives the following:

TestStringÍÍÍýýýýÝÝÝÝÝÝÝ*b4d“

Why am I getting the garbage data at the end of the string? What am i doing wrong?

EDIT: clarified which answer in the linked question I'm using

Waqar
  • 8,558
  • 4
  • 35
  • 43
Jay
  • 2,077
  • 5
  • 24
  • 39
  • those functions you linked already operate on `std::string` – Sebastian Hoffmann Jul 13 '20 at 12:23
  • I'm not sure I follow. I'm using those to convert a std::string to vector, which i then need as char[]. – Jay Jul 13 '20 at 12:25
  • 2
    `decodedChar = new char[decodedData.size() +1];` What are the valid indices of this array? `decodedChar[decodedData.size() + 1] = 0` What index does this assign to? Is that valid? – Karl Knechtel Jul 13 '20 at 12:32
  • I'm just going to point this out, because nobody else did so far: *The whole bloody point of base… encoding is to transform data into a form that can be stored in a string, even if the original data itself isn't suitable to be stored in a string, because it might contain bytes that are outside the set of characters valid in a string. For example null bytes, which might terminate a string.* The whole exercise of going from a base64 to a vector to a string is ill advised. You should **STOP** at the vector and keep it at that! – datenwolf Jul 13 '20 at 13:03

2 Answers2

3
char* decodedChar;
decodedChar = new char[decodedData.size() +1]; // +1 for the final 0

Why would you manually allocate a buffer and then copy to it when you have std::string available that does this for you?

Just do:

std::string encodedData = "VGVzdFN0cmluZw=="; //"TestString"
std::vector<BYTE> decodedData = base64_decode(encodedData);

std::string decodedString { decodedData.begin(), decodedData.end() };

std::cout << decodedString << '\n';

If you need a char * out of this, just use .c_str()

const char* cstr = decodedString.c_str();

If you need to pass this on to a function that takes char* as input, for example:

void someFunc(char* data);
//...
//call site
someFunc( &decodedString[0] );

We have a TON of functions and abstractions and containers in C++ that were made to improve upon the C language, and so that programmers wouldn't have to write things by hand and make same mistakes every time they code. It would be best if we use those functionalities wherever we can to avoid raw loops or to do simple modifications like this.

Waqar
  • 8,558
  • 4
  • 35
  • 43
2

You are writing beyond the last element of your allocated array, which can cause literally anything to happen (according to the C++ standard). You need decodedChar[decodedData.size()] = 0;

TonyK
  • 16,761
  • 4
  • 37
  • 72