Search code examples
javascriptgoogle-chromebase64firefox4data-uri

HTML5 Data URI fails when a base64 null is followed by an =?


I'm doing some pretty unholy things with JavaScript, and I've run into a weird problem.

I am creating binary data that fills a buffer of a static size. If the content doesn't fill the buffer, the remainder is filled with null characters.

The next step is to convert to base64.

The size (bytes) isn't always a multiple of 3, so I may need to add padding to the end. The last bytes in the buffer are always null (actually, it's about a kb of nulls).

When I convert this to base64 on Firefox and Chrome, I get an ERR_INVALID_URL when I have a trailing '=', but it downloads fine when I don't.

For example:

var url = "data:application/octet-stream;base64,";

window.open(url + "AAAA"); // works
window.open(url + "AAAA="); // doesn't work
window.open(url + "icw="); // works

My files work, but they're not up to spec.

Is there a reason why this is invalid base64? More importantly, is this a bug or part of the specification?

Edit:

I've posted an answer that gives some of the oddities between Firefox and Chrome. Does anyone know what the standard specifies? Or is it one of those loose specifications that causes fragmentation? I'd like something definitive if possible.


Solution

  • The padding character = is used to fill up to a multiple of four code characters. As every three bytes of input are mapped onto four bytes of output, a number of input bytes that is not a multiple of three requires padding (a remainder of one byte requires == and a remainder of two bytes requires =).

    In you case AAAA already is a valid code word and doesn’t require padding.