From 16dd8a6eae222131887e1c6d023c559caad36d0c Mon Sep 17 00:00:00 2001 From: SheetJS Date: Wed, 15 Mar 2023 04:17:09 -0400 Subject: [PATCH] UTF16LE sans codepage (fixes #2898 h/t @brismuth) --- bits/02_codepage.js | 5 +++++ bits/18_cfb.js | 2 +- bits/87_read.js | 8 +++++++- types/index.d.ts | 3 +++ xlsx.mjs | 15 +++++++++++++-- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/bits/02_codepage.js b/bits/02_codepage.js index b388aa1..267f55e 100644 --- a/bits/02_codepage.js +++ b/bits/02_codepage.js @@ -41,6 +41,11 @@ function utf16leread(data/*:string*/)/*:string*/ { for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data.charCodeAt(2*i) + (data.charCodeAt(2*i+1)<<8)); return o.join(""); } +function utf16lereadu(data/*:Uint8Array*/)/*:string*/ { + var o/*:Array*/ = []; + for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data[2*i] + (data[2*i+1]<<8)); + return o.join(""); +} function utf16beread(data/*:string*/)/*:string*/ { var o/*:Array*/ = []; for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data.charCodeAt(2*i+1) + (data.charCodeAt(2*i)<<8)); diff --git a/bits/18_cfb.js b/bits/18_cfb.js index 5d770fc..7b4b3a8 100644 --- a/bits/18_cfb.js +++ b/bits/18_cfb.js @@ -73,7 +73,7 @@ function slice_by_16_tables(T) { for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF]; } var out = []; - for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' && typeof table.subarray == "function" ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); return out; } var TT = slice_by_16_tables(T0); diff --git a/bits/87_read.js b/bits/87_read.js index 0908895..bc3d32e 100644 --- a/bits/87_read.js +++ b/bits/87_read.js @@ -50,7 +50,13 @@ function read_plaintext_raw(data/*:RawData*/, o/*:ParseOpts*/)/*:Workbook*/ { function read_utf16(data/*:RawData*/, o/*:ParseOpts*/)/*:Workbook*/ { var d = data; if(o.type == 'base64') d = Base64_decode(d); - d = typeof $cptable !== "undefined" ? $cptable.utils.decode(1200, d.slice(2), 'str') : utf16leread(d.slice(2)); + if(typeof ArrayBuffer !== "undefined" && data instanceof ArrayBuffer) d = new Uint8Array(data); + d = typeof $cptable !== "undefined" ? $cptable.utils.decode(1200, d.slice(2), 'str') : ( + (has_buf && Buffer.isBuffer(data)) ? data.slice(2).toString("utf16le") : + (typeof Uint8Array !== "undefined" && d instanceof Uint8Array) ? ( + typeof TextDecoder !== "undefined" ? new TextDecoder("utf-16le").decode(d.slice(2)) : utf16lereadu(d.slice(2)) + ) : utf16leread(d.slice(2)) + ); o.type = "binary"; return read_plaintext(d, o); } diff --git a/types/index.d.ts b/types/index.d.ts index 3be4c8d..d565620 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -693,6 +693,9 @@ export interface CellObject { /** Range of enclosing array if formula is array formula (if applicable) */ F?: string; + /** If true, cell is a dynamic array formula (for supported file formats) */ + D?: boolean; + /** Rich text encoding (if applicable) */ r?: any; diff --git a/xlsx.mjs b/xlsx.mjs index 4ef6f00..833b270 100644 --- a/xlsx.mjs +++ b/xlsx.mjs @@ -47,6 +47,11 @@ function utf16leread(data/*:string*/)/*:string*/ { for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data.charCodeAt(2*i) + (data.charCodeAt(2*i+1)<<8)); return o.join(""); } +function utf16lereadu(data/*:Uint8Array*/)/*:string*/ { + var o/*:Array*/ = []; + for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data[2*i] + (data[2*i+1]<<8)); + return o.join(""); +} function utf16beread(data/*:string*/)/*:string*/ { var o/*:Array*/ = []; for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data.charCodeAt(2*i+1) + (data.charCodeAt(2*i)<<8)); @@ -1435,7 +1440,7 @@ function slice_by_16_tables(T) { for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF]; } var out = []; - for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' && typeof table.subarray == "function" ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); return out; } var TT = slice_by_16_tables(T0); @@ -25719,7 +25724,13 @@ function read_plaintext_raw(data/*:RawData*/, o/*:ParseOpts*/)/*:Workbook*/ { function read_utf16(data/*:RawData*/, o/*:ParseOpts*/)/*:Workbook*/ { var d = data; if(o.type == 'base64') d = Base64_decode(d); - d = typeof $cptable !== "undefined" ? $cptable.utils.decode(1200, d.slice(2), 'str') : utf16leread(d.slice(2)); + if(typeof ArrayBuffer !== "undefined" && data instanceof ArrayBuffer) d = new Uint8Array(data); + d = typeof $cptable !== "undefined" ? $cptable.utils.decode(1200, d.slice(2), 'str') : ( + (has_buf && Buffer.isBuffer(data)) ? data.slice(2).toString("utf16le") : + (typeof Uint8Array !== "undefined" && d instanceof Uint8Array) ? ( + typeof TextDecoder !== "undefined" ? new TextDecoder("utf-16le").decode(d.slice(2)) : utf16lereadu(d.slice(2)) + ) : utf16leread(d.slice(2)) + ); o.type = "binary"; return read_plaintext(d, o); }