fix(puter-js): account for base64 padding in estimateDataUrlSize (#3805)

Math.ceil(len * 3 / 4) over-counts by 1-2 bytes on padded payloads, so thumbnails at the size limit were wrongly rejected. Subtract padding like ai dataUriByteLength.
This commit is contained in:
Felix-Ayush
2026-09-08 22:33:33 -07:00
committed by GitHub
parent d7877359d4
commit 9bb5bffd01
2 changed files with 33 additions and 1 deletions
@@ -11,7 +11,8 @@ export const estimateDataUrlSize = (dataUrl) => {
if ( ! dataUrl ) return 0;
const commaIndex = dataUrl.indexOf(',');
const base64 = commaIndex === -1 ? dataUrl : dataUrl.slice(commaIndex + 1);
return Math.ceil(base64.length * 3 / 4);
const padding = base64.endsWith('==') ? 2 : (base64.endsWith('=') ? 1 : 0);
return Math.floor(base64.length * 3 / 4) - padding;
};
/**
@@ -0,0 +1,31 @@
import { describe, expect, it } from 'vitest';
import { estimateDataUrlSize } from './dataUrl.js';
// `estimateDataUrlSize` gates thumbnail uploads, so it must return decoded
// bytes — not `ceil(base64.length * 3 / 4)`, which over-counts by 1-2 bytes
// whenever the payload ends in `=` padding.
describe('estimateDataUrlSize', () => {
it('returns 0 for empty input', () => {
expect(estimateDataUrlSize('')).toBe(0);
});
it('sizes an unpadded payload', () => {
// 'ABC' -> 'QUJD'
expect(estimateDataUrlSize('data:text/plain;base64,QUJD')).toBe(3);
});
it('subtracts single `=` padding', () => {
// 'AB' -> 'QUI='
expect(estimateDataUrlSize('data:text/plain;base64,QUI=')).toBe(2);
});
it('subtracts double `==` padding', () => {
// 'A' -> 'QQ=='
expect(estimateDataUrlSize('data:text/plain;base64,QQ==')).toBe(1);
});
it('sizes raw base64 without a data URL prefix', () => {
expect(estimateDataUrlSize('QUI=')).toBe(2);
});
});