Turbo-Base64
Turbo-Base64 copied to clipboard
Decoding on Apple Mac M1 Pro fails with valid Base64-encoded input
Hi @powturbo ,
I'm using this great lib of yours for decoding BASE64 encoded image data exported from Microsoft Outlook. While things work smoothly with all my test data, I have one image failing to be decoded properly. I have attached the file base64.zip containing a file base64.dat (10880 bytes) for your reference.
When I pass the entire encoded data (of size 10880 bytes) to tb64dec(), it returns 0 (== error) from within tb64v128dec() at line 136: if(!(rc=tb64xdec(ip, inlen&(64-1), op)) || vaddvq_u8(vshrq_n_u8(xv,7))) return 0; //decode all
Reason being: tb64xdec() returns 0 immediately because the argument (inlen&(64-1)) equals 0 (as inlen == 10880) which is checked within that function. I don't think this is an intended behaviour.
If I decode the exact same data in 4 byte BASE64 chunks by repeatedly calling tb64dec() with proper offsets into the data, everything works just fine, so I conclude that a) the input data is correctly BASE64 encoded (I also checked with several BASE64 validitors successfully) and b) the above return code 0 is not correct ( the comment "// decode all" behind "return 0;" also suggests that there may be some different behaviour intended.
I would even argue that whenever you pass data of a size which is a multiple of 64 bytes to the tb64dec() function, it will return 0 instead of the size of the decoded data.
I therefore suggest to change the code as follows:
File turbob64v128.c: [...] //BG DEL line 136: if(!(rc=tb64xdec(ip, inlen&(64-1), op)) || vaddvq_u8(vshrq_n_u8(xv,7))) return 0; //decode all //BG ADD line 136: size_t rc = 0; if (inlen&(64-1)) { // if inlen was not a multiple of 64 bytes, there's exactly inlen-(ip-in) == inlen&(64-1) bytes left to decode, but don't call if there's nothing left! if(!(rc=tb64xdec(ip, inlen&(64-1), op)) || vaddvq_u8(vshrq_n_u8(xv,7))) return 0; // failure! } //BG ADD end return (op-out)+rc;
Without having looked into it deeper, I think tb64v256dec() probably suffers from the same issue.
Or maybe its all me. Any feedback or comments?
Kind regards, Björn