Skip to content

Commit 7973210

Browse files
committed
Allow superfluos padding base64 decoding
1 parent 89d17b3 commit 7973210

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_binascii.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ def test_b2a_hex(self):
7070
b = self.type2test(b'helloo')
7171
self.assertEqual(binascii.hexlify(b), b'68656c6c6f6f')
7272

73+
def test_b2a_base64_padding(self):
74+
b = self.type2test(b'cDXriAy/7i02kBeDkN0m2RIDz85w6pwuHkt2PZ4VmT2PQc1TZs8Ebvf6eKDFcD/S====')
75+
self.assertEqual(binascii.a2b_base64(b), b'p5\xeb\x88\x0c\xbf\xee-6\x90\x17\x83\x90\xdd&\xd9\x12\x03\xcf\xcep\xea\x9c.\x1eKv=\x9e\x15\x99=\x8fA\xcdSf\xcf\x04n\xf7\xfax\xa0\xc5p?\xd2')
76+
7377
class ArrayBinASCIITest(BinASCIITest):
7478
def type2test(self, s):
7579
return array.array('b', list(s))

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,21 @@ PBytes doConvert(VirtualFrame frame, Object buffer,
171171
@TruffleBoundary
172172
private ByteSequenceStorage b64decode(byte[] data, int dataLen) {
173173
try {
174+
// Remove superfluous padding, Java refuses it but CPython ignores it
175+
int end;
176+
for (end = dataLen - 1; end >= 0; end--) {
177+
if (data[end] != '=') {
178+
break;
179+
}
180+
}
181+
// The length without the padding
182+
int unpaddedLen = end + 1;
183+
// Round up to a multiple of 4 to get correct minimal padding. Clamp to dataLen in
184+
// case the data is not padded correctly
185+
int decodeLen = Math.min((unpaddedLen + 3) & ~3, dataLen);
174186
// Using MIME decoder because that one skips over anything that is not the alphabet,
175187
// just like CPython does
176-
ByteBuffer result = Base64.getMimeDecoder().decode(ByteBuffer.wrap(data, 0, dataLen));
188+
ByteBuffer result = Base64.getMimeDecoder().decode(ByteBuffer.wrap(data, 0, decodeLen));
177189
return new ByteSequenceStorage(result.array(), result.limit());
178190
} catch (IllegalArgumentException e) {
179191
throw PRaiseNode.raiseUncached(this, BinasciiError, e);

0 commit comments

Comments
 (0)