Skip to content

Commit bd81036

Browse files
authored
Fixing base64 decoding error when input string is bad (#5170)
The following code would crash the previous version when calling MemFree: // 53 * A const char maliciousBase64Input[] = "AAAAAAAAAAAAAAAAAAAAAAAA" "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; int decodedSize = 0; unsigned char *decodedData = DecodeDataBase64( maliciousBase64Input, &decodedSize); if (decodedData) { MemFree(decodedData); } The reason is a lack of array bound checks in the decoding loop, which corrupted here the heap (though this is platform dependent). Adding the bound checks here prevents the memory corruption. Tested with encoding random data of sizes 0-1023 and comparing it with the decoded result.
1 parent eb81689 commit bd81036

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

src/rcore.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2671,13 +2671,24 @@ unsigned char *DecodeDataBase64(const char *text, int *outputSize)
26712671
for (int i = 0; i < dataSize;)
26722672
{
26732673
// Every 4 sixtets must generate 3 octets
2674+
if (i + 2 >= dataSize)
2675+
{
2676+
TRACELOG(LOG_WARNING, "BASE64 decoding error: Input data size is not valid");
2677+
break;
2678+
}
2679+
26742680
unsigned int sixtetA = base64DecodeTable[(unsigned char)text[i]];
26752681
unsigned int sixtetB = base64DecodeTable[(unsigned char)text[i + 1]];
2676-
unsigned int sixtetC = ((unsigned char)text[i + 2] != '=')? base64DecodeTable[(unsigned char)text[i + 2]] : 0;
2677-
unsigned int sixtetD = ((unsigned char)text[i + 3] != '=')? base64DecodeTable[(unsigned char)text[i + 3]] : 0;
2682+
unsigned int sixtetC = (i + 2 < dataSize && (unsigned char)text[i + 2] != '=')? base64DecodeTable[(unsigned char)text[i + 2]] : 0;
2683+
unsigned int sixtetD = (i + 3 < dataSize && (unsigned char)text[i + 3] != '=')? base64DecodeTable[(unsigned char)text[i + 3]] : 0;
26782684

26792685
unsigned int octetPack = (sixtetA << 18) | (sixtetB << 12) | (sixtetC << 6) | sixtetD;
26802686

2687+
if (outputCount + 3 > maxOutputSize)
2688+
{
2689+
TRACELOG(LOG_WARNING, "BASE64 decoding: Output data size is too small");
2690+
break;
2691+
}
26812692
decodedData[outputCount + 0] = (octetPack >> 16) & 0xff;
26822693
decodedData[outputCount + 1] = (octetPack >> 8) & 0xff;
26832694
decodedData[outputCount + 2] = octetPack & 0xff;

0 commit comments

Comments
 (0)