From 6bea47aaefef2059ea4a5dfc01cd93e3aed11bdc Mon Sep 17 00:00:00 2001 From: Hafez Date: Mon, 8 Aug 2022 22:41:08 +0200 Subject: [PATCH] allow reading base64 files from a dataURI scheme (#2763) --- bits/04_base64.js | 4 +++- modules/04_base64.js | 4 +++- modules/04_base64.ts | 3 ++- test.js | 33 +++++++++++++++++++++++++++++---- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/bits/04_base64.js b/bits/04_base64.js index 53f40f5..0164e3f 100644 --- a/bits/04_base64.js +++ b/bits/04_base64.js @@ -48,7 +48,9 @@ function Base64_encode_pass(input) { function Base64_decode(input) { var o = ""; var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0; - input = input.replace(/[^\w\+\/\=]/g, ""); + input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64,/, '') + .replace(/[^\w\+\/\=]/g, ""); + for (var i = 0; i < input.length; ) { e1 = Base64_map.indexOf(input.charAt(i++)); e2 = Base64_map.indexOf(input.charAt(i++)); diff --git a/modules/04_base64.js b/modules/04_base64.js index 53f40f5..fdd658a 100644 --- a/modules/04_base64.js +++ b/modules/04_base64.js @@ -48,7 +48,9 @@ function Base64_encode_pass(input) { function Base64_decode(input) { var o = ""; var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0; - input = input.replace(/[^\w\+\/\=]/g, ""); + input = input.replace(/^data:.+\/.+;base64\,/,'') + .replace(/[^\w\+\/\=]/g, "") + for (var i = 0; i < input.length; ) { e1 = Base64_map.indexOf(input.charAt(i++)); e2 = Base64_map.indexOf(input.charAt(i++)); diff --git a/modules/04_base64.ts b/modules/04_base64.ts index 154a446..adbd40a 100644 --- a/modules/04_base64.ts +++ b/modules/04_base64.ts @@ -40,7 +40,8 @@ function Base64_encode_pass(input: string): string { function Base64_decode(input: string): string { var o = ""; var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0; - input = input.replace(/[^\w\+\/\=]/g, ""); + input = input.replace(/^data:.+\/.+;base64\,/,'') + .replace(/[^\w\+\/\=]/g, "") for(var i = 0; i < input.length;) { e1 = Base64_map.indexOf(input.charAt(i++)); e2 = Base64_map.indexOf(input.charAt(i++)); diff --git a/test.js b/test.js index 1c25e3e..f7d9cd5 100644 --- a/test.js +++ b/test.js @@ -688,6 +688,31 @@ describe('input formats', function() { it('should read base64 strings', function() { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'base64'), {type: 'base64'}); }); }); + + it('handles base64 within data URI scheme (gh-2762)', function() { + // Arrange + var fileInBase64 = 'TmFtZXMNCkhhZmV6DQpTYW0NCg=='; + var fileInBase64WithDataURIScheme = 'data:text/csv;base64,TmFtZXMNCkhhZmV6DQpTYW0NCg=='; + + // Act + var workBookFromRawBase64 = X.read(fileInBase64, { type: 'base64' }); + var workBookFromBase64WithinDataURI = X.read(fileInBase64WithDataURIScheme, { type: 'base64' }); + + // Assert + assert.deepStrictEqual(workBookFromRawBase64, workBookFromBase64WithinDataURI); + }); + it('handles base64 where data URI has no media type (gh-2762)', function() { + // Arrange + var fileInBase64 = 'TmFtZXMNCkhhZmV6DQpTYW0NCg=='; + var fileInBase64WithDataURIScheme = 'data:;base64,TmFtZXMNCkhhZmV6DQpTYW0NCg=='; + + // Act + var workBookFromRawBase64 = X.read(fileInBase64, { type: 'base64' }); + var workBookFromBase64WithinDataURI = X.read(fileInBase64WithDataURIScheme, { type: 'base64' }); + + // Assert + assert.deepStrictEqual(workBookFromRawBase64, workBookFromBase64WithinDataURI); + }); if(typeof Uint8Array !== 'undefined') it('should read array', function() { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'}); }); }); @@ -1393,7 +1418,7 @@ describe('parse features', function() { }); describe('data types formats', function() {[ - ['xlsx', paths.dtfxlsx], + ['xlsx', paths.dtfxlsx] ].forEach(function(m) { it(m[0], function() { var wb = X.read(fs.readFileSync(m[1]), {type: TYPE, cellDates: true}); var ws = wb.Sheets[wb.SheetNames[0]]; @@ -2109,7 +2134,7 @@ function plaintext_test(wb, raw) { var sheet = wb.Sheets[wb.SheetNames[0]]; plaintext_val.forEach(function(x) { var cell = get_cell(sheet, x[0]); - var tcval = x[2+(!!raw ? 1 : 0)]; + var tcval = x[2+(raw ? 1 : 0)]; var type = raw ? 's' : x[1]; if(x.length == 1) { if(cell) { assert.equal(cell.t, 'z'); assert.ok(!cell.v); } return; } assert.equal(cell.v, tcval); assert.equal(cell.t, type); @@ -2201,8 +2226,8 @@ describe('CSV', function() { var aoa = [ ["3a", "3 a", "3 a-1"], ["3b", "3 b", "3 b-1"], - ["3p", "3 P", "3 p-1"], - ] + ["3p", "3 P", "3 p-1"] + ]; var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1; for(var R = 0; R < 3; ++R) { assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);