Skip to content

Commit

Permalink
Base64: enable optional output padding
Browse files Browse the repository at this point in the history
# fix memory leak (pInput wasn't freed in two places where Decode returns NULL)
  • Loading branch information
nofishonfriday committed Oct 17, 2022
1 parent 60104ce commit fc099cf
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
30 changes: 25 additions & 5 deletions Utility/Base64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,21 @@ Base64::~Base64()
//////////////////////////////////////////////////////////////////////
// Public Member Functions
//////////////////////////////////////////////////////////////////////
char* Base64::Encode(const char* pInput, int iInputLen)
char* Base64::Encode(const char* pInput, int iInputLen, const bool pad)
{
int iLen = iInputLen;
int iEncodedLen;

//calculate encoded buffer size
iEncodedLen = (int)(((iLen-1) * 4 / 3) + 3); // an extra for the null terminator!
if (pad)
iEncodedLen = 4 * ceil(iLen / 3.f);
else
iEncodedLen = ceil(4 * iLen / 3.f);

// allocate:
if (m_pEncodedBuf != NULL)
free (m_pEncodedBuf);
m_pEncodedBuf = new char[iEncodedLen];
m_pEncodedBuf = new char[iEncodedLen + 1];
char* pOutput = m_pEncodedBuf;

//let's step through the buffer (in groups of three bytes) and encode it...
Expand Down Expand Up @@ -96,6 +99,10 @@ char* Base64::Encode(const char* pInput, int iInputLen)
*(pOutput++) = cb64[(((unsigned char)pInput[1] & 0x0F) << 2)];
}
}

while (pad && pOutput < m_pEncodedBuf + iEncodedLen)
*(pOutput++) = '=';

// Null terminate
*pOutput = 0;

Expand All @@ -112,24 +119,37 @@ char* Base64::Decode(const char* pEncodedBuf, int *iOutLen)
*iOutLen = 0;

// allocate buffer to hold the decoded string:
iDecodedLen = (int)((strlen(pEncodedBuf)-1)*3/4)+1;
const int iEncodedLen = strlen(pEncodedBuf);
iDecodedLen = 3 * (iEncodedLen / 4.f);

// remove padding from decoded length
for(int i = iEncodedLen - 1; i >= 0 && pEncodedBuf[i] == '='; --i, --iDecodedLen);

if (m_pDecodedBuf != NULL)
free (m_pDecodedBuf);
m_pDecodedBuf = new char[iDecodedLen];

// allocate a local scratch buffer for decoding - work with BYTE's to avoid fatal sign extensions by compiler:
char* pInput = new char[strlen(pEncodedBuf)+1];
char* pInput = new char[iEncodedLen+1];
strcpy(pInput, pEncodedBuf);

// Loop for each byte of input:
iLen = iBlock = i = 0;
while (pInput[iBlock+i])
{
if ((unsigned char)pInput[iBlock+i] < 0x2B || (unsigned char)pInput[iBlock+i] > 0x7A)
{
delete [] pInput;
return NULL;
}
if (pInput[iBlock+i] == '=')
break;
pInput[iBlock+i] = cd64[(unsigned char)pInput[iBlock+i] - 0x2B];
if (pInput[iBlock+i] == '$')
{
delete [] pInput;
return NULL;
}
pInput[iBlock+i] -= 0x3E;

switch(i++)
Expand Down
2 changes: 1 addition & 1 deletion Utility/Base64.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Base64
virtual ~Base64();

char* Decode(const char* pInput, int *bufsize); //bufsize holds the decoded length
char* Encode(const char* pEncodedBuf, int iLen);
char* Encode(const char* pEncodedBuf, int iLen, bool pad = false);
char* m_pEncodedBuf;
char* m_pDecodedBuf;
};

0 comments on commit fc099cf

Please sign in to comment.