Comparing version 1.0.8 to 1.1.0
736
cfb.js
@@ -5,3 +5,3 @@ /* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||
/*exported CFB */ | ||
/*global module, require:false, process:false, Buffer:false, Uint8Array:false */ | ||
/*global module, require:false, process:false, Buffer:false, Uint8Array:false, Uint16Array:false */ | ||
@@ -62,2 +62,4 @@ var Base64 = (function make_b64(){ | ||
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; | ||
// $FlowIgnore | ||
if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); }; | ||
} | ||
@@ -71,4 +73,10 @@ | ||
function new_unsafe_buf(len) { | ||
/* jshint -W056 */ | ||
return has_buf ? Buffer.allocUnsafe(len) : new Array(len); | ||
/* jshint +W056 */ | ||
} | ||
var s2a = function s2a(s) { | ||
if(has_buf) return Buffer.from(s, "binary"); | ||
if(has_buf) return Buffer_from(s, "binary"); | ||
return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; }); | ||
@@ -102,3 +110,2 @@ }; | ||
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat((bufs[0])) : ___toBuffer(bufs);}; | ||
// $FlowIgnore | ||
s2a = function(s) { return Buffer_from(s, "binary"); }; | ||
@@ -173,6 +180,107 @@ bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : __bconcat(bufs); }; | ||
/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ | ||
/* vim: set ts=2: */ | ||
/*exported CRC32 */ | ||
var CRC32; | ||
(function (factory) { | ||
/*jshint ignore:start */ | ||
/*eslint-disable */ | ||
factory(CRC32 = {}); | ||
/*eslint-enable */ | ||
/*jshint ignore:end */ | ||
}(function(CRC32) { | ||
CRC32.version = '1.2.0'; | ||
/* see perf/crc32table.js */ | ||
/*global Int32Array */ | ||
function signed_crc_table() { | ||
var c = 0, table = new Array(256); | ||
for(var n =0; n != 256; ++n){ | ||
c = n; | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
table[n] = c; | ||
} | ||
return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; | ||
} | ||
var T = signed_crc_table(); | ||
function crc32_bstr(bstr, seed) { | ||
var C = seed ^ -1, L = bstr.length - 1; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; | ||
C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; | ||
} | ||
if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_buf(buf, seed) { | ||
if(buf.length > 10000) return crc32_buf_8(buf, seed); | ||
var C = seed ^ -1, L = buf.length - 3; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
} | ||
while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_buf_8(buf, seed) { | ||
var C = seed ^ -1, L = buf.length - 7; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
} | ||
while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_str(str, seed) { | ||
var C = seed ^ -1; | ||
for(var i = 0, L=str.length, c, d; i < L;) { | ||
c = str.charCodeAt(i++); | ||
if(c < 0x80) { | ||
C = (C>>>8) ^ T[(C ^ c)&0xFF]; | ||
} else if(c < 0x800) { | ||
C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; | ||
} else if(c >= 0xD800 && c < 0xE000) { | ||
c = (c&1023)+64; d = str.charCodeAt(i++)&1023; | ||
C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; | ||
} else { | ||
C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; | ||
} | ||
} | ||
return C ^ -1; | ||
} | ||
CRC32.table = T; | ||
CRC32.bstr = crc32_bstr; | ||
CRC32.buf = crc32_buf; | ||
CRC32.str = crc32_str; | ||
})); | ||
/* [MS-CFB] v20171201 */ | ||
var CFB = (function _CFB(){ | ||
var exports = {}; | ||
exports.version = '1.0.8'; | ||
exports.version = '1.1.0'; | ||
/* [MS-CFB] 2.6.4 */ | ||
@@ -198,5 +306,71 @@ function namecmp(l, r) { | ||
} | ||
/* -------------------------------------------------------------------------- */ | ||
/* DOS Date format: | ||
high|YYYYYYYm.mmmddddd.HHHHHMMM.MMMSSSSS|low | ||
add 1980 to stored year | ||
stored second should be doubled | ||
*/ | ||
/* write JS date to buf as a DOS date */ | ||
function write_dos_date(buf, date) { | ||
if(typeof date === "string") date = new Date(date); | ||
var hms = date.getHours(); | ||
hms = hms << 6 | date.getMinutes(); | ||
hms = hms << 5 | (date.getSeconds()>>>1); | ||
buf.write_shift(2, hms); | ||
var ymd = (date.getFullYear() - 1980); | ||
ymd = ymd << 4 | (date.getMonth()+1); | ||
ymd = ymd << 5 | date.getDate(); | ||
buf.write_shift(2, ymd); | ||
} | ||
/* read four bytes from buf and interpret as a DOS date */ | ||
function parse_dos_date(buf) { | ||
var hms = buf.read_shift(2) & 0xFFFF; | ||
var ymd = buf.read_shift(2) & 0xFFFF; | ||
var val = new Date(); | ||
var d = ymd & 0x1F; ymd >>>= 5; | ||
var m = ymd & 0x0F; ymd >>>= 4; | ||
val.setMilliseconds(0); | ||
val.setFullYear(ymd + 1980); | ||
val.setMonth(m-1); | ||
val.setDate(d); | ||
var S = hms & 0x1F; hms >>>= 5; | ||
var M = hms & 0x3F; hms >>>= 6; | ||
val.setHours(hms); | ||
val.setMinutes(M); | ||
val.setSeconds(S<<1); | ||
return val; | ||
} | ||
function parse_extra_field(blob) { | ||
prep_blob(blob, 0); | ||
var o = {}; | ||
var flags = 0; | ||
while(blob.l <= blob.length - 4) { | ||
var type = blob.read_shift(2); | ||
var sz = blob.read_shift(2), tgt = blob.l + sz; | ||
var p = {}; | ||
switch(type) { | ||
/* UNIX-style Timestamps */ | ||
case 0x5455: { | ||
flags = blob.read_shift(1); | ||
if(flags & 1) p.mtime = blob.read_shift(4); | ||
/* for some reason, CD flag corresponds to LFH */ | ||
if(sz > 5) { | ||
if(flags & 2) p.atime = blob.read_shift(4); | ||
if(flags & 4) p.ctime = blob.read_shift(4); | ||
} | ||
if(p.mtime) p.mt = new Date(p.mtime*1000); | ||
} | ||
break; | ||
} | ||
blob.l = tgt; | ||
o[type] = p; | ||
} | ||
return o; | ||
} | ||
var fs; | ||
function get_fs() { return fs || (fs = require('fs')); } | ||
function parse(file, options) { | ||
if(file[0] == 0x50 && file[1] == 0x4b) return parse_zip(file, options); | ||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512"); | ||
@@ -222,2 +396,4 @@ var mver = 3; | ||
case 3: ssz = 512; break; case 4: ssz = 4096; break; | ||
case 0: if(mv[1] == 0) return parse_zip(file, options); | ||
/* falls through */ | ||
default: throw new Error("Major Version: Expected 3 or 4 saw " + mver); | ||
@@ -301,2 +477,3 @@ } | ||
function check_get_mver(blob) { | ||
if(blob[blob.l] == 0x50 && blob[blob.l + 1] == 0x4b) return [0, 0]; | ||
// header signature 8 | ||
@@ -619,2 +796,3 @@ blob.chk(HEADER_SIGNATURE, 'Header Signature: '); | ||
rebuild_cfb(cfb); | ||
if(_opts.fileType == 'zip') return write_zip(cfb, _opts); | ||
var L = (function(cfb){ | ||
@@ -814,2 +992,547 @@ var mini_size = 0, fat_size = 0; | ||
} | ||
/* node < 8.1 zlib does not expose bytesRead, so default to pure JS */ | ||
var _zlib; | ||
function use_zlib(zlib) { try { | ||
var InflateRaw = zlib.InflateRaw; | ||
var InflRaw = new InflateRaw(); | ||
InflRaw._processChunk(new Uint8Array([3, 0]), InflRaw._finishFlushFlag); | ||
if(InflRaw.bytesRead) _zlib = zlib; | ||
else throw new Error("zlib does not expose bytesRead"); | ||
} catch(e) {console.error("cannot use native zlib: " + (e.message || e)); } } | ||
function _inflateRawSync(payload, usz) { | ||
if(!_zlib) return _inflate(payload, usz); | ||
var InflateRaw = _zlib.InflateRaw; | ||
var InflRaw = new InflateRaw(); | ||
var out = InflRaw._processChunk(payload.slice(payload.l), InflRaw._finishFlushFlag); | ||
payload.l += InflRaw.bytesRead; | ||
return out; | ||
} | ||
function _deflateRawSync(payload) { | ||
return _zlib ? _zlib.deflateRawSync(payload) : _deflate(payload); | ||
} | ||
var CLEN_ORDER = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; | ||
/* LEN_ID = [ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285 ]; */ | ||
var LEN_LN = [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13 , 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 ]; | ||
/* DST_ID = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 ]; */ | ||
var DST_LN = [ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ]; | ||
function bit_swap_8(n) { var t = (((((n<<1)|(n<<11)) & 0x22110) | (((n<<5)|(n<<15)) & 0x88440))); return ((t>>16) | (t>>8) |t)&0xFF; } | ||
var use_typed_arrays = typeof Uint8Array !== 'undefined'; | ||
var bitswap8 = use_typed_arrays ? new Uint8Array(1<<8) : []; | ||
for(var q = 0; q < (1<<8); ++q) bitswap8[q] = bit_swap_8(q); | ||
function bit_swap_n(n, b) { | ||
var rev = bitswap8[n & 0xFF]; | ||
if(b <= 8) return rev >>> (8-b); | ||
rev = (rev << 8) | bitswap8[(n>>8)&0xFF]; | ||
if(b <= 16) return rev >>> (16-b); | ||
rev = (rev << 8) | bitswap8[(n>>16)&0xFF]; | ||
return rev >>> (24-b); | ||
} | ||
/* helpers for unaligned bit reads */ | ||
function read_bits_2(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 6 ? 0 : buf[h+1]<<8))>>>w)& 0x03; } | ||
function read_bits_3(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 5 ? 0 : buf[h+1]<<8))>>>w)& 0x07; } | ||
function read_bits_4(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 4 ? 0 : buf[h+1]<<8))>>>w)& 0x0F; } | ||
function read_bits_5(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 3 ? 0 : buf[h+1]<<8))>>>w)& 0x1F; } | ||
function read_bits_7(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 1 ? 0 : buf[h+1]<<8))>>>w)& 0x7F; } | ||
/* works up to n = 3 * 8 + 1 = 25 */ | ||
function read_bits_n(buf, bl, n) { | ||
var w = (bl&7), h = (bl>>>3), f = ((1<<n)-1); | ||
var v = buf[h] >>> w; | ||
if(n < 8 - w) return v & f; | ||
v |= buf[h+1]<<(8-w); | ||
if(n < 16 - w) return v & f; | ||
v |= buf[h+2]<<(16-w); | ||
if(n < 24 - w) return v & f; | ||
v |= buf[h+3]<<(24-w); | ||
return v & f; | ||
} | ||
/* until ArrayBuffer#realloc is a thing, fake a realloc */ | ||
function realloc(b, sz) { | ||
var L = b.length, M = 2*L > sz ? 2*L : sz + 5, i = 0; | ||
if(L >= sz) return b; | ||
if(has_buf) { | ||
var o = new_unsafe_buf(M); | ||
// $FlowIgnore | ||
if(b.copy) b.copy(o); | ||
else for(; i < b.length; ++i) o[i] = b[i]; | ||
return o; | ||
} else if(use_typed_arrays) { | ||
var a = new Uint8Array(M); | ||
if(a.set) a.set(b); | ||
else for(; i < b.length; ++i) a[i] = b[i]; | ||
return a; | ||
} | ||
b.length = M; | ||
return b; | ||
} | ||
/* zero-filled arrays for older browsers */ | ||
function zero_fill_array(n) { | ||
var o = new Array(n); | ||
for(var i = 0; i < n; ++i) o[i] = 0; | ||
return o; | ||
}var _deflate = (function() { | ||
var _deflateRaw = (function() { | ||
return function deflateRaw(data, out) { | ||
var boff = 0; | ||
while(boff < data.length) { | ||
var L = Math.min(0xFFFF, data.length - boff); | ||
var h = boff + L == data.length; | ||
/* TODO: this is only type 0 stored */ | ||
out.write_shift(1, +h); | ||
out.write_shift(2, L); | ||
out.write_shift(2, (~L) & 0xFFFF); | ||
while(L-- > 0) out[out.l++] = data[boff++]; | ||
} | ||
return out.l; | ||
}; | ||
})(); | ||
return function(data) { | ||
var buf = new_buf(50+Math.floor(data.length*1.1)); | ||
var off = _deflateRaw(data, buf); | ||
return buf.slice(0, off); | ||
}; | ||
})(); | ||
/* modified inflate function also moves original read head */ | ||
/* build tree (used for literals and lengths) */ | ||
function build_tree(clens, cmap, MAX) { | ||
var maxlen = 1, w = 0, i = 0, j = 0, ccode = 0, L = clens.length; | ||
var bl_count = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32); | ||
for(i = 0; i < 32; ++i) bl_count[i] = 0; | ||
for(i = L; i < MAX; ++i) clens[i] = 0; | ||
L = clens.length; | ||
var ctree = use_typed_arrays ? new Uint16Array(L) : zero_fill_array(L); // [] | ||
/* build code tree */ | ||
for(i = 0; i < L; ++i) { | ||
bl_count[(w = clens[i])]++; | ||
if(maxlen < w) maxlen = w; | ||
ctree[i] = 0; | ||
} | ||
bl_count[0] = 0; | ||
for(i = 1; i <= maxlen; ++i) bl_count[i+16] = (ccode = (ccode + bl_count[i-1])<<1); | ||
for(i = 0; i < L; ++i) { | ||
ccode = clens[i]; | ||
if(ccode != 0) ctree[i] = bl_count[ccode+16]++; | ||
} | ||
/* cmap[maxlen + 4 bits] = (off&15) + (lit<<4) reverse mapping */ | ||
var cleni = 0; | ||
for(i = 0; i < L; ++i) { | ||
cleni = clens[i]; | ||
if(cleni != 0) { | ||
ccode = bit_swap_n(ctree[i], maxlen)>>(maxlen-cleni); | ||
for(j = (1<<(maxlen + 4 - cleni)) - 1; j>=0; --j) | ||
cmap[ccode|(j<<cleni)] = (cleni&15) | (i<<4); | ||
} | ||
} | ||
return maxlen; | ||
} | ||
var fix_lmap = use_typed_arrays ? new Uint16Array(512) : zero_fill_array(512); | ||
var fix_dmap = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32); | ||
if(!use_typed_arrays) { | ||
for(var i = 0; i < 512; ++i) fix_lmap[i] = 0; | ||
for(i = 0; i < 32; ++i) fix_dmap[i] = 0; | ||
} | ||
(function() { | ||
var dlens = []; | ||
var i = 0; | ||
for(;i<32; i++) dlens.push(5); | ||
build_tree(dlens, fix_dmap, 32); | ||
var clens = []; | ||
i = 0; | ||
for(; i<=143; i++) clens.push(8); | ||
for(; i<=255; i++) clens.push(9); | ||
for(; i<=279; i++) clens.push(7); | ||
for(; i<=287; i++) clens.push(8); | ||
build_tree(clens, fix_lmap, 288); | ||
})(); | ||
var dyn_lmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768); | ||
var dyn_dmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768); | ||
var dyn_cmap = use_typed_arrays ? new Uint16Array(128) : zero_fill_array(128); | ||
var dyn_len_1 = 1, dyn_len_2 = 1; | ||
/* 5.5.3 Expanding Huffman Codes */ | ||
function dyn(data, boff) { | ||
/* nomenclature from RFC1951 refers to bit values; these are offset by the implicit constant */ | ||
var _HLIT = read_bits_5(data, boff) + 257; boff += 5; | ||
var _HDIST = read_bits_5(data, boff) + 1; boff += 5; | ||
var _HCLEN = read_bits_4(data, boff) + 4; boff += 4; | ||
var w = 0; | ||
/* grab and store code lengths */ | ||
var clens = use_typed_arrays ? new Uint8Array(19) : zero_fill_array(19); | ||
var ctree = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; | ||
var maxlen = 1; | ||
var bl_count = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8); | ||
var next_code = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8); | ||
var L = clens.length; /* 19 */ | ||
for(var i = 0; i < _HCLEN; ++i) { | ||
clens[CLEN_ORDER[i]] = w = read_bits_3(data, boff); | ||
if(maxlen < w) maxlen = w; | ||
bl_count[w]++; | ||
boff += 3; | ||
} | ||
/* build code tree */ | ||
var ccode = 0; | ||
bl_count[0] = 0; | ||
for(i = 1; i <= maxlen; ++i) next_code[i] = ccode = (ccode + bl_count[i-1])<<1; | ||
for(i = 0; i < L; ++i) if((ccode = clens[i]) != 0) ctree[i] = next_code[ccode]++; | ||
/* cmap[7 bits from stream] = (off&7) + (lit<<3) */ | ||
var cleni = 0; | ||
for(i = 0; i < L; ++i) { | ||
cleni = clens[i]; | ||
if(cleni != 0) { | ||
ccode = bitswap8[ctree[i]]>>(8-cleni); | ||
for(var j = (1<<(7-cleni))-1; j>=0; --j) dyn_cmap[ccode|(j<<cleni)] = (cleni&7) | (i<<3); | ||
} | ||
} | ||
/* read literal and dist codes at once */ | ||
var hcodes = []; | ||
maxlen = 1; | ||
for(; hcodes.length < _HLIT + _HDIST;) { | ||
ccode = dyn_cmap[read_bits_7(data, boff)]; | ||
boff += ccode & 7; | ||
switch((ccode >>>= 3)) { | ||
case 16: | ||
w = 3 + read_bits_2(data, boff); boff += 2; | ||
ccode = hcodes[hcodes.length - 1]; | ||
while(w-- > 0) hcodes.push(ccode); | ||
break; | ||
case 17: | ||
w = 3 + read_bits_3(data, boff); boff += 3; | ||
while(w-- > 0) hcodes.push(0); | ||
break; | ||
case 18: | ||
w = 11 + read_bits_7(data, boff); boff += 7; | ||
while(w -- > 0) hcodes.push(0); | ||
break; | ||
default: | ||
hcodes.push(ccode); | ||
if(maxlen < ccode) maxlen = ccode; | ||
break; | ||
} | ||
} | ||
/* build literal / length trees */ | ||
var h1 = hcodes.slice(0, _HLIT), h2 = hcodes.slice(_HLIT); | ||
for(i = _HLIT; i < 286; ++i) h1[i] = 0; | ||
for(i = _HDIST; i < 30; ++i) h2[i] = 0; | ||
dyn_len_1 = build_tree(h1, dyn_lmap, 286); | ||
dyn_len_2 = build_tree(h2, dyn_dmap, 30); | ||
return boff; | ||
} | ||
/* return [ data, bytesRead ] */ | ||
function inflate(data, usz) { | ||
/* shortcircuit for empty buffer [0x03, 0x00] */ | ||
if(data[0] == 3 && !(data[1] & 0x3)) { return [new_raw_buf(usz), 2]; } | ||
/* bit offset */ | ||
var boff = 0; | ||
/* header includes final bit and type bits */ | ||
var header = 0; | ||
var outbuf = new_unsafe_buf(usz ? usz : (1<<18)); | ||
var woff = 0; | ||
var OL = outbuf.length>>>0; | ||
var max_len_1 = 0, max_len_2 = 0; | ||
while((header&1) == 0) { | ||
header = read_bits_3(data, boff); boff += 3; | ||
if((header >>> 1) == 0) { | ||
/* Stored block */ | ||
if(boff & 7) boff += 8 - (boff&7); | ||
/* 2 bytes sz, 2 bytes bit inverse */ | ||
var sz = data[boff>>>3] | data[(boff>>>3)+1]<<8; | ||
boff += 32; | ||
/* push sz bytes */ | ||
if(!usz && OL < woff + sz) { outbuf = realloc(outbuf, woff + sz); OL = outbuf.length; } | ||
if(typeof data.copy === 'function') { | ||
// $FlowIgnore | ||
data.copy(outbuf, woff, boff>>>3, (boff>>>3)+sz); | ||
woff += sz; boff += 8*sz; | ||
} else while(sz-- > 0) { outbuf[woff++] = data[boff>>>3]; boff += 8; } | ||
continue; | ||
} else if((header >>> 1) == 1) { | ||
/* Fixed Huffman */ | ||
max_len_1 = 9; max_len_2 = 5; | ||
} else { | ||
/* Dynamic Huffman */ | ||
boff = dyn(data, boff); | ||
max_len_1 = dyn_len_1; max_len_2 = dyn_len_2; | ||
} | ||
if(!usz && (OL < woff + 32767)) { outbuf = realloc(outbuf, woff + 32767); OL = outbuf.length; } | ||
for(;;) { // while(true) is apparently out of vogue in modern JS circles | ||
/* ingest code and move read head */ | ||
var bits = read_bits_n(data, boff, max_len_1); | ||
var code = (header>>>1) == 1 ? fix_lmap[bits] : dyn_lmap[bits]; | ||
boff += code & 15; code >>>= 4; | ||
/* 0-255 are literals, 256 is end of block token, 257+ are copy tokens */ | ||
if(((code>>>8)&0xFF) === 0) outbuf[woff++] = code; | ||
else if(code == 256) break; | ||
else { | ||
code -= 257; | ||
var len_eb = (code < 8) ? 0 : ((code-4)>>2); if(len_eb > 5) len_eb = 0; | ||
var tgt = woff + LEN_LN[code]; | ||
/* length extra bits */ | ||
if(len_eb > 0) { | ||
tgt += read_bits_n(data, boff, len_eb); | ||
boff += len_eb; | ||
} | ||
/* dist code */ | ||
bits = read_bits_n(data, boff, max_len_2); | ||
code = (header>>>1) == 1 ? fix_dmap[bits] : dyn_dmap[bits]; | ||
boff += code & 15; code >>>= 4; | ||
var dst_eb = (code < 4 ? 0 : (code-2)>>1); | ||
var dst = DST_LN[code]; | ||
/* dist extra bits */ | ||
if(dst_eb > 0) { | ||
dst += read_bits_n(data, boff, dst_eb); | ||
boff += dst_eb; | ||
} | ||
/* in the common case, manual byte copy is faster than TA set / Buffer copy */ | ||
if(!usz && OL < tgt) { outbuf = realloc(outbuf, tgt); OL = outbuf.length; } | ||
while(woff < tgt) { outbuf[woff] = outbuf[woff - dst]; ++woff; } | ||
} | ||
} | ||
} | ||
return [usz ? outbuf : outbuf.slice(0, woff), (boff+7)>>>3]; | ||
} | ||
function _inflate(payload, usz) { | ||
var data = payload.slice(payload.l||0); | ||
var out = inflate(data, usz); | ||
payload.l += out[1]; | ||
return out[0]; | ||
} | ||
function warn_or_throw(wrn, msg) { | ||
if(wrn) { if(typeof console !== 'undefined') console.error(msg); } | ||
else throw new Error(msg); | ||
} | ||
function parse_zip(file, options) { | ||
var blob = file; | ||
prep_blob(blob, 0); | ||
var FileIndex = [], FullPaths = []; | ||
var o = { | ||
FileIndex: FileIndex, | ||
FullPaths: FullPaths | ||
}; | ||
init_cfb(o, { root: options.root }); | ||
/* find end of central directory, start just after signature */ | ||
var i = blob.length - 4; | ||
while((blob[i] != 0x50 || blob[i+1] != 0x4b || blob[i+2] != 0x05 || blob[i+3] != 0x06) && i >= 0) --i; | ||
blob.l = i + 4; | ||
/* parse end of central directory */ | ||
blob.l += 4; | ||
var fcnt = blob.read_shift(2); | ||
blob.l += 6; | ||
var start_cd = blob.read_shift(4); | ||
/* parse central directory */ | ||
blob.l = start_cd; | ||
for(i = 0; i < fcnt; ++i) { | ||
/* trust local file header instead of CD entry */ | ||
blob.l += 20; | ||
var csz = blob.read_shift(4); | ||
var usz = blob.read_shift(4); | ||
var namelen = blob.read_shift(2); | ||
var efsz = blob.read_shift(2); | ||
var fcsz = blob.read_shift(2); | ||
blob.l += 8; | ||
var offset = blob.read_shift(4); | ||
var EF = parse_extra_field(blob.slice(blob.l+namelen, blob.l+namelen+efsz)); | ||
blob.l += namelen + efsz + fcsz; | ||
var L = blob.l; | ||
blob.l = offset + 4; | ||
parse_local_file(blob, csz, usz, o, EF); | ||
blob.l = L; | ||
} | ||
return o; | ||
} | ||
/* head starts just after local file header signature */ | ||
function parse_local_file(blob, csz, usz, o, EF) { | ||
/* [local file header] */ | ||
blob.l += 2; | ||
var flags = blob.read_shift(2); | ||
var meth = blob.read_shift(2); | ||
var date = parse_dos_date(blob); | ||
if(flags & 0x2041) throw new Error("Unsupported ZIP encryption"); | ||
var crc32 = blob.read_shift(4); | ||
var _csz = blob.read_shift(4); | ||
var _usz = blob.read_shift(4); | ||
var namelen = blob.read_shift(2); | ||
var efsz = blob.read_shift(2); | ||
// TODO: flags & (1<<11) // UTF8 | ||
var name = ""; for(var i = 0; i < namelen; ++i) name += String.fromCharCode(blob[blob.l++]); | ||
if(efsz) { | ||
var ef = parse_extra_field(blob.slice(blob.l, blob.l + efsz)); | ||
if((ef[0x5455]||{}).mt) date = ef[0x5455].mt; | ||
if(((EF||{})[0x5455]||{}).mt) date = EF[0x5455].mt; | ||
} | ||
blob.l += efsz; | ||
/* [encryption header] */ | ||
/* [file data] */ | ||
var data = blob.slice(blob.l, blob.l + _csz); | ||
switch(meth) { | ||
case 8: data = _inflateRawSync(blob, _usz); break; | ||
case 0: break; | ||
default: throw new Error("Unsupported ZIP Compression method " + meth); | ||
} | ||
/* [data descriptor] */ | ||
var wrn = false; | ||
if(flags & 8) { | ||
crc32 = blob.read_shift(4); | ||
if(crc32 == 0x08074b50) { crc32 = blob.read_shift(4); wrn = true; } | ||
_csz = blob.read_shift(4); | ||
_usz = blob.read_shift(4); | ||
} | ||
if(_csz != csz) warn_or_throw(wrn, "Bad compressed size: " + csz + " != " + _csz); | ||
if(_usz != usz) warn_or_throw(wrn, "Bad uncompressed size: " + usz + " != " + _usz); | ||
var _crc32 = CRC32.buf(data, 0); | ||
if(crc32 != _crc32) warn_or_throw(wrn, "Bad CRC32 checksum: " + crc32 + " != " + _crc32); | ||
cfb_add(o, name, data, {unsafe: true, mt: date}); | ||
} | ||
function write_zip(cfb, options) { | ||
var _opts = options || {}; | ||
var out = [], cdirs = []; | ||
var o = new_buf(1); | ||
var method = (_opts.compression ? 8 : 0), flags = 0; | ||
var desc = false; | ||
if(desc) flags |= 8; | ||
var i = 0, j = 0; | ||
var start_cd = 0, fcnt = 0; | ||
var root = cfb.FullPaths[0], fp = root, fi = cfb.FileIndex[0]; | ||
var crcs = []; | ||
var sz_cd = 0; | ||
for(i = 1; i < cfb.FullPaths.length; ++i) { | ||
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i]; | ||
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue; | ||
var start = start_cd; | ||
/* TODO: CP437 filename */ | ||
var namebuf = new_buf(fp.length); | ||
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F); | ||
namebuf = namebuf.slice(0, namebuf.l); | ||
crcs[fcnt] = CRC32.buf(fi.content, 0); | ||
var outbuf = fi.content; | ||
if(method == 8) outbuf = _deflateRawSync(outbuf); | ||
/* local file header */ | ||
o = new_buf(30); | ||
o.write_shift(4, 0x04034b50); | ||
o.write_shift(2, 20); | ||
o.write_shift(2, flags); | ||
o.write_shift(2, method); | ||
/* TODO: last mod file time/date */ | ||
if(fi.mt) write_dos_date(o, fi.mt); | ||
else o.write_shift(4, 0); | ||
o.write_shift(-4, (flags & 8) ? 0 : crcs[fcnt]); | ||
o.write_shift(4, (flags & 8) ? 0 : outbuf.length); | ||
o.write_shift(4, (flags & 8) ? 0 : fi.content.length); | ||
o.write_shift(2, namebuf.length); | ||
o.write_shift(2, 0); | ||
start_cd += o.length; | ||
out.push(o); | ||
start_cd += namebuf.length; | ||
out.push(namebuf); | ||
/* TODO: encryption header ? */ | ||
start_cd += outbuf.length; | ||
out.push(outbuf); | ||
/* data descriptor */ | ||
if(flags & 8) { | ||
o = new_buf(12); | ||
o.write_shift(-4, crcs[fcnt]); | ||
o.write_shift(4, outbuf.length); | ||
o.write_shift(4, fi.content.length); | ||
start_cd += o.l; | ||
out.push(o); | ||
} | ||
/* central directory */ | ||
o = new_buf(46); | ||
o.write_shift(4, 0x02014b50); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 20); | ||
o.write_shift(2, flags); | ||
o.write_shift(2, method); | ||
o.write_shift(4, 0); /* TODO: last mod file time/date */ | ||
o.write_shift(-4, crcs[fcnt]); | ||
o.write_shift(4, outbuf.length); | ||
o.write_shift(4, fi.content.length); | ||
o.write_shift(2, namebuf.length); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(4, 0); | ||
o.write_shift(4, start); | ||
sz_cd += o.l; | ||
cdirs.push(o); | ||
sz_cd += namebuf.length; | ||
cdirs.push(namebuf); | ||
++fcnt; | ||
} | ||
/* end of central directory */ | ||
o = new_buf(22); | ||
o.write_shift(4, 0x06054b50); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, fcnt); | ||
o.write_shift(2, fcnt); | ||
o.write_shift(4, sz_cd); | ||
o.write_shift(4, start_cd); | ||
o.write_shift(2, 0); | ||
return bconcat(([bconcat((out)), bconcat(cdirs), o])); | ||
} | ||
function cfb_new(opts) { | ||
@@ -841,2 +1564,4 @@ var o = ({}); | ||
if(opts.CLSID) file.clsid = opts.CLSID; | ||
if(opts.mt) file.mt = opts.mt; | ||
if(opts.ct) file.ct = opts.ct; | ||
} | ||
@@ -885,2 +1610,5 @@ return file; | ||
bconcat: bconcat, | ||
use_zlib: use_zlib, | ||
_deflateRaw: _deflate, | ||
_inflateRaw: _inflate, | ||
consts: consts | ||
@@ -887,0 +1615,0 @@ }; |
@@ -7,2 +7,6 @@ # CHANGELOG | ||
## 1.1.0 (2018-09-04) | ||
* Support for ZIP file format | ||
## 1.0.6 (2018-04-09) | ||
@@ -9,0 +13,0 @@ |
736
dist/cfb.js
@@ -5,3 +5,3 @@ /* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||
/*exported CFB */ | ||
/*global module, require:false, process:false, Buffer:false, Uint8Array:false */ | ||
/*global module, require:false, process:false, Buffer:false, Uint8Array:false, Uint16Array:false */ | ||
@@ -62,2 +62,4 @@ var Base64 = (function make_b64(){ | ||
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; | ||
// $FlowIgnore | ||
if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); }; | ||
} | ||
@@ -71,4 +73,10 @@ | ||
function new_unsafe_buf(len) { | ||
/* jshint -W056 */ | ||
return has_buf ? Buffer.allocUnsafe(len) : new Array(len); | ||
/* jshint +W056 */ | ||
} | ||
var s2a = function s2a(s) { | ||
if(has_buf) return Buffer.from(s, "binary"); | ||
if(has_buf) return Buffer_from(s, "binary"); | ||
return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; }); | ||
@@ -102,3 +110,2 @@ }; | ||
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat((bufs[0])) : ___toBuffer(bufs);}; | ||
// $FlowIgnore | ||
s2a = function(s) { return Buffer_from(s, "binary"); }; | ||
@@ -173,6 +180,107 @@ bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : __bconcat(bufs); }; | ||
/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ | ||
/* vim: set ts=2: */ | ||
/*exported CRC32 */ | ||
var CRC32; | ||
(function (factory) { | ||
/*jshint ignore:start */ | ||
/*eslint-disable */ | ||
factory(CRC32 = {}); | ||
/*eslint-enable */ | ||
/*jshint ignore:end */ | ||
}(function(CRC32) { | ||
CRC32.version = '1.2.0'; | ||
/* see perf/crc32table.js */ | ||
/*global Int32Array */ | ||
function signed_crc_table() { | ||
var c = 0, table = new Array(256); | ||
for(var n =0; n != 256; ++n){ | ||
c = n; | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
table[n] = c; | ||
} | ||
return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; | ||
} | ||
var T = signed_crc_table(); | ||
function crc32_bstr(bstr, seed) { | ||
var C = seed ^ -1, L = bstr.length - 1; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; | ||
C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; | ||
} | ||
if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_buf(buf, seed) { | ||
if(buf.length > 10000) return crc32_buf_8(buf, seed); | ||
var C = seed ^ -1, L = buf.length - 3; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
} | ||
while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_buf_8(buf, seed) { | ||
var C = seed ^ -1, L = buf.length - 7; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
} | ||
while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_str(str, seed) { | ||
var C = seed ^ -1; | ||
for(var i = 0, L=str.length, c, d; i < L;) { | ||
c = str.charCodeAt(i++); | ||
if(c < 0x80) { | ||
C = (C>>>8) ^ T[(C ^ c)&0xFF]; | ||
} else if(c < 0x800) { | ||
C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; | ||
} else if(c >= 0xD800 && c < 0xE000) { | ||
c = (c&1023)+64; d = str.charCodeAt(i++)&1023; | ||
C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; | ||
} else { | ||
C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; | ||
} | ||
} | ||
return C ^ -1; | ||
} | ||
CRC32.table = T; | ||
CRC32.bstr = crc32_bstr; | ||
CRC32.buf = crc32_buf; | ||
CRC32.str = crc32_str; | ||
})); | ||
/* [MS-CFB] v20171201 */ | ||
var CFB = (function _CFB(){ | ||
var exports = {}; | ||
exports.version = '1.0.8'; | ||
exports.version = '1.1.0'; | ||
/* [MS-CFB] 2.6.4 */ | ||
@@ -198,5 +306,71 @@ function namecmp(l, r) { | ||
} | ||
/* -------------------------------------------------------------------------- */ | ||
/* DOS Date format: | ||
high|YYYYYYYm.mmmddddd.HHHHHMMM.MMMSSSSS|low | ||
add 1980 to stored year | ||
stored second should be doubled | ||
*/ | ||
/* write JS date to buf as a DOS date */ | ||
function write_dos_date(buf, date) { | ||
if(typeof date === "string") date = new Date(date); | ||
var hms = date.getHours(); | ||
hms = hms << 6 | date.getMinutes(); | ||
hms = hms << 5 | (date.getSeconds()>>>1); | ||
buf.write_shift(2, hms); | ||
var ymd = (date.getFullYear() - 1980); | ||
ymd = ymd << 4 | (date.getMonth()+1); | ||
ymd = ymd << 5 | date.getDate(); | ||
buf.write_shift(2, ymd); | ||
} | ||
/* read four bytes from buf and interpret as a DOS date */ | ||
function parse_dos_date(buf) { | ||
var hms = buf.read_shift(2) & 0xFFFF; | ||
var ymd = buf.read_shift(2) & 0xFFFF; | ||
var val = new Date(); | ||
var d = ymd & 0x1F; ymd >>>= 5; | ||
var m = ymd & 0x0F; ymd >>>= 4; | ||
val.setMilliseconds(0); | ||
val.setFullYear(ymd + 1980); | ||
val.setMonth(m-1); | ||
val.setDate(d); | ||
var S = hms & 0x1F; hms >>>= 5; | ||
var M = hms & 0x3F; hms >>>= 6; | ||
val.setHours(hms); | ||
val.setMinutes(M); | ||
val.setSeconds(S<<1); | ||
return val; | ||
} | ||
function parse_extra_field(blob) { | ||
prep_blob(blob, 0); | ||
var o = {}; | ||
var flags = 0; | ||
while(blob.l <= blob.length - 4) { | ||
var type = blob.read_shift(2); | ||
var sz = blob.read_shift(2), tgt = blob.l + sz; | ||
var p = {}; | ||
switch(type) { | ||
/* UNIX-style Timestamps */ | ||
case 0x5455: { | ||
flags = blob.read_shift(1); | ||
if(flags & 1) p.mtime = blob.read_shift(4); | ||
/* for some reason, CD flag corresponds to LFH */ | ||
if(sz > 5) { | ||
if(flags & 2) p.atime = blob.read_shift(4); | ||
if(flags & 4) p.ctime = blob.read_shift(4); | ||
} | ||
if(p.mtime) p.mt = new Date(p.mtime*1000); | ||
} | ||
break; | ||
} | ||
blob.l = tgt; | ||
o[type] = p; | ||
} | ||
return o; | ||
} | ||
var fs; | ||
function get_fs() { return fs || (fs = require('fs')); } | ||
function parse(file, options) { | ||
if(file[0] == 0x50 && file[1] == 0x4b) return parse_zip(file, options); | ||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512"); | ||
@@ -222,2 +396,4 @@ var mver = 3; | ||
case 3: ssz = 512; break; case 4: ssz = 4096; break; | ||
case 0: if(mv[1] == 0) return parse_zip(file, options); | ||
/* falls through */ | ||
default: throw new Error("Major Version: Expected 3 or 4 saw " + mver); | ||
@@ -301,2 +477,3 @@ } | ||
function check_get_mver(blob) { | ||
if(blob[blob.l] == 0x50 && blob[blob.l + 1] == 0x4b) return [0, 0]; | ||
// header signature 8 | ||
@@ -619,2 +796,3 @@ blob.chk(HEADER_SIGNATURE, 'Header Signature: '); | ||
rebuild_cfb(cfb); | ||
if(_opts.fileType == 'zip') return write_zip(cfb, _opts); | ||
var L = (function(cfb){ | ||
@@ -814,2 +992,547 @@ var mini_size = 0, fat_size = 0; | ||
} | ||
/* node < 8.1 zlib does not expose bytesRead, so default to pure JS */ | ||
var _zlib; | ||
function use_zlib(zlib) { try { | ||
var InflateRaw = zlib.InflateRaw; | ||
var InflRaw = new InflateRaw(); | ||
InflRaw._processChunk(new Uint8Array([3, 0]), InflRaw._finishFlushFlag); | ||
if(InflRaw.bytesRead) _zlib = zlib; | ||
else throw new Error("zlib does not expose bytesRead"); | ||
} catch(e) {console.error("cannot use native zlib: " + (e.message || e)); } } | ||
function _inflateRawSync(payload, usz) { | ||
if(!_zlib) return _inflate(payload, usz); | ||
var InflateRaw = _zlib.InflateRaw; | ||
var InflRaw = new InflateRaw(); | ||
var out = InflRaw._processChunk(payload.slice(payload.l), InflRaw._finishFlushFlag); | ||
payload.l += InflRaw.bytesRead; | ||
return out; | ||
} | ||
function _deflateRawSync(payload) { | ||
return _zlib ? _zlib.deflateRawSync(payload) : _deflate(payload); | ||
} | ||
var CLEN_ORDER = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; | ||
/* LEN_ID = [ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285 ]; */ | ||
var LEN_LN = [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13 , 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 ]; | ||
/* DST_ID = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 ]; */ | ||
var DST_LN = [ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ]; | ||
function bit_swap_8(n) { var t = (((((n<<1)|(n<<11)) & 0x22110) | (((n<<5)|(n<<15)) & 0x88440))); return ((t>>16) | (t>>8) |t)&0xFF; } | ||
var use_typed_arrays = typeof Uint8Array !== 'undefined'; | ||
var bitswap8 = use_typed_arrays ? new Uint8Array(1<<8) : []; | ||
for(var q = 0; q < (1<<8); ++q) bitswap8[q] = bit_swap_8(q); | ||
function bit_swap_n(n, b) { | ||
var rev = bitswap8[n & 0xFF]; | ||
if(b <= 8) return rev >>> (8-b); | ||
rev = (rev << 8) | bitswap8[(n>>8)&0xFF]; | ||
if(b <= 16) return rev >>> (16-b); | ||
rev = (rev << 8) | bitswap8[(n>>16)&0xFF]; | ||
return rev >>> (24-b); | ||
} | ||
/* helpers for unaligned bit reads */ | ||
function read_bits_2(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 6 ? 0 : buf[h+1]<<8))>>>w)& 0x03; } | ||
function read_bits_3(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 5 ? 0 : buf[h+1]<<8))>>>w)& 0x07; } | ||
function read_bits_4(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 4 ? 0 : buf[h+1]<<8))>>>w)& 0x0F; } | ||
function read_bits_5(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 3 ? 0 : buf[h+1]<<8))>>>w)& 0x1F; } | ||
function read_bits_7(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 1 ? 0 : buf[h+1]<<8))>>>w)& 0x7F; } | ||
/* works up to n = 3 * 8 + 1 = 25 */ | ||
function read_bits_n(buf, bl, n) { | ||
var w = (bl&7), h = (bl>>>3), f = ((1<<n)-1); | ||
var v = buf[h] >>> w; | ||
if(n < 8 - w) return v & f; | ||
v |= buf[h+1]<<(8-w); | ||
if(n < 16 - w) return v & f; | ||
v |= buf[h+2]<<(16-w); | ||
if(n < 24 - w) return v & f; | ||
v |= buf[h+3]<<(24-w); | ||
return v & f; | ||
} | ||
/* until ArrayBuffer#realloc is a thing, fake a realloc */ | ||
function realloc(b, sz) { | ||
var L = b.length, M = 2*L > sz ? 2*L : sz + 5, i = 0; | ||
if(L >= sz) return b; | ||
if(has_buf) { | ||
var o = new_unsafe_buf(M); | ||
// $FlowIgnore | ||
if(b.copy) b.copy(o); | ||
else for(; i < b.length; ++i) o[i] = b[i]; | ||
return o; | ||
} else if(use_typed_arrays) { | ||
var a = new Uint8Array(M); | ||
if(a.set) a.set(b); | ||
else for(; i < b.length; ++i) a[i] = b[i]; | ||
return a; | ||
} | ||
b.length = M; | ||
return b; | ||
} | ||
/* zero-filled arrays for older browsers */ | ||
function zero_fill_array(n) { | ||
var o = new Array(n); | ||
for(var i = 0; i < n; ++i) o[i] = 0; | ||
return o; | ||
}var _deflate = (function() { | ||
var _deflateRaw = (function() { | ||
return function deflateRaw(data, out) { | ||
var boff = 0; | ||
while(boff < data.length) { | ||
var L = Math.min(0xFFFF, data.length - boff); | ||
var h = boff + L == data.length; | ||
/* TODO: this is only type 0 stored */ | ||
out.write_shift(1, +h); | ||
out.write_shift(2, L); | ||
out.write_shift(2, (~L) & 0xFFFF); | ||
while(L-- > 0) out[out.l++] = data[boff++]; | ||
} | ||
return out.l; | ||
}; | ||
})(); | ||
return function(data) { | ||
var buf = new_buf(50+Math.floor(data.length*1.1)); | ||
var off = _deflateRaw(data, buf); | ||
return buf.slice(0, off); | ||
}; | ||
})(); | ||
/* modified inflate function also moves original read head */ | ||
/* build tree (used for literals and lengths) */ | ||
function build_tree(clens, cmap, MAX) { | ||
var maxlen = 1, w = 0, i = 0, j = 0, ccode = 0, L = clens.length; | ||
var bl_count = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32); | ||
for(i = 0; i < 32; ++i) bl_count[i] = 0; | ||
for(i = L; i < MAX; ++i) clens[i] = 0; | ||
L = clens.length; | ||
var ctree = use_typed_arrays ? new Uint16Array(L) : zero_fill_array(L); // [] | ||
/* build code tree */ | ||
for(i = 0; i < L; ++i) { | ||
bl_count[(w = clens[i])]++; | ||
if(maxlen < w) maxlen = w; | ||
ctree[i] = 0; | ||
} | ||
bl_count[0] = 0; | ||
for(i = 1; i <= maxlen; ++i) bl_count[i+16] = (ccode = (ccode + bl_count[i-1])<<1); | ||
for(i = 0; i < L; ++i) { | ||
ccode = clens[i]; | ||
if(ccode != 0) ctree[i] = bl_count[ccode+16]++; | ||
} | ||
/* cmap[maxlen + 4 bits] = (off&15) + (lit<<4) reverse mapping */ | ||
var cleni = 0; | ||
for(i = 0; i < L; ++i) { | ||
cleni = clens[i]; | ||
if(cleni != 0) { | ||
ccode = bit_swap_n(ctree[i], maxlen)>>(maxlen-cleni); | ||
for(j = (1<<(maxlen + 4 - cleni)) - 1; j>=0; --j) | ||
cmap[ccode|(j<<cleni)] = (cleni&15) | (i<<4); | ||
} | ||
} | ||
return maxlen; | ||
} | ||
var fix_lmap = use_typed_arrays ? new Uint16Array(512) : zero_fill_array(512); | ||
var fix_dmap = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32); | ||
if(!use_typed_arrays) { | ||
for(var i = 0; i < 512; ++i) fix_lmap[i] = 0; | ||
for(i = 0; i < 32; ++i) fix_dmap[i] = 0; | ||
} | ||
(function() { | ||
var dlens = []; | ||
var i = 0; | ||
for(;i<32; i++) dlens.push(5); | ||
build_tree(dlens, fix_dmap, 32); | ||
var clens = []; | ||
i = 0; | ||
for(; i<=143; i++) clens.push(8); | ||
for(; i<=255; i++) clens.push(9); | ||
for(; i<=279; i++) clens.push(7); | ||
for(; i<=287; i++) clens.push(8); | ||
build_tree(clens, fix_lmap, 288); | ||
})(); | ||
var dyn_lmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768); | ||
var dyn_dmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768); | ||
var dyn_cmap = use_typed_arrays ? new Uint16Array(128) : zero_fill_array(128); | ||
var dyn_len_1 = 1, dyn_len_2 = 1; | ||
/* 5.5.3 Expanding Huffman Codes */ | ||
function dyn(data, boff) { | ||
/* nomenclature from RFC1951 refers to bit values; these are offset by the implicit constant */ | ||
var _HLIT = read_bits_5(data, boff) + 257; boff += 5; | ||
var _HDIST = read_bits_5(data, boff) + 1; boff += 5; | ||
var _HCLEN = read_bits_4(data, boff) + 4; boff += 4; | ||
var w = 0; | ||
/* grab and store code lengths */ | ||
var clens = use_typed_arrays ? new Uint8Array(19) : zero_fill_array(19); | ||
var ctree = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; | ||
var maxlen = 1; | ||
var bl_count = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8); | ||
var next_code = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8); | ||
var L = clens.length; /* 19 */ | ||
for(var i = 0; i < _HCLEN; ++i) { | ||
clens[CLEN_ORDER[i]] = w = read_bits_3(data, boff); | ||
if(maxlen < w) maxlen = w; | ||
bl_count[w]++; | ||
boff += 3; | ||
} | ||
/* build code tree */ | ||
var ccode = 0; | ||
bl_count[0] = 0; | ||
for(i = 1; i <= maxlen; ++i) next_code[i] = ccode = (ccode + bl_count[i-1])<<1; | ||
for(i = 0; i < L; ++i) if((ccode = clens[i]) != 0) ctree[i] = next_code[ccode]++; | ||
/* cmap[7 bits from stream] = (off&7) + (lit<<3) */ | ||
var cleni = 0; | ||
for(i = 0; i < L; ++i) { | ||
cleni = clens[i]; | ||
if(cleni != 0) { | ||
ccode = bitswap8[ctree[i]]>>(8-cleni); | ||
for(var j = (1<<(7-cleni))-1; j>=0; --j) dyn_cmap[ccode|(j<<cleni)] = (cleni&7) | (i<<3); | ||
} | ||
} | ||
/* read literal and dist codes at once */ | ||
var hcodes = []; | ||
maxlen = 1; | ||
for(; hcodes.length < _HLIT + _HDIST;) { | ||
ccode = dyn_cmap[read_bits_7(data, boff)]; | ||
boff += ccode & 7; | ||
switch((ccode >>>= 3)) { | ||
case 16: | ||
w = 3 + read_bits_2(data, boff); boff += 2; | ||
ccode = hcodes[hcodes.length - 1]; | ||
while(w-- > 0) hcodes.push(ccode); | ||
break; | ||
case 17: | ||
w = 3 + read_bits_3(data, boff); boff += 3; | ||
while(w-- > 0) hcodes.push(0); | ||
break; | ||
case 18: | ||
w = 11 + read_bits_7(data, boff); boff += 7; | ||
while(w -- > 0) hcodes.push(0); | ||
break; | ||
default: | ||
hcodes.push(ccode); | ||
if(maxlen < ccode) maxlen = ccode; | ||
break; | ||
} | ||
} | ||
/* build literal / length trees */ | ||
var h1 = hcodes.slice(0, _HLIT), h2 = hcodes.slice(_HLIT); | ||
for(i = _HLIT; i < 286; ++i) h1[i] = 0; | ||
for(i = _HDIST; i < 30; ++i) h2[i] = 0; | ||
dyn_len_1 = build_tree(h1, dyn_lmap, 286); | ||
dyn_len_2 = build_tree(h2, dyn_dmap, 30); | ||
return boff; | ||
} | ||
/* return [ data, bytesRead ] */ | ||
function inflate(data, usz) { | ||
/* shortcircuit for empty buffer [0x03, 0x00] */ | ||
if(data[0] == 3 && !(data[1] & 0x3)) { return [new_raw_buf(usz), 2]; } | ||
/* bit offset */ | ||
var boff = 0; | ||
/* header includes final bit and type bits */ | ||
var header = 0; | ||
var outbuf = new_unsafe_buf(usz ? usz : (1<<18)); | ||
var woff = 0; | ||
var OL = outbuf.length>>>0; | ||
var max_len_1 = 0, max_len_2 = 0; | ||
while((header&1) == 0) { | ||
header = read_bits_3(data, boff); boff += 3; | ||
if((header >>> 1) == 0) { | ||
/* Stored block */ | ||
if(boff & 7) boff += 8 - (boff&7); | ||
/* 2 bytes sz, 2 bytes bit inverse */ | ||
var sz = data[boff>>>3] | data[(boff>>>3)+1]<<8; | ||
boff += 32; | ||
/* push sz bytes */ | ||
if(!usz && OL < woff + sz) { outbuf = realloc(outbuf, woff + sz); OL = outbuf.length; } | ||
if(typeof data.copy === 'function') { | ||
// $FlowIgnore | ||
data.copy(outbuf, woff, boff>>>3, (boff>>>3)+sz); | ||
woff += sz; boff += 8*sz; | ||
} else while(sz-- > 0) { outbuf[woff++] = data[boff>>>3]; boff += 8; } | ||
continue; | ||
} else if((header >>> 1) == 1) { | ||
/* Fixed Huffman */ | ||
max_len_1 = 9; max_len_2 = 5; | ||
} else { | ||
/* Dynamic Huffman */ | ||
boff = dyn(data, boff); | ||
max_len_1 = dyn_len_1; max_len_2 = dyn_len_2; | ||
} | ||
if(!usz && (OL < woff + 32767)) { outbuf = realloc(outbuf, woff + 32767); OL = outbuf.length; } | ||
for(;;) { // while(true) is apparently out of vogue in modern JS circles | ||
/* ingest code and move read head */ | ||
var bits = read_bits_n(data, boff, max_len_1); | ||
var code = (header>>>1) == 1 ? fix_lmap[bits] : dyn_lmap[bits]; | ||
boff += code & 15; code >>>= 4; | ||
/* 0-255 are literals, 256 is end of block token, 257+ are copy tokens */ | ||
if(((code>>>8)&0xFF) === 0) outbuf[woff++] = code; | ||
else if(code == 256) break; | ||
else { | ||
code -= 257; | ||
var len_eb = (code < 8) ? 0 : ((code-4)>>2); if(len_eb > 5) len_eb = 0; | ||
var tgt = woff + LEN_LN[code]; | ||
/* length extra bits */ | ||
if(len_eb > 0) { | ||
tgt += read_bits_n(data, boff, len_eb); | ||
boff += len_eb; | ||
} | ||
/* dist code */ | ||
bits = read_bits_n(data, boff, max_len_2); | ||
code = (header>>>1) == 1 ? fix_dmap[bits] : dyn_dmap[bits]; | ||
boff += code & 15; code >>>= 4; | ||
var dst_eb = (code < 4 ? 0 : (code-2)>>1); | ||
var dst = DST_LN[code]; | ||
/* dist extra bits */ | ||
if(dst_eb > 0) { | ||
dst += read_bits_n(data, boff, dst_eb); | ||
boff += dst_eb; | ||
} | ||
/* in the common case, manual byte copy is faster than TA set / Buffer copy */ | ||
if(!usz && OL < tgt) { outbuf = realloc(outbuf, tgt); OL = outbuf.length; } | ||
while(woff < tgt) { outbuf[woff] = outbuf[woff - dst]; ++woff; } | ||
} | ||
} | ||
} | ||
return [usz ? outbuf : outbuf.slice(0, woff), (boff+7)>>>3]; | ||
} | ||
function _inflate(payload, usz) { | ||
var data = payload.slice(payload.l||0); | ||
var out = inflate(data, usz); | ||
payload.l += out[1]; | ||
return out[0]; | ||
} | ||
function warn_or_throw(wrn, msg) { | ||
if(wrn) { if(typeof console !== 'undefined') console.error(msg); } | ||
else throw new Error(msg); | ||
} | ||
function parse_zip(file, options) { | ||
var blob = file; | ||
prep_blob(blob, 0); | ||
var FileIndex = [], FullPaths = []; | ||
var o = { | ||
FileIndex: FileIndex, | ||
FullPaths: FullPaths | ||
}; | ||
init_cfb(o, { root: options.root }); | ||
/* find end of central directory, start just after signature */ | ||
var i = blob.length - 4; | ||
while((blob[i] != 0x50 || blob[i+1] != 0x4b || blob[i+2] != 0x05 || blob[i+3] != 0x06) && i >= 0) --i; | ||
blob.l = i + 4; | ||
/* parse end of central directory */ | ||
blob.l += 4; | ||
var fcnt = blob.read_shift(2); | ||
blob.l += 6; | ||
var start_cd = blob.read_shift(4); | ||
/* parse central directory */ | ||
blob.l = start_cd; | ||
for(i = 0; i < fcnt; ++i) { | ||
/* trust local file header instead of CD entry */ | ||
blob.l += 20; | ||
var csz = blob.read_shift(4); | ||
var usz = blob.read_shift(4); | ||
var namelen = blob.read_shift(2); | ||
var efsz = blob.read_shift(2); | ||
var fcsz = blob.read_shift(2); | ||
blob.l += 8; | ||
var offset = blob.read_shift(4); | ||
var EF = parse_extra_field(blob.slice(blob.l+namelen, blob.l+namelen+efsz)); | ||
blob.l += namelen + efsz + fcsz; | ||
var L = blob.l; | ||
blob.l = offset + 4; | ||
parse_local_file(blob, csz, usz, o, EF); | ||
blob.l = L; | ||
} | ||
return o; | ||
} | ||
/* head starts just after local file header signature */ | ||
function parse_local_file(blob, csz, usz, o, EF) { | ||
/* [local file header] */ | ||
blob.l += 2; | ||
var flags = blob.read_shift(2); | ||
var meth = blob.read_shift(2); | ||
var date = parse_dos_date(blob); | ||
if(flags & 0x2041) throw new Error("Unsupported ZIP encryption"); | ||
var crc32 = blob.read_shift(4); | ||
var _csz = blob.read_shift(4); | ||
var _usz = blob.read_shift(4); | ||
var namelen = blob.read_shift(2); | ||
var efsz = blob.read_shift(2); | ||
// TODO: flags & (1<<11) // UTF8 | ||
var name = ""; for(var i = 0; i < namelen; ++i) name += String.fromCharCode(blob[blob.l++]); | ||
if(efsz) { | ||
var ef = parse_extra_field(blob.slice(blob.l, blob.l + efsz)); | ||
if((ef[0x5455]||{}).mt) date = ef[0x5455].mt; | ||
if(((EF||{})[0x5455]||{}).mt) date = EF[0x5455].mt; | ||
} | ||
blob.l += efsz; | ||
/* [encryption header] */ | ||
/* [file data] */ | ||
var data = blob.slice(blob.l, blob.l + _csz); | ||
switch(meth) { | ||
case 8: data = _inflateRawSync(blob, _usz); break; | ||
case 0: break; | ||
default: throw new Error("Unsupported ZIP Compression method " + meth); | ||
} | ||
/* [data descriptor] */ | ||
var wrn = false; | ||
if(flags & 8) { | ||
crc32 = blob.read_shift(4); | ||
if(crc32 == 0x08074b50) { crc32 = blob.read_shift(4); wrn = true; } | ||
_csz = blob.read_shift(4); | ||
_usz = blob.read_shift(4); | ||
} | ||
if(_csz != csz) warn_or_throw(wrn, "Bad compressed size: " + csz + " != " + _csz); | ||
if(_usz != usz) warn_or_throw(wrn, "Bad uncompressed size: " + usz + " != " + _usz); | ||
var _crc32 = CRC32.buf(data, 0); | ||
if(crc32 != _crc32) warn_or_throw(wrn, "Bad CRC32 checksum: " + crc32 + " != " + _crc32); | ||
cfb_add(o, name, data, {unsafe: true, mt: date}); | ||
} | ||
function write_zip(cfb, options) { | ||
var _opts = options || {}; | ||
var out = [], cdirs = []; | ||
var o = new_buf(1); | ||
var method = (_opts.compression ? 8 : 0), flags = 0; | ||
var desc = false; | ||
if(desc) flags |= 8; | ||
var i = 0, j = 0; | ||
var start_cd = 0, fcnt = 0; | ||
var root = cfb.FullPaths[0], fp = root, fi = cfb.FileIndex[0]; | ||
var crcs = []; | ||
var sz_cd = 0; | ||
for(i = 1; i < cfb.FullPaths.length; ++i) { | ||
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i]; | ||
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue; | ||
var start = start_cd; | ||
/* TODO: CP437 filename */ | ||
var namebuf = new_buf(fp.length); | ||
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F); | ||
namebuf = namebuf.slice(0, namebuf.l); | ||
crcs[fcnt] = CRC32.buf(fi.content, 0); | ||
var outbuf = fi.content; | ||
if(method == 8) outbuf = _deflateRawSync(outbuf); | ||
/* local file header */ | ||
o = new_buf(30); | ||
o.write_shift(4, 0x04034b50); | ||
o.write_shift(2, 20); | ||
o.write_shift(2, flags); | ||
o.write_shift(2, method); | ||
/* TODO: last mod file time/date */ | ||
if(fi.mt) write_dos_date(o, fi.mt); | ||
else o.write_shift(4, 0); | ||
o.write_shift(-4, (flags & 8) ? 0 : crcs[fcnt]); | ||
o.write_shift(4, (flags & 8) ? 0 : outbuf.length); | ||
o.write_shift(4, (flags & 8) ? 0 : fi.content.length); | ||
o.write_shift(2, namebuf.length); | ||
o.write_shift(2, 0); | ||
start_cd += o.length; | ||
out.push(o); | ||
start_cd += namebuf.length; | ||
out.push(namebuf); | ||
/* TODO: encryption header ? */ | ||
start_cd += outbuf.length; | ||
out.push(outbuf); | ||
/* data descriptor */ | ||
if(flags & 8) { | ||
o = new_buf(12); | ||
o.write_shift(-4, crcs[fcnt]); | ||
o.write_shift(4, outbuf.length); | ||
o.write_shift(4, fi.content.length); | ||
start_cd += o.l; | ||
out.push(o); | ||
} | ||
/* central directory */ | ||
o = new_buf(46); | ||
o.write_shift(4, 0x02014b50); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 20); | ||
o.write_shift(2, flags); | ||
o.write_shift(2, method); | ||
o.write_shift(4, 0); /* TODO: last mod file time/date */ | ||
o.write_shift(-4, crcs[fcnt]); | ||
o.write_shift(4, outbuf.length); | ||
o.write_shift(4, fi.content.length); | ||
o.write_shift(2, namebuf.length); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(4, 0); | ||
o.write_shift(4, start); | ||
sz_cd += o.l; | ||
cdirs.push(o); | ||
sz_cd += namebuf.length; | ||
cdirs.push(namebuf); | ||
++fcnt; | ||
} | ||
/* end of central directory */ | ||
o = new_buf(22); | ||
o.write_shift(4, 0x06054b50); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, fcnt); | ||
o.write_shift(2, fcnt); | ||
o.write_shift(4, sz_cd); | ||
o.write_shift(4, start_cd); | ||
o.write_shift(2, 0); | ||
return bconcat(([bconcat((out)), bconcat(cdirs), o])); | ||
} | ||
function cfb_new(opts) { | ||
@@ -841,2 +1564,4 @@ var o = ({}); | ||
if(opts.CLSID) file.clsid = opts.CLSID; | ||
if(opts.mt) file.mt = opts.mt; | ||
if(opts.ct) file.ct = opts.ct; | ||
} | ||
@@ -885,2 +1610,5 @@ return file; | ||
bconcat: bconcat, | ||
use_zlib: use_zlib, | ||
_deflateRaw: _deflate, | ||
_inflateRaw: _inflate, | ||
consts: consts | ||
@@ -887,0 +1615,0 @@ }; |
/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||
var Base64=function e(){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{encode:function(r){var t="";var i=0,n=0,f=0,a=0,s=0,h=0,l=0;for(var o=0;o<r.length;){i=r.charCodeAt(o++);a=i>>2;n=r.charCodeAt(o++);s=(i&3)<<4|n>>4;f=r.charCodeAt(o++);h=(n&15)<<2|f>>6;l=f&63;if(isNaN(n)){h=l=64}else if(isNaN(f)){l=64}t+=e.charAt(a)+e.charAt(s)+e.charAt(h)+e.charAt(l)}return t},decode:function r(t){var i="";var n=0,f=0,a=0,s=0,h=0,l=0,o=0;t=t.replace(/[^\w\+\/\=]/g,"");for(var u=0;u<t.length;){s=e.indexOf(t.charAt(u++));h=e.indexOf(t.charAt(u++));n=s<<2|h>>4;i+=String.fromCharCode(n);l=e.indexOf(t.charAt(u++));f=(h&15)<<4|l>>2;if(l!==64){i+=String.fromCharCode(f)}o=e.indexOf(t.charAt(u++));a=(l&3)<<6|o;if(o!==64){i+=String.fromCharCode(a)}}return i}}}();var has_buf=typeof Buffer!=="undefined"&&typeof process!=="undefined"&&typeof process.versions!=="undefined"&&process.versions.node;var Buffer_from=function(){};if(typeof Buffer!=="undefined"){var nbfs=!Buffer.from;if(!nbfs)try{Buffer.from("foo","utf8")}catch(e){nbfs=true}Buffer_from=nbfs?function(e,r){return r?new Buffer(e,r):new Buffer(e)}:Buffer.from.bind(Buffer);if(!Buffer.alloc)Buffer.alloc=function(e){return new Buffer(e)}}function new_raw_buf(e){return has_buf?Buffer.alloc(e):new Array(e)}var s2a=function r(e){if(has_buf)return Buffer.from(e,"binary");return e.split("").map(function(e){return e.charCodeAt(0)&255})};var chr0=/\u0000/g,chr1=/[\u0001-\u0006]/g;var __toBuffer=function(e){var r=[];for(var t=0;t<e[0].length;++t){r.push.apply(r,e[0][t])}return r};var ___toBuffer=__toBuffer;var __utf16le=function(e,r,t){var i=[];for(var n=r;n<t;n+=2)i.push(String.fromCharCode(__readUInt16LE(e,n)));return i.join("").replace(chr0,"")};var ___utf16le=__utf16le;var __hexlify=function(e,r,t){var i=[];for(var n=r;n<r+t;++n)i.push(("0"+e[n].toString(16)).slice(-2));return i.join("")};var ___hexlify=__hexlify;var __bconcat=function(e){if(Array.isArray(e[0]))return[].concat.apply([],e);var r=0,t=0;for(t=0;t<e.length;++t)r+=e[t].length;var i=new Uint8Array(r);for(t=0,r=0;t<e.length;r+=e[t].length,++t)i.set(e[t],r);return i};var bconcat=__bconcat;if(has_buf){__utf16le=function(e,r,t){if(!Buffer.isBuffer(e))return ___utf16le(e,r,t);return e.toString("utf16le",r,t).replace(chr0,"")};__hexlify=function(e,r,t){return Buffer.isBuffer(e)?e.toString("hex",r,r+t):___hexlify(e,r,t)};__toBuffer=function(e){return e[0].length>0&&Buffer.isBuffer(e[0][0])?Buffer.concat(e[0]):___toBuffer(e)};s2a=function(e){return Buffer_from(e,"binary")};bconcat=function(e){return Buffer.isBuffer(e[0])?Buffer.concat(e):__bconcat(e)}}var __readUInt8=function(e,r){return e[r]};var __readUInt16LE=function(e,r){return e[r+1]*(1<<8)+e[r]};var __readInt16LE=function(e,r){var t=e[r+1]*(1<<8)+e[r];return t<32768?t:(65535-t+1)*-1};var __readUInt32LE=function(e,r){return e[r+3]*(1<<24)+(e[r+2]<<16)+(e[r+1]<<8)+e[r]};var __readInt32LE=function(e,r){return(e[r+3]<<24)+(e[r+2]<<16)+(e[r+1]<<8)+e[r]};function ReadShift(e,r){var t,i,n=0;switch(e){case 1:t=__readUInt8(this,this.l);break;case 2:t=(r!=="i"?__readUInt16LE:__readInt16LE)(this,this.l);break;case 4:t=__readInt32LE(this,this.l);break;case 16:n=2;i=__hexlify(this,this.l,e);}this.l+=e;if(n===0)return t;return i}var __writeUInt32LE=function(e,r,t){e[t]=r&255;e[t+1]=r>>>8&255;e[t+2]=r>>>16&255;e[t+3]=r>>>24&255};var __writeInt32LE=function(e,r,t){e[t]=r&255;e[t+1]=r>>8&255;e[t+2]=r>>16&255;e[t+3]=r>>24&255};function WriteShift(e,r,t){var i=0,n=0;switch(t){case"hex":for(;n<e;++n){this[this.l++]=parseInt(r.slice(2*n,2*n+2),16)||0}return this;case"utf16le":var f=this.l+e;for(n=0;n<Math.min(r.length,e);++n){var a=r.charCodeAt(n);this[this.l++]=a&255;this[this.l++]=a>>8}while(this.l<f)this[this.l++]=0;return this;}switch(e){case 1:i=1;this[this.l]=r&255;break;case 2:i=2;this[this.l]=r&255;r>>>=8;this[this.l+1]=r&255;break;case 4:i=4;__writeUInt32LE(this,r,this.l);break;case-4:i=4;__writeInt32LE(this,r,this.l);break;}this.l+=i;return this}function CheckField(e,r){var t=__hexlify(this,this.l,e.length>>1);if(t!==e)throw new Error(r+"Expected "+e+" saw "+t);this.l+=e.length>>1}function prep_blob(e,r){e.l=r;e.read_shift=ReadShift;e.chk=CheckField;e.write_shift=WriteShift}function new_buf(e){var r=new_raw_buf(e);prep_blob(r,0);return r}var CFB=function t(){var e={};e.version="1.0.8";function r(e,r){var t=e.split("/"),i=r.split("/");for(var n=0,f=0,a=Math.min(t.length,i.length);n<a;++n){if(f=t[n].length-i[n].length)return f;if(t[n]!=i[n])return t[n]<i[n]?-1:1}return t.length-i.length}function t(e){if(e.charAt(e.length-1)=="/")return e.slice(0,-1).indexOf("/")===-1?e:t(e.slice(0,-1));var r=e.lastIndexOf("/");return r===-1?e:e.slice(0,r+1)}function i(e){if(e.charAt(e.length-1)=="/")return i(e.slice(0,-1));var r=e.lastIndexOf("/");return r===-1?e:e.slice(r+1)}var n;function f(){return n||(n=require("fs"))}function a(e,r){if(e.length<512)throw new Error("CFB file size "+e.length+" < 512");var t=3;var i=512;var n=0;var f=0;var a=0;var u=0;var _=0;var w=[];var p=e.slice(0,512);prep_blob(p,0);var F=s(p);t=F[0];switch(t){case 3:i=512;break;case 4:i=4096;break;default:throw new Error("Major Version: Expected 3 or 4 saw "+t);}if(i!==512){p=e.slice(0,i);prep_blob(p,28)}var g=e.slice(0,i);h(p,t);var I=p.read_shift(4,"i");if(t===3&&I!==0)throw new Error("# Directory Sectors: Expected 0 saw "+I);p.l+=4;a=p.read_shift(4,"i");p.l+=4;p.chk("00100000","Mini Stream Cutoff Size: ");u=p.read_shift(4,"i");n=p.read_shift(4,"i");_=p.read_shift(4,"i");f=p.read_shift(4,"i");for(var b=-1,x=0;x<109;++x){b=p.read_shift(4,"i");if(b<0)break;w[x]=b}var E=l(e,i);c(_,f,E,i,w);var C=d(E,a,w,i);C[a].name="!Directory";if(n>0&&u!==y)C[u].name="!MiniFAT";C[w[0]].name="!FAT";C.fat_addrs=w;C.ssz=i;var S={},B=[],m=[],A=[];v(a,C,E,B,n,S,m,u);o(m,A,B);B.shift();var L={FileIndex:m,FullPaths:A};if(r&&r.raw)L.raw={header:g,sectors:E};return L}function s(e){e.chk(S,"Header Signature: ");e.chk(m,"CLSID: ");var r=e.read_shift(2,"u");return[e.read_shift(2,"u"),r]}function h(e,r){var t=9;e.l+=2;switch(t=e.read_shift(2)){case 9:if(r!=3)throw new Error("Sector Shift: Expected 9 saw "+t);break;case 12:if(r!=4)throw new Error("Sector Shift: Expected 12 saw "+t);break;default:throw new Error("Sector Shift: Expected 9 or 12 saw "+t);}e.chk("0600","Mini Sector Shift: ");e.chk("000000000000","Reserved: ")}function l(e,r){var t=Math.ceil(e.length/r)-1;var i=[];for(var n=1;n<t;++n)i[n-1]=e.slice(n*r,(n+1)*r);i[t-1]=e.slice(t*r);return i}function o(e,r,t){var i=0,n=0,f=0,a=0,s=0,h=t.length;var l=[],o=[];for(;i<h;++i){l[i]=o[i]=i;r[i]=t[i]}for(;s<o.length;++s){i=o[s];n=e[i].L;f=e[i].R;a=e[i].C;if(l[i]===i){if(n!==-1&&l[n]!==n)l[i]=l[n];if(f!==-1&&l[f]!==f)l[i]=l[f]}if(a!==-1)l[a]=i;if(n!==-1){l[n]=l[i];if(o.lastIndexOf(n)<s)o.push(n)}if(f!==-1){l[f]=l[i];if(o.lastIndexOf(f)<s)o.push(f)}}for(i=1;i<h;++i)if(l[i]===i){if(f!==-1&&l[f]!==f)l[i]=l[f];else if(n!==-1&&l[n]!==n)l[i]=l[n]}for(i=1;i<h;++i){if(e[i].type===0)continue;s=l[i];if(s===0)r[i]=r[0]+"/"+r[i];else while(s!==0&&s!==l[s]){r[i]=r[s]+"/"+r[i];s=l[s]}l[i]=0}r[0]+="/";for(i=1;i<h;++i){if(e[i].type!==2)r[i]+="/"}}function u(e,r,t){var i=e.start,n=e.size;var f=[];var a=i;while(t&&n>0&&a>=0){f.push(r.slice(a*C,a*C+C));n-=C;a=__readInt32LE(t,a*4)}if(f.length===0)return new_buf(0);return bconcat(f).slice(0,e.size)}function c(e,r,t,i,n){var f=y;if(e===y){if(r!==0)throw new Error("DIFAT chain shorter than expected")}else if(e!==-1){var a=t[e],s=(i>>>2)-1;if(!a)return;for(var h=0;h<s;++h){if((f=__readInt32LE(a,h*4))===y)break;n.push(f)}c(__readInt32LE(a,i-4),r-1,t,i,n)}}function _(e,r,t,i,n){var f=[],a=[];if(!n)n=[];var s=i-1,h=0,l=0;for(h=r;h>=0;){n[h]=true;f[f.length]=h;a.push(e[h]);var o=t[Math.floor(h*4/i)];l=h*4&s;if(i<4+l)throw new Error("FAT boundary crossed: "+h+" 4 "+i);if(!e[o])break;h=__readInt32LE(e[o],l)}return{nodes:f,data:__toBuffer([a])}}function d(e,r,t,i){var n=e.length,f=[];var a=[],s=[],h=[];var l=i-1,o=0,u=0,c=0,_=0;for(o=0;o<n;++o){s=[];c=o+r;if(c>=n)c-=n;if(a[c])continue;h=[];for(u=c;u>=0;){a[u]=true;s[s.length]=u;h.push(e[u]);var d=t[Math.floor(u*4/i)];_=u*4&l;if(i<4+_)throw new Error("FAT boundary crossed: "+u+" 4 "+i);if(!e[d])break;u=__readInt32LE(e[d],_)}f[c]={nodes:s,data:__toBuffer([h])}}return f}function v(e,r,t,i,n,f,a,s){var h=0,l=i.length?2:0;var o=r[e].data;var c=0,d=0,v;for(;c<o.length;c+=128){var p=o.slice(c,c+128);prep_blob(p,64);d=p.read_shift(2);v=__utf16le(p,0,d-l);i.push(v);var F={name:v,type:p.read_shift(1),color:p.read_shift(1),L:p.read_shift(4,"i"),R:p.read_shift(4,"i"),C:p.read_shift(4,"i"),clsid:p.read_shift(16),state:p.read_shift(4,"i"),start:0,size:0};var g=p.read_shift(2)+p.read_shift(2)+p.read_shift(2)+p.read_shift(2);if(g!==0)F.ct=w(p,p.l-8);var I=p.read_shift(2)+p.read_shift(2)+p.read_shift(2)+p.read_shift(2);if(I!==0)F.mt=w(p,p.l-8);F.start=p.read_shift(4,"i");F.size=p.read_shift(4,"i");if(F.size<0&&F.start<0){F.size=F.type=0;F.start=y;F.name=""}if(F.type===5){h=F.start;if(n>0&&h!==y)r[h].name="!StreamData"}else if(F.size>=4096){F.storage="fat";if(r[F.start]===undefined)r[F.start]=_(t,F.start,r.fat_addrs,r.ssz);r[F.start].name=F.name;F.content=r[F.start].data.slice(0,F.size)}else{F.storage="minifat";if(F.size<0)F.size=0;else if(h!==y&&F.start!==y&&r[h]){F.content=u(F,r[h].data,(r[s]||{}).data)}}if(F.content)prep_blob(F.content,0);f[v]=F;a.push(F)}}function w(e,r){return new Date((__readUInt32LE(e,r+4)/1e7*Math.pow(2,32)+__readUInt32LE(e,r)/1e7-11644473600)*1e3)}function p(e,r){f();return a(n.readFileSync(e),r)}function F(e,r){switch(r&&r.type||"base64"){case"file":return p(e,r);case"base64":return a(s2a(Base64.decode(e)),r);case"binary":return a(s2a(e),r);}return a(e,r)}function g(e,r){var t=r||{},i=t.root||"Root Entry";if(!e.FullPaths)e.FullPaths=[];if(!e.FileIndex)e.FileIndex=[];if(e.FullPaths.length!==e.FileIndex.length)throw new Error("inconsistent CFB structure");if(e.FullPaths.length===0){e.FullPaths[0]=i+"/";e.FileIndex[0]={name:i,type:5}}if(t.CLSID)e.FileIndex[0].clsid=t.CLSID;I(e)}function I(e){var r="Sh33tJ5";if(CFB.find(e,"/"+r))return;var t=new_buf(4);t[0]=55;t[1]=t[3]=50;t[2]=54;e.FileIndex.push({name:r,type:2,content:t,size:4,L:69,R:69,C:69});e.FullPaths.push(e.FullPaths[0]+r);b(e)}function b(e,n){g(e);var f=false,a=false;for(var s=e.FullPaths.length-1;s>=0;--s){var h=e.FileIndex[s];switch(h.type){case 0:if(a)f=true;else{e.FileIndex.pop();e.FullPaths.pop()}break;case 1:;case 2:;case 5:a=true;if(isNaN(h.R*h.L*h.C))f=true;if(h.R>-1&&h.L>-1&&h.R==h.L)f=true;break;default:f=true;break;}}if(!f&&!n)return;var l=new Date(1987,1,19),o=0;var u=[];for(s=0;s<e.FullPaths.length;++s){if(e.FileIndex[s].type===0)continue;u.push([e.FullPaths[s],e.FileIndex[s]])}for(s=0;s<u.length;++s){var c=t(u[s][0]);a=false;for(o=0;o<u.length;++o)if(u[o][0]===c)a=true;if(!a)u.push([c,{name:i(c).replace("/",""),type:1,clsid:m,ct:l,mt:l,content:null}])}u.sort(function(e,t){return r(e[0],t[0])});e.FullPaths=[];e.FileIndex=[];for(s=0;s<u.length;++s){e.FullPaths[s]=u[s][0];e.FileIndex[s]=u[s][1]}for(s=0;s<u.length;++s){var _=e.FileIndex[s];var d=e.FullPaths[s];_.name=i(d).replace("/","");_.L=_.R=_.C=-(_.color=1);_.size=_.content?_.content.length:0;_.start=0;_.clsid=_.clsid||m;if(s===0){_.C=u.length>1?1:-1;_.size=0;_.type=5}else if(d.slice(-1)=="/"){for(o=s+1;o<u.length;++o)if(t(e.FullPaths[o])==d)break;_.C=o>=u.length?-1:o;for(o=s+1;o<u.length;++o)if(t(e.FullPaths[o])==t(d))break;_.R=o>=u.length?-1:o;_.type=1}else{if(t(e.FullPaths[s+1]||"")==t(d))_.R=s+1;_.type=2}}}function x(e,r){var t=r||{};b(e);var i=function(e){var r=0,t=0;for(var i=0;i<e.FileIndex.length;++i){var n=e.FileIndex[i];if(!n.content)continue;var f=n.content.length;if(f>0){if(f<4096)r+=f+63>>6;else t+=f+511>>9}}var a=e.FullPaths.length+3>>2;var s=r+7>>3;var h=r+127>>7;var l=s+t+a+h;var o=l+127>>7;var u=o<=109?0:Math.ceil((o-109)/127);while(l+o+u+127>>7>o)u=++o<=109?0:Math.ceil((o-109)/127);var c=[1,u,o,h,a,t,r,0];e.FileIndex[0].size=r<<6;c[7]=(e.FileIndex[0].start=c[0]+c[1]+c[2]+c[3]+c[4]+c[5])+(c[6]+7>>3);return c}(e);var n=new_buf(i[7]<<9);var f=0,a=0;{for(f=0;f<8;++f)n.write_shift(1,B[f]);for(f=0;f<8;++f)n.write_shift(2,0);n.write_shift(2,62);n.write_shift(2,3);n.write_shift(2,65534);n.write_shift(2,9);n.write_shift(2,6);for(f=0;f<3;++f)n.write_shift(2,0);n.write_shift(4,0);n.write_shift(4,i[2]);n.write_shift(4,i[0]+i[1]+i[2]+i[3]-1);n.write_shift(4,0);n.write_shift(4,1<<12);n.write_shift(4,i[3]?i[0]+i[1]+i[2]-1:y);n.write_shift(4,i[3]);n.write_shift(-4,i[1]?i[0]-1:y);n.write_shift(4,i[1]);for(f=0;f<109;++f)n.write_shift(-4,f<i[2]?i[1]+f:-1)}if(i[1]){for(a=0;a<i[1];++a){for(;f<236+a*127;++f)n.write_shift(-4,f<i[2]?i[1]+f:-1);n.write_shift(-4,a===i[1]-1?y:a+1)}}var s=function(e){for(a+=e;f<a-1;++f)n.write_shift(-4,f+1);if(e){++f;n.write_shift(-4,y)}};a=f=0;for(a+=i[1];f<a;++f)n.write_shift(-4,A.DIFSECT);for(a+=i[2];f<a;++f)n.write_shift(-4,A.FATSECT);s(i[3]);s(i[4]);var h=0,l=0;var o=e.FileIndex[0];for(;h<e.FileIndex.length;++h){o=e.FileIndex[h];if(!o.content)continue;l=o.content.length;if(l<4096)continue;o.start=a;s(l+511>>9)}s(i[6]+7>>3);while(n.l&511)n.write_shift(-4,A.ENDOFCHAIN);a=f=0;for(h=0;h<e.FileIndex.length;++h){o=e.FileIndex[h];if(!o.content)continue;l=o.content.length;if(!l||l>=4096)continue;o.start=a;s(l+63>>6)}while(n.l&511)n.write_shift(-4,A.ENDOFCHAIN);for(f=0;f<i[4]<<2;++f){var u=e.FullPaths[f];if(!u||u.length===0){for(h=0;h<17;++h)n.write_shift(4,0);for(h=0;h<3;++h)n.write_shift(4,-1);for(h=0;h<12;++h)n.write_shift(4,0);continue}o=e.FileIndex[f];if(f===0)o.start=o.size?o.start-1:y;var c=f===0&&t.root||o.name;l=2*(c.length+1);n.write_shift(64,c,"utf16le");n.write_shift(2,l);n.write_shift(1,o.type);n.write_shift(1,o.color);n.write_shift(-4,o.L);n.write_shift(-4,o.R);n.write_shift(-4,o.C);if(!o.clsid)for(h=0;h<4;++h)n.write_shift(4,0);else n.write_shift(16,o.clsid,"hex");n.write_shift(4,o.state||0);n.write_shift(4,0);n.write_shift(4,0);n.write_shift(4,0);n.write_shift(4,0);n.write_shift(4,o.start);n.write_shift(4,o.size);n.write_shift(4,0)}for(f=1;f<e.FileIndex.length;++f){o=e.FileIndex[f];if(o.size>=4096){n.l=o.start+1<<9;for(h=0;h<o.size;++h)n.write_shift(1,o.content[h]);for(;h&511;++h)n.write_shift(1,0)}}for(f=1;f<e.FileIndex.length;++f){o=e.FileIndex[f];if(o.size>0&&o.size<4096){for(h=0;h<o.size;++h)n.write_shift(1,o.content[h]);for(;h&63;++h)n.write_shift(1,0)}}while(n.l<n.length)n.write_shift(1,0);return n}function E(e,r){var t=e.FullPaths.map(function(e){return e.toUpperCase()});var i=t.map(function(e){var r=e.split("/");return r[r.length-(e.slice(-1)=="/"?2:1)]});var n=false;if(r.charCodeAt(0)===47){n=true;r=t[0].slice(0,-1)+r}else n=r.indexOf("/")!==-1;var f=r.toUpperCase();var a=n===true?t.indexOf(f):i.indexOf(f);if(a!==-1)return e.FileIndex[a];var s=!f.match(chr1);f=f.replace(chr0,"");if(s)f=f.replace(chr1,"!");for(a=0;a<t.length;++a){if((s?t[a].replace(chr1,"!"):t[a]).replace(chr0,"")==f)return e.FileIndex[a];if((s?i[a].replace(chr1,"!"):i[a]).replace(chr0,"")==f)return e.FileIndex[a]}return null}var C=64;var y=-2;var S="d0cf11e0a1b11ae1";var B=[208,207,17,224,161,177,26,225];var m="00000000000000000000000000000000";var A={MAXREGSECT:-6,DIFSECT:-4,FATSECT:-3,ENDOFCHAIN:y,FREESECT:-1,HEADER_SIGNATURE:S,HEADER_MINOR_VERSION:"3e00",MAXREGSID:-6,NOSTREAM:-1,HEADER_CLSID:m,EntryTypes:["unknown","storage","stream","lockbytes","property","root"]};function L(e,r,t){f();var i=x(e,t);n.writeFileSync(r,i)}function k(e){var r=new Array(e.length);for(var t=0;t<e.length;++t)r[t]=String.fromCharCode(e[t]);return r.join("")}function R(e,r){var t=x(e,r);switch(r&&r.type){case"file":f();n.writeFileSync(r.filename,t);return t;case"binary":return k(t);case"base64":return Base64.encode(k(t));}return t}function z(e){var r={};g(r,e);return r}function P(e,r,t,n){var f=n&&n.unsafe;if(!f)g(e);var a=!f&&CFB.find(e,r);if(!a){var s=e.FullPaths[0];if(r.slice(0,s.length)==s)s=r;else{if(s.slice(-1)!="/")s+="/";s=(s+r).replace("//","/")}a={name:i(r),type:2};e.FileIndex.push(a);e.FullPaths.push(s);if(!f)CFB.utils.cfb_gc(e)}a.content=t;a.size=t?t.length:0;if(n){if(n.CLSID)a.clsid=n.CLSID}return a}function D(e,r){g(e);var t=CFB.find(e,r);if(t)for(var i=0;i<e.FileIndex.length;++i)if(e.FileIndex[i]==t){e.FileIndex.splice(i,1);e.FullPaths.splice(i,1);return true}return false}function O(e,r,t){g(e);var n=CFB.find(e,r);if(n)for(var f=0;f<e.FileIndex.length;++f)if(e.FileIndex[f]==n){e.FileIndex[f].name=i(t);e.FullPaths[f]=t;return true}return false}function T(e){b(e,true)}e.find=E;e.read=F;e.parse=a;e.write=R;e.writeFile=L;e.utils={cfb_new:z,cfb_add:P,cfb_del:D,cfb_mov:O,cfb_gc:T,ReadShift:ReadShift,CheckField:CheckField,prep_blob:prep_blob,bconcat:bconcat,consts:A};return e}();if(typeof require!=="undefined"&&typeof module!=="undefined"&&typeof DO_NOT_EXPORT_CFB==="undefined"){module.exports=CFB} | ||
var Base64=function r(){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{encode:function(e){var t="";var i=0,n=0,f=0,a=0,s=0,h=0,l=0;for(var o=0;o<e.length;){i=e.charCodeAt(o++);a=i>>2;n=e.charCodeAt(o++);s=(i&3)<<4|n>>4;f=e.charCodeAt(o++);h=(n&15)<<2|f>>6;l=f&63;if(isNaN(n)){h=l=64}else if(isNaN(f)){l=64}t+=r.charAt(a)+r.charAt(s)+r.charAt(h)+r.charAt(l)}return t},decode:function e(t){var i="";var n=0,f=0,a=0,s=0,h=0,l=0,o=0;t=t.replace(/[^\w\+\/\=]/g,"");for(var u=0;u<t.length;){s=r.indexOf(t.charAt(u++));h=r.indexOf(t.charAt(u++));n=s<<2|h>>4;i+=String.fromCharCode(n);l=r.indexOf(t.charAt(u++));f=(h&15)<<4|l>>2;if(l!==64){i+=String.fromCharCode(f)}o=r.indexOf(t.charAt(u++));a=(l&3)<<6|o;if(o!==64){i+=String.fromCharCode(a)}}return i}}}();var has_buf=typeof Buffer!=="undefined"&&typeof process!=="undefined"&&typeof process.versions!=="undefined"&&process.versions.node;var Buffer_from=function(){};if(typeof Buffer!=="undefined"){var nbfs=!Buffer.from;if(!nbfs)try{Buffer.from("foo","utf8")}catch(e){nbfs=true}Buffer_from=nbfs?function(r,e){return e?new Buffer(r,e):new Buffer(r)}:Buffer.from.bind(Buffer);if(!Buffer.alloc)Buffer.alloc=function(r){return new Buffer(r)};if(!Buffer.allocUnsafe)Buffer.allocUnsafe=function(r){return new Buffer(r)}}function new_raw_buf(r){return has_buf?Buffer.alloc(r):new Array(r)}function new_unsafe_buf(r){return has_buf?Buffer.allocUnsafe(r):new Array(r)}var s2a=function e(r){if(has_buf)return Buffer_from(r,"binary");return r.split("").map(function(r){return r.charCodeAt(0)&255})};var chr0=/\u0000/g,chr1=/[\u0001-\u0006]/g;var __toBuffer=function(r){var e=[];for(var t=0;t<r[0].length;++t){e.push.apply(e,r[0][t])}return e};var ___toBuffer=__toBuffer;var __utf16le=function(r,e,t){var i=[];for(var n=e;n<t;n+=2)i.push(String.fromCharCode(__readUInt16LE(r,n)));return i.join("").replace(chr0,"")};var ___utf16le=__utf16le;var __hexlify=function(r,e,t){var i=[];for(var n=e;n<e+t;++n)i.push(("0"+r[n].toString(16)).slice(-2));return i.join("")};var ___hexlify=__hexlify;var __bconcat=function(r){if(Array.isArray(r[0]))return[].concat.apply([],r);var e=0,t=0;for(t=0;t<r.length;++t)e+=r[t].length;var i=new Uint8Array(e);for(t=0,e=0;t<r.length;e+=r[t].length,++t)i.set(r[t],e);return i};var bconcat=__bconcat;if(has_buf){__utf16le=function(r,e,t){if(!Buffer.isBuffer(r))return ___utf16le(r,e,t);return r.toString("utf16le",e,t).replace(chr0,"")};__hexlify=function(r,e,t){return Buffer.isBuffer(r)?r.toString("hex",e,e+t):___hexlify(r,e,t)};__toBuffer=function(r){return r[0].length>0&&Buffer.isBuffer(r[0][0])?Buffer.concat(r[0]):___toBuffer(r)};s2a=function(r){return Buffer_from(r,"binary")};bconcat=function(r){return Buffer.isBuffer(r[0])?Buffer.concat(r):__bconcat(r)}}var __readUInt8=function(r,e){return r[e]};var __readUInt16LE=function(r,e){return r[e+1]*(1<<8)+r[e]};var __readInt16LE=function(r,e){var t=r[e+1]*(1<<8)+r[e];return t<32768?t:(65535-t+1)*-1};var __readUInt32LE=function(r,e){return r[e+3]*(1<<24)+(r[e+2]<<16)+(r[e+1]<<8)+r[e]};var __readInt32LE=function(r,e){return(r[e+3]<<24)+(r[e+2]<<16)+(r[e+1]<<8)+r[e]};function ReadShift(r,e){var t,i,n=0;switch(r){case 1:t=__readUInt8(this,this.l);break;case 2:t=(e!=="i"?__readUInt16LE:__readInt16LE)(this,this.l);break;case 4:t=__readInt32LE(this,this.l);break;case 16:n=2;i=__hexlify(this,this.l,r);}this.l+=r;if(n===0)return t;return i}var __writeUInt32LE=function(r,e,t){r[t]=e&255;r[t+1]=e>>>8&255;r[t+2]=e>>>16&255;r[t+3]=e>>>24&255};var __writeInt32LE=function(r,e,t){r[t]=e&255;r[t+1]=e>>8&255;r[t+2]=e>>16&255;r[t+3]=e>>24&255};function WriteShift(r,e,t){var i=0,n=0;switch(t){case"hex":for(;n<r;++n){this[this.l++]=parseInt(e.slice(2*n,2*n+2),16)||0}return this;case"utf16le":var f=this.l+r;for(n=0;n<Math.min(e.length,r);++n){var a=e.charCodeAt(n);this[this.l++]=a&255;this[this.l++]=a>>8}while(this.l<f)this[this.l++]=0;return this;}switch(r){case 1:i=1;this[this.l]=e&255;break;case 2:i=2;this[this.l]=e&255;e>>>=8;this[this.l+1]=e&255;break;case 4:i=4;__writeUInt32LE(this,e,this.l);break;case-4:i=4;__writeInt32LE(this,e,this.l);break;}this.l+=i;return this}function CheckField(r,e){var t=__hexlify(this,this.l,r.length>>1);if(t!==r)throw new Error(e+"Expected "+r+" saw "+t);this.l+=r.length>>1}function prep_blob(r,e){r.l=e;r.read_shift=ReadShift;r.chk=CheckField;r.write_shift=WriteShift}function new_buf(r){var e=new_raw_buf(r);prep_blob(e,0);return e}var CRC32;(function(r){r(CRC32={})})(function(r){r.version="1.2.0";function e(){var r=0,e=new Array(256);for(var t=0;t!=256;++t){r=t;r=r&1?-306674912^r>>>1:r>>>1;r=r&1?-306674912^r>>>1:r>>>1;r=r&1?-306674912^r>>>1:r>>>1;r=r&1?-306674912^r>>>1:r>>>1;r=r&1?-306674912^r>>>1:r>>>1;r=r&1?-306674912^r>>>1:r>>>1;r=r&1?-306674912^r>>>1:r>>>1;r=r&1?-306674912^r>>>1:r>>>1;e[t]=r}return typeof Int32Array!=="undefined"?new Int32Array(e):e}var t=e();function i(r,e){var i=e^-1,n=r.length-1;for(var f=0;f<n;){i=i>>>8^t[(i^r.charCodeAt(f++))&255];i=i>>>8^t[(i^r.charCodeAt(f++))&255]}if(f===n)i=i>>>8^t[(i^r.charCodeAt(f))&255];return i^-1}function n(r,e){if(r.length>1e4)return f(r,e);var i=e^-1,n=r.length-3;for(var a=0;a<n;){i=i>>>8^t[(i^r[a++])&255];i=i>>>8^t[(i^r[a++])&255];i=i>>>8^t[(i^r[a++])&255];i=i>>>8^t[(i^r[a++])&255]}while(a<n+3)i=i>>>8^t[(i^r[a++])&255];return i^-1}function f(r,e){var i=e^-1,n=r.length-7;for(var f=0;f<n;){i=i>>>8^t[(i^r[f++])&255];i=i>>>8^t[(i^r[f++])&255];i=i>>>8^t[(i^r[f++])&255];i=i>>>8^t[(i^r[f++])&255];i=i>>>8^t[(i^r[f++])&255];i=i>>>8^t[(i^r[f++])&255];i=i>>>8^t[(i^r[f++])&255];i=i>>>8^t[(i^r[f++])&255]}while(f<n+7)i=i>>>8^t[(i^r[f++])&255];return i^-1}function a(r,e){var i=e^-1;for(var n=0,f=r.length,a,s;n<f;){a=r.charCodeAt(n++);if(a<128){i=i>>>8^t[(i^a)&255]}else if(a<2048){i=i>>>8^t[(i^(192|a>>6&31))&255];i=i>>>8^t[(i^(128|a&63))&255]}else if(a>=55296&&a<57344){a=(a&1023)+64;s=r.charCodeAt(n++)&1023;i=i>>>8^t[(i^(240|a>>8&7))&255];i=i>>>8^t[(i^(128|a>>2&63))&255];i=i>>>8^t[(i^(128|s>>6&15|(a&3)<<4))&255];i=i>>>8^t[(i^(128|s&63))&255]}else{i=i>>>8^t[(i^(224|a>>12&15))&255];i=i>>>8^t[(i^(128|a>>6&63))&255];i=i>>>8^t[(i^(128|a&63))&255]}}return i^-1}r.table=t;r.bstr=i;r.buf=n;r.str=a});var CFB=function t(){var r={};r.version="1.1.0";function e(r,e){var t=r.split("/"),i=e.split("/");for(var n=0,f=0,a=Math.min(t.length,i.length);n<a;++n){if(f=t[n].length-i[n].length)return f;if(t[n]!=i[n])return t[n]<i[n]?-1:1}return t.length-i.length}function t(r){if(r.charAt(r.length-1)=="/")return r.slice(0,-1).indexOf("/")===-1?r:t(r.slice(0,-1));var e=r.lastIndexOf("/");return e===-1?r:r.slice(0,e+1)}function i(r){if(r.charAt(r.length-1)=="/")return i(r.slice(0,-1));var e=r.lastIndexOf("/");return e===-1?r:r.slice(e+1)}function n(r,e){if(typeof e==="string")e=new Date(e);var t=e.getHours();t=t<<6|e.getMinutes();t=t<<5|e.getSeconds()>>>1;r.write_shift(2,t);var i=e.getFullYear()-1980;i=i<<4|e.getMonth()+1;i=i<<5|e.getDate();r.write_shift(2,i)}function f(r){var e=r.read_shift(2)&65535;var t=r.read_shift(2)&65535;var i=new Date;var n=t&31;t>>>=5;var f=t&15;t>>>=4;i.setMilliseconds(0);i.setFullYear(t+1980);i.setMonth(f-1);i.setDate(n);var a=e&31;e>>>=5;var s=e&63;e>>>=6;i.setHours(e);i.setMinutes(s);i.setSeconds(a<<1);return i}function a(r){prep_blob(r,0);var e={};var t=0;while(r.l<=r.length-4){var i=r.read_shift(2);var n=r.read_shift(2),f=r.l+n;var a={};switch(i){case 21589:{t=r.read_shift(1);if(t&1)a.mtime=r.read_shift(4);if(n>5){if(t&2)a.atime=r.read_shift(4);if(t&4)a.ctime=r.read_shift(4)}if(a.mtime)a.mt=new Date(a.mtime*1e3)}break;}r.l=f;e[i]=a}return e}var s;function h(){return s||(s=require("fs"))}function l(r,e){if(r[0]==80&&r[1]==75)return wr(r,e);if(r.length<512)throw new Error("CFB file size "+r.length+" < 512");var t=3;var i=512;var n=0;var f=0;var a=0;var s=0;var h=0;var l=[];var v=r.slice(0,512);prep_blob(v,0);var w=o(v);t=w[0];switch(t){case 3:i=512;break;case 4:i=4096;break;case 0:if(w[1]==0)return wr(r,e);default:throw new Error("Major Version: Expected 3 or 4 saw "+t);}if(i!==512){v=r.slice(0,i);prep_blob(v,28)}var b=r.slice(0,i);u(v,t);var F=v.read_shift(4,"i");if(t===3&&F!==0)throw new Error("# Directory Sectors: Expected 0 saw "+F);v.l+=4;a=v.read_shift(4,"i");v.l+=4;v.chk("00100000","Mini Stream Cutoff Size: ");s=v.read_shift(4,"i");n=v.read_shift(4,"i");h=v.read_shift(4,"i");f=v.read_shift(4,"i");for(var y=-1,I=0;I<109;++I){y=v.read_shift(4,"i");if(y<0)break;l[I]=y}var C=c(r,i);d(h,f,C,i,l);var x=p(C,a,l,i);x[a].name="!Directory";if(n>0&&s!==B)x[s].name="!MiniFAT";x[l[0]].name="!FAT";x.fat_addrs=l;x.ssz=i;var m={},E=[],A=[],S=[];g(a,x,C,E,n,m,A,s);_(A,S,E);E.shift();var k={FileIndex:A,FullPaths:S};if(e&&e.raw)k.raw={header:b,sectors:C};return k}function o(r){if(r[r.l]==80&&r[r.l+1]==75)return[0,0];r.chk(S,"Header Signature: ");r.chk(R,"CLSID: ");var e=r.read_shift(2,"u");return[r.read_shift(2,"u"),e]}function u(r,e){var t=9;r.l+=2;switch(t=r.read_shift(2)){case 9:if(e!=3)throw new Error("Sector Shift: Expected 9 saw "+t);break;case 12:if(e!=4)throw new Error("Sector Shift: Expected 12 saw "+t);break;default:throw new Error("Sector Shift: Expected 9 or 12 saw "+t);}r.chk("0600","Mini Sector Shift: ");r.chk("000000000000","Reserved: ")}function c(r,e){var t=Math.ceil(r.length/e)-1;var i=[];for(var n=1;n<t;++n)i[n-1]=r.slice(n*e,(n+1)*e);i[t-1]=r.slice(t*e);return i}function _(r,e,t){var i=0,n=0,f=0,a=0,s=0,h=t.length;var l=[],o=[];for(;i<h;++i){l[i]=o[i]=i;e[i]=t[i]}for(;s<o.length;++s){i=o[s];n=r[i].L;f=r[i].R;a=r[i].C;if(l[i]===i){if(n!==-1&&l[n]!==n)l[i]=l[n];if(f!==-1&&l[f]!==f)l[i]=l[f]}if(a!==-1)l[a]=i;if(n!==-1){l[n]=l[i];if(o.lastIndexOf(n)<s)o.push(n)}if(f!==-1){l[f]=l[i];if(o.lastIndexOf(f)<s)o.push(f)}}for(i=1;i<h;++i)if(l[i]===i){if(f!==-1&&l[f]!==f)l[i]=l[f];else if(n!==-1&&l[n]!==n)l[i]=l[n]}for(i=1;i<h;++i){if(r[i].type===0)continue;s=l[i];if(s===0)e[i]=e[0]+"/"+e[i];else while(s!==0&&s!==l[s]){e[i]=e[s]+"/"+e[i];s=l[s]}l[i]=0}e[0]+="/";for(i=1;i<h;++i){if(r[i].type!==2)e[i]+="/"}}function v(r,e,t){var i=r.start,n=r.size;var f=[];var a=i;while(t&&n>0&&a>=0){f.push(e.slice(a*A,a*A+A));n-=A;a=__readInt32LE(t,a*4)}if(f.length===0)return new_buf(0);return bconcat(f).slice(0,r.size)}function d(r,e,t,i,n){var f=B;if(r===B){if(e!==0)throw new Error("DIFAT chain shorter than expected")}else if(r!==-1){var a=t[r],s=(i>>>2)-1;if(!a)return;for(var h=0;h<s;++h){if((f=__readInt32LE(a,h*4))===B)break;n.push(f)}d(__readInt32LE(a,i-4),e-1,t,i,n)}}function w(r,e,t,i,n){var f=[],a=[];if(!n)n=[];var s=i-1,h=0,l=0;for(h=e;h>=0;){n[h]=true;f[f.length]=h;a.push(r[h]);var o=t[Math.floor(h*4/i)];l=h*4&s;if(i<4+l)throw new Error("FAT boundary crossed: "+h+" 4 "+i);if(!r[o])break;h=__readInt32LE(r[o],l)}return{nodes:f,data:__toBuffer([a])}}function p(r,e,t,i){var n=r.length,f=[];var a=[],s=[],h=[];var l=i-1,o=0,u=0,c=0,_=0;for(o=0;o<n;++o){s=[];c=o+e;if(c>=n)c-=n;if(a[c])continue;h=[];for(u=c;u>=0;){a[u]=true;s[s.length]=u;h.push(r[u]);var v=t[Math.floor(u*4/i)];_=u*4&l;if(i<4+_)throw new Error("FAT boundary crossed: "+u+" 4 "+i);if(!r[v])break;u=__readInt32LE(r[v],_)}f[c]={nodes:s,data:__toBuffer([h])}}return f}function g(r,e,t,i,n,f,a,s){var h=0,l=i.length?2:0;var o=e[r].data;var u=0,c=0,_;for(;u<o.length;u+=128){var d=o.slice(u,u+128);prep_blob(d,64);c=d.read_shift(2);_=__utf16le(d,0,c-l);i.push(_);var p={name:_,type:d.read_shift(1),color:d.read_shift(1),L:d.read_shift(4,"i"),R:d.read_shift(4,"i"),C:d.read_shift(4,"i"),clsid:d.read_shift(16),state:d.read_shift(4,"i"),start:0,size:0};var g=d.read_shift(2)+d.read_shift(2)+d.read_shift(2)+d.read_shift(2);if(g!==0)p.ct=b(d,d.l-8);var F=d.read_shift(2)+d.read_shift(2)+d.read_shift(2)+d.read_shift(2);if(F!==0)p.mt=b(d,d.l-8);p.start=d.read_shift(4,"i");p.size=d.read_shift(4,"i");if(p.size<0&&p.start<0){p.size=p.type=0;p.start=B;p.name=""}if(p.type===5){h=p.start;if(n>0&&h!==B)e[h].name="!StreamData"}else if(p.size>=4096){p.storage="fat";if(e[p.start]===undefined)e[p.start]=w(t,p.start,e.fat_addrs,e.ssz);e[p.start].name=p.name;p.content=e[p.start].data.slice(0,p.size)}else{p.storage="minifat";if(p.size<0)p.size=0;else if(h!==B&&p.start!==B&&e[h]){p.content=v(p,e[h].data,(e[s]||{}).data)}}if(p.content)prep_blob(p.content,0);f[_]=p;a.push(p)}}function b(r,e){return new Date((__readUInt32LE(r,e+4)/1e7*Math.pow(2,32)+__readUInt32LE(r,e)/1e7-11644473600)*1e3)}function F(r,e){h();return l(s.readFileSync(r),e)}function y(r,e){switch(e&&e.type||"base64"){case"file":return F(r,e);case"base64":return l(s2a(Base64.decode(r)),e);case"binary":return l(s2a(r),e);}return l(r,e)}function I(r,e){var t=e||{},i=t.root||"Root Entry";if(!r.FullPaths)r.FullPaths=[];if(!r.FileIndex)r.FileIndex=[];if(r.FullPaths.length!==r.FileIndex.length)throw new Error("inconsistent CFB structure");if(r.FullPaths.length===0){r.FullPaths[0]=i+"/";r.FileIndex[0]={name:i,type:5}}if(t.CLSID)r.FileIndex[0].clsid=t.CLSID;C(r)}function C(r){var e="Sh33tJ5";if(CFB.find(r,"/"+e))return;var t=new_buf(4);t[0]=55;t[1]=t[3]=50;t[2]=54;r.FileIndex.push({name:e,type:2,content:t,size:4,L:69,R:69,C:69});r.FullPaths.push(r.FullPaths[0]+e);x(r)}function x(r,n){I(r);var f=false,a=false;for(var s=r.FullPaths.length-1;s>=0;--s){var h=r.FileIndex[s];switch(h.type){case 0:if(a)f=true;else{r.FileIndex.pop();r.FullPaths.pop()}break;case 1:;case 2:;case 5:a=true;if(isNaN(h.R*h.L*h.C))f=true;if(h.R>-1&&h.L>-1&&h.R==h.L)f=true;break;default:f=true;break;}}if(!f&&!n)return;var l=new Date(1987,1,19),o=0;var u=[];for(s=0;s<r.FullPaths.length;++s){if(r.FileIndex[s].type===0)continue;u.push([r.FullPaths[s],r.FileIndex[s]])}for(s=0;s<u.length;++s){var c=t(u[s][0]);a=false;for(o=0;o<u.length;++o)if(u[o][0]===c)a=true;if(!a)u.push([c,{name:i(c).replace("/",""),type:1,clsid:R,ct:l,mt:l,content:null}])}u.sort(function(r,t){return e(r[0],t[0])});r.FullPaths=[];r.FileIndex=[];for(s=0;s<u.length;++s){r.FullPaths[s]=u[s][0];r.FileIndex[s]=u[s][1]}for(s=0;s<u.length;++s){var _=r.FileIndex[s];var v=r.FullPaths[s];_.name=i(v).replace("/","");_.L=_.R=_.C=-(_.color=1);_.size=_.content?_.content.length:0;_.start=0;_.clsid=_.clsid||R;if(s===0){_.C=u.length>1?1:-1;_.size=0;_.type=5}else if(v.slice(-1)=="/"){for(o=s+1;o<u.length;++o)if(t(r.FullPaths[o])==v)break;_.C=o>=u.length?-1:o;for(o=s+1;o<u.length;++o)if(t(r.FullPaths[o])==t(v))break;_.R=o>=u.length?-1:o;_.type=1}else{if(t(r.FullPaths[s+1]||"")==t(v))_.R=s+1;_.type=2}}}function m(r,e){var t=e||{};x(r);if(t.fileType=="zip")return gr(r,t);var i=function(r){var e=0,t=0;for(var i=0;i<r.FileIndex.length;++i){var n=r.FileIndex[i];if(!n.content)continue;var f=n.content.length;if(f>0){if(f<4096)e+=f+63>>6;else t+=f+511>>9}}var a=r.FullPaths.length+3>>2;var s=e+7>>3;var h=e+127>>7;var l=s+t+a+h;var o=l+127>>7;var u=o<=109?0:Math.ceil((o-109)/127);while(l+o+u+127>>7>o)u=++o<=109?0:Math.ceil((o-109)/127);var c=[1,u,o,h,a,t,e,0];r.FileIndex[0].size=e<<6;c[7]=(r.FileIndex[0].start=c[0]+c[1]+c[2]+c[3]+c[4]+c[5])+(c[6]+7>>3);return c}(r);var n=new_buf(i[7]<<9);var f=0,a=0;{for(f=0;f<8;++f)n.write_shift(1,k[f]);for(f=0;f<8;++f)n.write_shift(2,0);n.write_shift(2,62);n.write_shift(2,3);n.write_shift(2,65534);n.write_shift(2,9);n.write_shift(2,6);for(f=0;f<3;++f)n.write_shift(2,0);n.write_shift(4,0);n.write_shift(4,i[2]);n.write_shift(4,i[0]+i[1]+i[2]+i[3]-1);n.write_shift(4,0);n.write_shift(4,1<<12);n.write_shift(4,i[3]?i[0]+i[1]+i[2]-1:B);n.write_shift(4,i[3]);n.write_shift(-4,i[1]?i[0]-1:B);n.write_shift(4,i[1]);for(f=0;f<109;++f)n.write_shift(-4,f<i[2]?i[1]+f:-1)}if(i[1]){for(a=0;a<i[1];++a){for(;f<236+a*127;++f)n.write_shift(-4,f<i[2]?i[1]+f:-1);n.write_shift(-4,a===i[1]-1?B:a+1)}}var s=function(r){for(a+=r;f<a-1;++f)n.write_shift(-4,f+1);if(r){++f;n.write_shift(-4,B)}};a=f=0;for(a+=i[1];f<a;++f)n.write_shift(-4,z.DIFSECT);for(a+=i[2];f<a;++f)n.write_shift(-4,z.FATSECT);s(i[3]);s(i[4]);var h=0,l=0;var o=r.FileIndex[0];for(;h<r.FileIndex.length;++h){o=r.FileIndex[h];if(!o.content)continue;l=o.content.length;if(l<4096)continue;o.start=a;s(l+511>>9)}s(i[6]+7>>3);while(n.l&511)n.write_shift(-4,z.ENDOFCHAIN);a=f=0;for(h=0;h<r.FileIndex.length;++h){o=r.FileIndex[h];if(!o.content)continue;l=o.content.length;if(!l||l>=4096)continue;o.start=a;s(l+63>>6)}while(n.l&511)n.write_shift(-4,z.ENDOFCHAIN);for(f=0;f<i[4]<<2;++f){var u=r.FullPaths[f];if(!u||u.length===0){for(h=0;h<17;++h)n.write_shift(4,0);for(h=0;h<3;++h)n.write_shift(4,-1);for(h=0;h<12;++h)n.write_shift(4,0);continue}o=r.FileIndex[f];if(f===0)o.start=o.size?o.start-1:B;var c=f===0&&t.root||o.name;l=2*(c.length+1);n.write_shift(64,c,"utf16le");n.write_shift(2,l);n.write_shift(1,o.type);n.write_shift(1,o.color);n.write_shift(-4,o.L);n.write_shift(-4,o.R);n.write_shift(-4,o.C);if(!o.clsid)for(h=0;h<4;++h)n.write_shift(4,0);else n.write_shift(16,o.clsid,"hex");n.write_shift(4,o.state||0);n.write_shift(4,0);n.write_shift(4,0);n.write_shift(4,0);n.write_shift(4,0);n.write_shift(4,o.start);n.write_shift(4,o.size);n.write_shift(4,0)}for(f=1;f<r.FileIndex.length;++f){o=r.FileIndex[f];if(o.size>=4096){n.l=o.start+1<<9;for(h=0;h<o.size;++h)n.write_shift(1,o.content[h]);for(;h&511;++h)n.write_shift(1,0)}}for(f=1;f<r.FileIndex.length;++f){o=r.FileIndex[f];if(o.size>0&&o.size<4096){for(h=0;h<o.size;++h)n.write_shift(1,o.content[h]);for(;h&63;++h)n.write_shift(1,0)}}while(n.l<n.length)n.write_shift(1,0);return n}function E(r,e){var t=r.FullPaths.map(function(r){return r.toUpperCase()});var i=t.map(function(r){var e=r.split("/");return e[e.length-(r.slice(-1)=="/"?2:1)]});var n=false;if(e.charCodeAt(0)===47){n=true;e=t[0].slice(0,-1)+e}else n=e.indexOf("/")!==-1;var f=e.toUpperCase();var a=n===true?t.indexOf(f):i.indexOf(f);if(a!==-1)return r.FileIndex[a];var s=!f.match(chr1);f=f.replace(chr0,"");if(s)f=f.replace(chr1,"!");for(a=0;a<t.length;++a){if((s?t[a].replace(chr1,"!"):t[a]).replace(chr0,"")==f)return r.FileIndex[a];if((s?i[a].replace(chr1,"!"):i[a]).replace(chr0,"")==f)return r.FileIndex[a]}return null}var A=64;var B=-2;var S="d0cf11e0a1b11ae1";var k=[208,207,17,224,161,177,26,225];var R="00000000000000000000000000000000";var z={MAXREGSECT:-6,DIFSECT:-4,FATSECT:-3,ENDOFCHAIN:B,FREESECT:-1,HEADER_SIGNATURE:S,HEADER_MINOR_VERSION:"3e00",MAXREGSID:-6,NOSTREAM:-1,HEADER_CLSID:R,EntryTypes:["unknown","storage","stream","lockbytes","property","root"]};function L(r,e,t){h();var i=m(r,t);s.writeFileSync(e,i)}function U(r){var e=new Array(r.length);for(var t=0;t<r.length;++t)e[t]=String.fromCharCode(r[t]);return e.join("")}function P(r,e){var t=m(r,e);switch(e&&e.type){case"file":h();s.writeFileSync(e.filename,t);return t;case"binary":return U(t);case"base64":return Base64.encode(U(t));}return t}var D;function M(r){try{var e=r.InflateRaw;var t=new e;t._processChunk(new Uint8Array([3,0]),t._finishFlushFlag);if(t.bytesRead)D=r;else throw new Error("zlib does not expose bytesRead")}catch(i){console.error("cannot use native zlib: "+(i.message||i))}}function O(r,e){if(!D)return vr(r,e);var t=D.InflateRaw;var i=new t;var n=i._processChunk(r.slice(r.l),i._finishFlushFlag);r.l+=i.bytesRead;return n}function T(r){return D?D.deflateRawSync(r):tr(r)}var N=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];var H=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258];var j=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577];function G(r){var e=(r<<1|r<<11)&139536|(r<<5|r<<15)&558144;return(e>>16|e>>8|e)&255}var X=typeof Uint8Array!=="undefined";var q=X?new Uint8Array(1<<8):[];for(var J=0;J<1<<8;++J)q[J]=G(J);function V(r,e){var t=q[r&255];if(e<=8)return t>>>8-e;t=t<<8|q[r>>8&255];if(e<=16)return t>>>16-e;t=t<<8|q[r>>16&255];return t>>>24-e}function W(r,e){var t=e&7,i=e>>>3;return(r[i]|(t<=6?0:r[i+1]<<8))>>>t&3}function Y(r,e){var t=e&7,i=e>>>3;return(r[i]|(t<=5?0:r[i+1]<<8))>>>t&7}function Z(r,e){var t=e&7,i=e>>>3;return(r[i]|(t<=4?0:r[i+1]<<8))>>>t&15}function K(r,e){var t=e&7,i=e>>>3;return(r[i]|(t<=3?0:r[i+1]<<8))>>>t&31}function Q(r,e){var t=e&7,i=e>>>3;return(r[i]|(t<=1?0:r[i+1]<<8))>>>t&127}function $(r,e,t){var i=e&7,n=e>>>3,f=(1<<t)-1;var a=r[n]>>>i;if(t<8-i)return a&f;a|=r[n+1]<<8-i;if(t<16-i)return a&f;a|=r[n+2]<<16-i;if(t<24-i)return a&f;a|=r[n+3]<<24-i;return a&f}function rr(r,e){var t=r.length,i=2*t>e?2*t:e+5,n=0;if(t>=e)return r;if(has_buf){var f=new_unsafe_buf(i);if(r.copy)r.copy(f);else for(;n<r.length;++n)f[n]=r[n];return f}else if(X){var a=new Uint8Array(i);if(a.set)a.set(r);else for(;n<r.length;++n)a[n]=r[n];return a}r.length=i;return r}function er(r){var e=new Array(r);for(var t=0;t<r;++t)e[t]=0;return e}var tr=function(){var r=function(){return function r(e,t){var i=0;while(i<e.length){var n=Math.min(65535,e.length-i);var f=i+n==e.length;t.write_shift(1,+f);t.write_shift(2,n);t.write_shift(2,~n&65535);while(n-- >0)t[t.l++]=e[i++]}return t.l}}();return function(e){var t=new_buf(50+Math.floor(e.length*1.1));var i=r(e,t);return t.slice(0,i)}}();function ir(r,e,t){var i=1,n=0,f=0,a=0,s=0,h=r.length;var l=X?new Uint16Array(32):er(32);for(f=0;f<32;++f)l[f]=0;for(f=h;f<t;++f)r[f]=0;h=r.length;var o=X?new Uint16Array(h):er(h);for(f=0;f<h;++f){l[n=r[f]]++;if(i<n)i=n;o[f]=0}l[0]=0;for(f=1;f<=i;++f)l[f+16]=s=s+l[f-1]<<1;for(f=0;f<h;++f){s=r[f];if(s!=0)o[f]=l[s+16]++}var u=0;for(f=0;f<h;++f){u=r[f];if(u!=0){s=V(o[f],i)>>i-u;for(a=(1<<i+4-u)-1;a>=0;--a)e[s|a<<u]=u&15|f<<4}}return i}var nr=X?new Uint16Array(512):er(512);var fr=X?new Uint16Array(32):er(32);if(!X){for(var ar=0;ar<512;++ar)nr[ar]=0;for(ar=0;ar<32;++ar)fr[ar]=0}(function(){var r=[];var e=0;for(;e<32;e++)r.push(5);ir(r,fr,32);var t=[];e=0;for(;e<=143;e++)t.push(8);for(;e<=255;e++)t.push(9);for(;e<=279;e++)t.push(7);for(;e<=287;e++)t.push(8);ir(t,nr,288)})();var sr=X?new Uint16Array(32768):er(32768);var hr=X?new Uint16Array(32768):er(32768);var lr=X?new Uint16Array(128):er(128);var or=1,ur=1;function cr(r,e){var t=K(r,e)+257;e+=5;var i=K(r,e)+1;e+=5;var n=Z(r,e)+4;e+=4;var f=0;var a=X?new Uint8Array(19):er(19);var s=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];var h=1;var l=X?new Uint8Array(8):er(8);var o=X?new Uint8Array(8):er(8);var u=a.length;for(var c=0;c<n;++c){a[N[c]]=f=Y(r,e);if(h<f)h=f;l[f]++;e+=3}var _=0;l[0]=0;for(c=1;c<=h;++c)o[c]=_=_+l[c-1]<<1;for(c=0;c<u;++c)if((_=a[c])!=0)s[c]=o[_]++;var v=0;for(c=0;c<u;++c){v=a[c];if(v!=0){_=q[s[c]]>>8-v;for(var d=(1<<7-v)-1;d>=0;--d)lr[_|d<<v]=v&7|c<<3}}var w=[];h=1;for(;w.length<t+i;){_=lr[Q(r,e)];e+=_&7;switch(_>>>=3){case 16:f=3+W(r,e);e+=2;_=w[w.length-1];while(f-- >0)w.push(_);break;case 17:f=3+Y(r,e);e+=3;while(f-- >0)w.push(0);break;case 18:f=11+Q(r,e);e+=7;while(f-- >0)w.push(0);break;default:w.push(_);if(h<_)h=_;break;}}var p=w.slice(0,t),g=w.slice(t);for(c=t;c<286;++c)p[c]=0;for(c=i;c<30;++c)g[c]=0;or=ir(p,sr,286);ur=ir(g,hr,30);return e}function _r(r,e){if(r[0]==3&&!(r[1]&3)){return[new_raw_buf(e),2]}var t=0;var i=0;var n=new_unsafe_buf(e?e:1<<18);var f=0;var a=n.length>>>0;var s=0,h=0;while((i&1)==0){i=Y(r,t);t+=3;if(i>>>1==0){if(t&7)t+=8-(t&7);var l=r[t>>>3]|r[(t>>>3)+1]<<8;t+=32;if(!e&&a<f+l){n=rr(n,f+l);a=n.length}if(typeof r.copy==="function"){r.copy(n,f,t>>>3,(t>>>3)+l);f+=l;t+=8*l}else while(l-- >0){n[f++]=r[t>>>3];t+=8}continue}else if(i>>>1==1){s=9;h=5}else{t=cr(r,t);s=or;h=ur}if(!e&&a<f+32767){n=rr(n,f+32767);a=n.length}for(;;){var o=$(r,t,s);var u=i>>>1==1?nr[o]:sr[o];t+=u&15;u>>>=4;if((u>>>8&255)===0)n[f++]=u;else if(u==256)break;else{u-=257;var c=u<8?0:u-4>>2;if(c>5)c=0;var _=f+H[u];if(c>0){_+=$(r,t,c);t+=c}o=$(r,t,h);u=i>>>1==1?fr[o]:hr[o];t+=u&15;u>>>=4;var v=u<4?0:u-2>>1;var d=j[u];if(v>0){d+=$(r,t,v);t+=v}if(!e&&a<_){n=rr(n,_);a=n.length}while(f<_){n[f]=n[f-d];++f}}}}return[e?n:n.slice(0,f),t+7>>>3]}function vr(r,e){var t=r.slice(r.l||0);var i=_r(t,e);r.l+=i[1];return i[0]}function dr(r,e){if(r){if(typeof console!=="undefined")console.error(e)}else throw new Error(e)}function wr(r,e){var t=r;prep_blob(t,0);var i=[],n=[];var f={FileIndex:i,FullPaths:n};I(f,{root:e.root});var s=t.length-4;while((t[s]!=80||t[s+1]!=75||t[s+2]!=5||t[s+3]!=6)&&s>=0)--s;t.l=s+4;t.l+=4;var h=t.read_shift(2);t.l+=6;var l=t.read_shift(4);t.l=l;for(s=0;s<h;++s){t.l+=20;var o=t.read_shift(4);var u=t.read_shift(4);var c=t.read_shift(2);var _=t.read_shift(2);var v=t.read_shift(2);t.l+=8;var d=t.read_shift(4);var w=a(t.slice(t.l+c,t.l+c+_));t.l+=c+_+v;var p=t.l;t.l=d+4;pr(t,o,u,f,w);t.l=p}return f}function pr(r,e,t,i,n){r.l+=2;var s=r.read_shift(2);var h=r.read_shift(2);var l=f(r);if(s&8257)throw new Error("Unsupported ZIP encryption");var o=r.read_shift(4);var u=r.read_shift(4);var c=r.read_shift(4);var _=r.read_shift(2);var v=r.read_shift(2);var d="";for(var w=0;w<_;++w)d+=String.fromCharCode(r[r.l++]);if(v){var p=a(r.slice(r.l,r.l+v));if((p[21589]||{}).mt)l=p[21589].mt;if(((n||{})[21589]||{}).mt)l=n[21589].mt}r.l+=v;var g=r.slice(r.l,r.l+u);switch(h){case 8:g=O(r,c);break;case 0:break;default:throw new Error("Unsupported ZIP Compression method "+h);}var b=false;if(s&8){o=r.read_shift(4);if(o==134695760){o=r.read_shift(4);b=true}u=r.read_shift(4);c=r.read_shift(4)}if(u!=e)dr(b,"Bad compressed size: "+e+" != "+u);if(c!=t)dr(b,"Bad uncompressed size: "+t+" != "+c);var F=CRC32.buf(g,0);if(o!=F)dr(b,"Bad CRC32 checksum: "+o+" != "+F);Fr(i,d,g,{unsafe:true,mt:l})}function gr(r,e){var t=e||{};var i=[],f=[];var a=new_buf(1);var s=t.compression?8:0,h=0;var l=false;if(l)h|=8;var o=0,u=0;var c=0,_=0;var v=r.FullPaths[0],d=v,w=r.FileIndex[0];var p=[];var g=0;for(o=1;o<r.FullPaths.length;++o){d=r.FullPaths[o].slice(v.length);w=r.FileIndex[o];if(!w.size||!w.content||d=="Sh33tJ5")continue;var b=c;var F=new_buf(d.length);for(u=0;u<d.length;++u)F.write_shift(1,d.charCodeAt(u)&127);F=F.slice(0,F.l);p[_]=CRC32.buf(w.content,0);var y=w.content;if(s==8)y=T(y);a=new_buf(30);a.write_shift(4,67324752);a.write_shift(2,20);a.write_shift(2,h);a.write_shift(2,s);if(w.mt)n(a,w.mt);else a.write_shift(4,0);a.write_shift(-4,h&8?0:p[_]);a.write_shift(4,h&8?0:y.length);a.write_shift(4,h&8?0:w.content.length);a.write_shift(2,F.length);a.write_shift(2,0);c+=a.length;i.push(a);c+=F.length;i.push(F);c+=y.length;i.push(y);if(h&8){a=new_buf(12);a.write_shift(-4,p[_]);a.write_shift(4,y.length);a.write_shift(4,w.content.length);c+=a.l;i.push(a)}a=new_buf(46);a.write_shift(4,33639248);a.write_shift(2,0);a.write_shift(2,20);a.write_shift(2,h);a.write_shift(2,s);a.write_shift(4,0);a.write_shift(-4,p[_]);a.write_shift(4,y.length);a.write_shift(4,w.content.length);a.write_shift(2,F.length);a.write_shift(2,0);a.write_shift(2,0);a.write_shift(2,0);a.write_shift(2,0);a.write_shift(4,0);a.write_shift(4,b);g+=a.l;f.push(a);g+=F.length;f.push(F);++_}a=new_buf(22);a.write_shift(4,101010256);a.write_shift(2,0);a.write_shift(2,0);a.write_shift(2,_);a.write_shift(2,_);a.write_shift(4,g);a.write_shift(4,c);a.write_shift(2,0);return bconcat([bconcat(i),bconcat(f),a])}function br(r){var e={};I(e,r);return e}function Fr(r,e,t,n){var f=n&&n.unsafe;if(!f)I(r);var a=!f&&CFB.find(r,e);if(!a){var s=r.FullPaths[0];if(e.slice(0,s.length)==s)s=e;else{if(s.slice(-1)!="/")s+="/";s=(s+e).replace("//","/")}a={name:i(e),type:2};r.FileIndex.push(a);r.FullPaths.push(s);if(!f)CFB.utils.cfb_gc(r)}a.content=t;a.size=t?t.length:0;if(n){if(n.CLSID)a.clsid=n.CLSID;if(n.mt)a.mt=n.mt;if(n.ct)a.ct=n.ct}return a}function yr(r,e){I(r);var t=CFB.find(r,e);if(t)for(var i=0;i<r.FileIndex.length;++i)if(r.FileIndex[i]==t){r.FileIndex.splice(i,1);r.FullPaths.splice(i,1);return true}return false}function Ir(r,e,t){I(r);var n=CFB.find(r,e);if(n)for(var f=0;f<r.FileIndex.length;++f)if(r.FileIndex[f]==n){r.FileIndex[f].name=i(t);r.FullPaths[f]=t;return true}return false}function Cr(r){x(r,true)}r.find=E;r.read=y;r.parse=l;r.write=P;r.writeFile=L;r.utils={cfb_new:br,cfb_add:Fr,cfb_del:yr,cfb_mov:Ir,cfb_gc:Cr,ReadShift:ReadShift,CheckField:CheckField,prep_blob:prep_blob,bconcat:bconcat,use_zlib:M,_deflateRaw:tr,_inflateRaw:vr,consts:z};return r}();if(typeof require!=="undefined"&&typeof module!=="undefined"&&typeof DO_NOT_EXPORT_CFB==="undefined"){module.exports=CFB} |
@@ -15,3 +15,6 @@ var DO_NOT_EXPORT_CFB = true; | ||
declare var chr1:any; | ||
declare var has_buf:boolean; | ||
declare var new_buf:any; | ||
declare var new_raw_buf:any; | ||
declare var new_unsafe_buf:any; | ||
*/ | ||
@@ -22,3 +25,3 @@ /* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||
/*exported CFB */ | ||
/*global module, require:false, process:false, Buffer:false, Uint8Array:false */ | ||
/*global module, require:false, process:false, Buffer:false, Uint8Array:false, Uint16Array:false */ | ||
@@ -40,6 +43,107 @@ /*:: | ||
*/ | ||
/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ | ||
/* vim: set ts=2: */ | ||
/*exported CRC32 */ | ||
var CRC32; | ||
(function (factory) { | ||
/*jshint ignore:start */ | ||
/*eslint-disable */ | ||
factory(CRC32 = {}); | ||
/*eslint-enable */ | ||
/*jshint ignore:end */ | ||
}(function(CRC32) { | ||
CRC32.version = '1.2.0'; | ||
/* see perf/crc32table.js */ | ||
/*global Int32Array */ | ||
function signed_crc_table()/*:any*/ { | ||
var c = 0, table/*:Array<number>*/ = new Array(256); | ||
for(var n =0; n != 256; ++n){ | ||
c = n; | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
table[n] = c; | ||
} | ||
return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; | ||
} | ||
var T = signed_crc_table(); | ||
function crc32_bstr(bstr/*:string*/, seed/*:number*/)/*:number*/ { | ||
var C = seed ^ -1, L = bstr.length - 1; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; | ||
C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; | ||
} | ||
if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_buf(buf/*:Uint8Array|Array<number>*/, seed/*:number*/)/*:number*/ { | ||
if(buf.length > 10000) return crc32_buf_8(buf, seed); | ||
var C = seed ^ -1, L = buf.length - 3; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
} | ||
while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_buf_8(buf/*:Uint8Array|Array<number>*/, seed/*:number*/)/*:number*/ { | ||
var C = seed ^ -1, L = buf.length - 7; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
} | ||
while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_str(str/*:string*/, seed/*:number*/)/*:number*/ { | ||
var C = seed ^ -1; | ||
for(var i = 0, L=str.length, c, d; i < L;) { | ||
c = str.charCodeAt(i++); | ||
if(c < 0x80) { | ||
C = (C>>>8) ^ T[(C ^ c)&0xFF]; | ||
} else if(c < 0x800) { | ||
C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; | ||
} else if(c >= 0xD800 && c < 0xE000) { | ||
c = (c&1023)+64; d = str.charCodeAt(i++)&1023; | ||
C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; | ||
} else { | ||
C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; | ||
} | ||
} | ||
return C ^ -1; | ||
} | ||
CRC32.table = T; | ||
CRC32.bstr = crc32_bstr; | ||
CRC32.buf = crc32_buf; | ||
CRC32.str = crc32_str; | ||
})); | ||
/* [MS-CFB] v20171201 */ | ||
var CFB = (function _CFB(){ | ||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/; | ||
exports.version = '1.0.8'; | ||
exports.version = '1.1.0'; | ||
/* [MS-CFB] 2.6.4 */ | ||
@@ -65,5 +169,71 @@ function namecmp(l/*:string*/, r/*:string*/)/*:number*/ { | ||
} | ||
/* -------------------------------------------------------------------------- */ | ||
/* DOS Date format: | ||
high|YYYYYYYm.mmmddddd.HHHHHMMM.MMMSSSSS|low | ||
add 1980 to stored year | ||
stored second should be doubled | ||
*/ | ||
/* write JS date to buf as a DOS date */ | ||
function write_dos_date(buf/*:CFBlob*/, date/*:Date|string*/) { | ||
if(typeof date === "string") date = new Date(date); | ||
var hms/*:number*/ = date.getHours(); | ||
hms = hms << 6 | date.getMinutes(); | ||
hms = hms << 5 | (date.getSeconds()>>>1); | ||
buf.write_shift(2, hms); | ||
var ymd/*:number*/ = (date.getFullYear() - 1980); | ||
ymd = ymd << 4 | (date.getMonth()+1); | ||
ymd = ymd << 5 | date.getDate(); | ||
buf.write_shift(2, ymd); | ||
} | ||
/* read four bytes from buf and interpret as a DOS date */ | ||
function parse_dos_date(buf/*:CFBlob*/)/*:Date*/ { | ||
var hms = buf.read_shift(2) & 0xFFFF; | ||
var ymd = buf.read_shift(2) & 0xFFFF; | ||
var val = new Date(); | ||
var d = ymd & 0x1F; ymd >>>= 5; | ||
var m = ymd & 0x0F; ymd >>>= 4; | ||
val.setMilliseconds(0); | ||
val.setFullYear(ymd + 1980); | ||
val.setMonth(m-1); | ||
val.setDate(d); | ||
var S = hms & 0x1F; hms >>>= 5; | ||
var M = hms & 0x3F; hms >>>= 6; | ||
val.setHours(hms); | ||
val.setMinutes(M); | ||
val.setSeconds(S<<1); | ||
return val; | ||
} | ||
function parse_extra_field(blob/*:CFBlob*/)/*:any*/ { | ||
prep_blob(blob, 0); | ||
var o = /*::(*/{}/*:: :any)*/; | ||
var flags = 0; | ||
while(blob.l <= blob.length - 4) { | ||
var type = blob.read_shift(2); | ||
var sz = blob.read_shift(2), tgt = blob.l + sz; | ||
var p = {}; | ||
switch(type) { | ||
/* UNIX-style Timestamps */ | ||
case 0x5455: { | ||
flags = blob.read_shift(1); | ||
if(flags & 1) p.mtime = blob.read_shift(4); | ||
/* for some reason, CD flag corresponds to LFH */ | ||
if(sz > 5) { | ||
if(flags & 2) p.atime = blob.read_shift(4); | ||
if(flags & 4) p.ctime = blob.read_shift(4); | ||
} | ||
if(p.mtime) p.mt = new Date(p.mtime*1000); | ||
} | ||
break; | ||
} | ||
blob.l = tgt; | ||
o[type] = p; | ||
} | ||
return o; | ||
} | ||
var fs/*:: = require('fs'); */; | ||
function get_fs() { return fs || (fs = require('fs')); } | ||
function parse(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ { | ||
if(file[0] == 0x50 && file[1] == 0x4b) return parse_zip(file, options); | ||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512"); | ||
@@ -89,2 +259,4 @@ var mver = 3; | ||
case 3: ssz = 512; break; case 4: ssz = 4096; break; | ||
case 0: if(mv[1] == 0) return parse_zip(file, options); | ||
/* falls through */ | ||
default: throw new Error("Major Version: Expected 3 or 4 saw " + mver); | ||
@@ -168,2 +340,3 @@ } | ||
function check_get_mver(blob/*:CFBlob*/)/*:[number, number]*/ { | ||
if(blob[blob.l] == 0x50 && blob[blob.l + 1] == 0x4b) return [0, 0]; | ||
// header signature 8 | ||
@@ -486,2 +659,3 @@ blob.chk(HEADER_SIGNATURE, 'Header Signature: '); | ||
rebuild_cfb(cfb); | ||
if(_opts.fileType == 'zip') return write_zip(cfb, _opts); | ||
var L = (function(cfb/*:CFBContainer*/)/*:Array<number>*/{ | ||
@@ -687,2 +861,547 @@ var mini_size = 0, fat_size = 0; | ||
} | ||
/* node < 8.1 zlib does not expose bytesRead, so default to pure JS */ | ||
var _zlib; | ||
function use_zlib(zlib) { try { | ||
var InflateRaw = zlib.InflateRaw; | ||
var InflRaw = new InflateRaw(); | ||
InflRaw._processChunk(new Uint8Array([3, 0]), InflRaw._finishFlushFlag); | ||
if(InflRaw.bytesRead) _zlib = zlib; | ||
else throw new Error("zlib does not expose bytesRead"); | ||
} catch(e) {console.error("cannot use native zlib: " + (e.message || e)); } } | ||
function _inflateRawSync(payload, usz) { | ||
if(!_zlib) return _inflate(payload, usz); | ||
var InflateRaw = _zlib.InflateRaw; | ||
var InflRaw = new InflateRaw(); | ||
var out = InflRaw._processChunk(payload.slice(payload.l), InflRaw._finishFlushFlag); | ||
payload.l += InflRaw.bytesRead; | ||
return out; | ||
} | ||
function _deflateRawSync(payload) { | ||
return _zlib ? _zlib.deflateRawSync(payload) : _deflate(payload); | ||
} | ||
var CLEN_ORDER = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; | ||
/* LEN_ID = [ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285 ]; */ | ||
var LEN_LN = [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13 , 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 ]; | ||
/* DST_ID = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 ]; */ | ||
var DST_LN = [ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ]; | ||
function bit_swap_8(n) { var t = (((((n<<1)|(n<<11)) & 0x22110) | (((n<<5)|(n<<15)) & 0x88440))); return ((t>>16) | (t>>8) |t)&0xFF; } | ||
var use_typed_arrays = typeof Uint8Array !== 'undefined'; | ||
var bitswap8 = use_typed_arrays ? new Uint8Array(1<<8) : []; | ||
for(var q = 0; q < (1<<8); ++q) bitswap8[q] = bit_swap_8(q); | ||
function bit_swap_n(n, b) { | ||
var rev = bitswap8[n & 0xFF]; | ||
if(b <= 8) return rev >>> (8-b); | ||
rev = (rev << 8) | bitswap8[(n>>8)&0xFF]; | ||
if(b <= 16) return rev >>> (16-b); | ||
rev = (rev << 8) | bitswap8[(n>>16)&0xFF]; | ||
return rev >>> (24-b); | ||
} | ||
/* helpers for unaligned bit reads */ | ||
function read_bits_2(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 6 ? 0 : buf[h+1]<<8))>>>w)& 0x03; } | ||
function read_bits_3(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 5 ? 0 : buf[h+1]<<8))>>>w)& 0x07; } | ||
function read_bits_4(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 4 ? 0 : buf[h+1]<<8))>>>w)& 0x0F; } | ||
function read_bits_5(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 3 ? 0 : buf[h+1]<<8))>>>w)& 0x1F; } | ||
function read_bits_7(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 1 ? 0 : buf[h+1]<<8))>>>w)& 0x7F; } | ||
/* works up to n = 3 * 8 + 1 = 25 */ | ||
function read_bits_n(buf, bl, n) { | ||
var w = (bl&7), h = (bl>>>3), f = ((1<<n)-1); | ||
var v = buf[h] >>> w; | ||
if(n < 8 - w) return v & f; | ||
v |= buf[h+1]<<(8-w); | ||
if(n < 16 - w) return v & f; | ||
v |= buf[h+2]<<(16-w); | ||
if(n < 24 - w) return v & f; | ||
v |= buf[h+3]<<(24-w); | ||
return v & f; | ||
} | ||
/* until ArrayBuffer#realloc is a thing, fake a realloc */ | ||
function realloc(b, sz/*:number*/) { | ||
var L = b.length, M = 2*L > sz ? 2*L : sz + 5, i = 0; | ||
if(L >= sz) return b; | ||
if(has_buf) { | ||
var o = new_unsafe_buf(M); | ||
// $FlowIgnore | ||
if(b.copy) b.copy(o); | ||
else for(; i < b.length; ++i) o[i] = b[i]; | ||
return o; | ||
} else if(use_typed_arrays) { | ||
var a = new Uint8Array(M); | ||
if(a.set) a.set(b); | ||
else for(; i < b.length; ++i) a[i] = b[i]; | ||
return a; | ||
} | ||
b.length = M; | ||
return b; | ||
} | ||
/* zero-filled arrays for older browsers */ | ||
function zero_fill_array(n) { | ||
var o = new Array(n); | ||
for(var i = 0; i < n; ++i) o[i] = 0; | ||
return o; | ||
}var _deflate = (function() { | ||
var _deflateRaw = (function() { | ||
return function deflateRaw(data, out) { | ||
var boff = 0; | ||
while(boff < data.length) { | ||
var L = Math.min(0xFFFF, data.length - boff); | ||
var h = boff + L == data.length; | ||
/* TODO: this is only type 0 stored */ | ||
out.write_shift(1, +h); | ||
out.write_shift(2, L); | ||
out.write_shift(2, (~L) & 0xFFFF); | ||
while(L-- > 0) out[out.l++] = data[boff++]; | ||
} | ||
return out.l; | ||
}; | ||
})(); | ||
return function(data) { | ||
var buf = new_buf(50+Math.floor(data.length*1.1)); | ||
var off = _deflateRaw(data, buf); | ||
return buf.slice(0, off); | ||
}; | ||
})(); | ||
/* modified inflate function also moves original read head */ | ||
/* build tree (used for literals and lengths) */ | ||
function build_tree(clens, cmap, MAX/*:number*/)/*:number*/ { | ||
var maxlen = 1, w = 0, i = 0, j = 0, ccode = 0, L = clens.length; | ||
var bl_count = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32); | ||
for(i = 0; i < 32; ++i) bl_count[i] = 0; | ||
for(i = L; i < MAX; ++i) clens[i] = 0; | ||
L = clens.length; | ||
var ctree = use_typed_arrays ? new Uint16Array(L) : zero_fill_array(L); // [] | ||
/* build code tree */ | ||
for(i = 0; i < L; ++i) { | ||
bl_count[(w = clens[i])]++; | ||
if(maxlen < w) maxlen = w; | ||
ctree[i] = 0; | ||
} | ||
bl_count[0] = 0; | ||
for(i = 1; i <= maxlen; ++i) bl_count[i+16] = (ccode = (ccode + bl_count[i-1])<<1); | ||
for(i = 0; i < L; ++i) { | ||
ccode = clens[i]; | ||
if(ccode != 0) ctree[i] = bl_count[ccode+16]++; | ||
} | ||
/* cmap[maxlen + 4 bits] = (off&15) + (lit<<4) reverse mapping */ | ||
var cleni = 0; | ||
for(i = 0; i < L; ++i) { | ||
cleni = clens[i]; | ||
if(cleni != 0) { | ||
ccode = bit_swap_n(ctree[i], maxlen)>>(maxlen-cleni); | ||
for(j = (1<<(maxlen + 4 - cleni)) - 1; j>=0; --j) | ||
cmap[ccode|(j<<cleni)] = (cleni&15) | (i<<4); | ||
} | ||
} | ||
return maxlen; | ||
} | ||
var fix_lmap = use_typed_arrays ? new Uint16Array(512) : zero_fill_array(512); | ||
var fix_dmap = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32); | ||
if(!use_typed_arrays) { | ||
for(var i = 0; i < 512; ++i) fix_lmap[i] = 0; | ||
for(i = 0; i < 32; ++i) fix_dmap[i] = 0; | ||
} | ||
(function() { | ||
var dlens/*:Array<number>*/ = []; | ||
var i = 0; | ||
for(;i<32; i++) dlens.push(5); | ||
build_tree(dlens, fix_dmap, 32); | ||
var clens/*:Array<number>*/ = []; | ||
i = 0; | ||
for(; i<=143; i++) clens.push(8); | ||
for(; i<=255; i++) clens.push(9); | ||
for(; i<=279; i++) clens.push(7); | ||
for(; i<=287; i++) clens.push(8); | ||
build_tree(clens, fix_lmap, 288); | ||
})(); | ||
var dyn_lmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768); | ||
var dyn_dmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768); | ||
var dyn_cmap = use_typed_arrays ? new Uint16Array(128) : zero_fill_array(128); | ||
var dyn_len_1 = 1, dyn_len_2 = 1; | ||
/* 5.5.3 Expanding Huffman Codes */ | ||
function dyn(data, boff/*:number*/) { | ||
/* nomenclature from RFC1951 refers to bit values; these are offset by the implicit constant */ | ||
var _HLIT = read_bits_5(data, boff) + 257; boff += 5; | ||
var _HDIST = read_bits_5(data, boff) + 1; boff += 5; | ||
var _HCLEN = read_bits_4(data, boff) + 4; boff += 4; | ||
var w = 0; | ||
/* grab and store code lengths */ | ||
var clens = use_typed_arrays ? new Uint8Array(19) : zero_fill_array(19); | ||
var ctree = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; | ||
var maxlen = 1; | ||
var bl_count = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8); | ||
var next_code = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8); | ||
var L = clens.length; /* 19 */ | ||
for(var i = 0; i < _HCLEN; ++i) { | ||
clens[CLEN_ORDER[i]] = w = read_bits_3(data, boff); | ||
if(maxlen < w) maxlen = w; | ||
bl_count[w]++; | ||
boff += 3; | ||
} | ||
/* build code tree */ | ||
var ccode = 0; | ||
bl_count[0] = 0; | ||
for(i = 1; i <= maxlen; ++i) next_code[i] = ccode = (ccode + bl_count[i-1])<<1; | ||
for(i = 0; i < L; ++i) if((ccode = clens[i]) != 0) ctree[i] = next_code[ccode]++; | ||
/* cmap[7 bits from stream] = (off&7) + (lit<<3) */ | ||
var cleni = 0; | ||
for(i = 0; i < L; ++i) { | ||
cleni = clens[i]; | ||
if(cleni != 0) { | ||
ccode = bitswap8[ctree[i]]>>(8-cleni); | ||
for(var j = (1<<(7-cleni))-1; j>=0; --j) dyn_cmap[ccode|(j<<cleni)] = (cleni&7) | (i<<3); | ||
} | ||
} | ||
/* read literal and dist codes at once */ | ||
var hcodes/*:Array<number>*/ = []; | ||
maxlen = 1; | ||
for(; hcodes.length < _HLIT + _HDIST;) { | ||
ccode = dyn_cmap[read_bits_7(data, boff)]; | ||
boff += ccode & 7; | ||
switch((ccode >>>= 3)) { | ||
case 16: | ||
w = 3 + read_bits_2(data, boff); boff += 2; | ||
ccode = hcodes[hcodes.length - 1]; | ||
while(w-- > 0) hcodes.push(ccode); | ||
break; | ||
case 17: | ||
w = 3 + read_bits_3(data, boff); boff += 3; | ||
while(w-- > 0) hcodes.push(0); | ||
break; | ||
case 18: | ||
w = 11 + read_bits_7(data, boff); boff += 7; | ||
while(w -- > 0) hcodes.push(0); | ||
break; | ||
default: | ||
hcodes.push(ccode); | ||
if(maxlen < ccode) maxlen = ccode; | ||
break; | ||
} | ||
} | ||
/* build literal / length trees */ | ||
var h1 = hcodes.slice(0, _HLIT), h2 = hcodes.slice(_HLIT); | ||
for(i = _HLIT; i < 286; ++i) h1[i] = 0; | ||
for(i = _HDIST; i < 30; ++i) h2[i] = 0; | ||
dyn_len_1 = build_tree(h1, dyn_lmap, 286); | ||
dyn_len_2 = build_tree(h2, dyn_dmap, 30); | ||
return boff; | ||
} | ||
/* return [ data, bytesRead ] */ | ||
function inflate(data, usz/*:number*/) { | ||
/* shortcircuit for empty buffer [0x03, 0x00] */ | ||
if(data[0] == 3 && !(data[1] & 0x3)) { return [new_raw_buf(usz), 2]; } | ||
/* bit offset */ | ||
var boff = 0; | ||
/* header includes final bit and type bits */ | ||
var header = 0; | ||
var outbuf = new_unsafe_buf(usz ? usz : (1<<18)); | ||
var woff = 0; | ||
var OL = outbuf.length>>>0; | ||
var max_len_1 = 0, max_len_2 = 0; | ||
while((header&1) == 0) { | ||
header = read_bits_3(data, boff); boff += 3; | ||
if((header >>> 1) == 0) { | ||
/* Stored block */ | ||
if(boff & 7) boff += 8 - (boff&7); | ||
/* 2 bytes sz, 2 bytes bit inverse */ | ||
var sz = data[boff>>>3] | data[(boff>>>3)+1]<<8; | ||
boff += 32; | ||
/* push sz bytes */ | ||
if(!usz && OL < woff + sz) { outbuf = realloc(outbuf, woff + sz); OL = outbuf.length; } | ||
if(typeof data.copy === 'function') { | ||
// $FlowIgnore | ||
data.copy(outbuf, woff, boff>>>3, (boff>>>3)+sz); | ||
woff += sz; boff += 8*sz; | ||
} else while(sz-- > 0) { outbuf[woff++] = data[boff>>>3]; boff += 8; } | ||
continue; | ||
} else if((header >>> 1) == 1) { | ||
/* Fixed Huffman */ | ||
max_len_1 = 9; max_len_2 = 5; | ||
} else { | ||
/* Dynamic Huffman */ | ||
boff = dyn(data, boff); | ||
max_len_1 = dyn_len_1; max_len_2 = dyn_len_2; | ||
} | ||
if(!usz && (OL < woff + 32767)) { outbuf = realloc(outbuf, woff + 32767); OL = outbuf.length; } | ||
for(;;) { // while(true) is apparently out of vogue in modern JS circles | ||
/* ingest code and move read head */ | ||
var bits = read_bits_n(data, boff, max_len_1); | ||
var code = (header>>>1) == 1 ? fix_lmap[bits] : dyn_lmap[bits]; | ||
boff += code & 15; code >>>= 4; | ||
/* 0-255 are literals, 256 is end of block token, 257+ are copy tokens */ | ||
if(((code>>>8)&0xFF) === 0) outbuf[woff++] = code; | ||
else if(code == 256) break; | ||
else { | ||
code -= 257; | ||
var len_eb = (code < 8) ? 0 : ((code-4)>>2); if(len_eb > 5) len_eb = 0; | ||
var tgt = woff + LEN_LN[code]; | ||
/* length extra bits */ | ||
if(len_eb > 0) { | ||
tgt += read_bits_n(data, boff, len_eb); | ||
boff += len_eb; | ||
} | ||
/* dist code */ | ||
bits = read_bits_n(data, boff, max_len_2); | ||
code = (header>>>1) == 1 ? fix_dmap[bits] : dyn_dmap[bits]; | ||
boff += code & 15; code >>>= 4; | ||
var dst_eb = (code < 4 ? 0 : (code-2)>>1); | ||
var dst = DST_LN[code]; | ||
/* dist extra bits */ | ||
if(dst_eb > 0) { | ||
dst += read_bits_n(data, boff, dst_eb); | ||
boff += dst_eb; | ||
} | ||
/* in the common case, manual byte copy is faster than TA set / Buffer copy */ | ||
if(!usz && OL < tgt) { outbuf = realloc(outbuf, tgt); OL = outbuf.length; } | ||
while(woff < tgt) { outbuf[woff] = outbuf[woff - dst]; ++woff; } | ||
} | ||
} | ||
} | ||
return [usz ? outbuf : outbuf.slice(0, woff), (boff+7)>>>3]; | ||
} | ||
function _inflate(payload, usz) { | ||
var data = payload.slice(payload.l||0); | ||
var out = inflate(data, usz); | ||
payload.l += out[1]; | ||
return out[0]; | ||
} | ||
function warn_or_throw(wrn, msg) { | ||
if(wrn) { if(typeof console !== 'undefined') console.error(msg); } | ||
else throw new Error(msg); | ||
} | ||
function parse_zip(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ { | ||
var blob/*:CFBlob*/ = /*::(*/file/*:: :any)*/; | ||
prep_blob(blob, 0); | ||
var FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array<string>*/ = []; | ||
var o = { | ||
FileIndex: FileIndex, | ||
FullPaths: FullPaths | ||
}; | ||
init_cfb(o, { root: options.root }); | ||
/* find end of central directory, start just after signature */ | ||
var i = blob.length - 4; | ||
while((blob[i] != 0x50 || blob[i+1] != 0x4b || blob[i+2] != 0x05 || blob[i+3] != 0x06) && i >= 0) --i; | ||
blob.l = i + 4; | ||
/* parse end of central directory */ | ||
blob.l += 4; | ||
var fcnt = blob.read_shift(2); | ||
blob.l += 6; | ||
var start_cd = blob.read_shift(4); | ||
/* parse central directory */ | ||
blob.l = start_cd; | ||
for(i = 0; i < fcnt; ++i) { | ||
/* trust local file header instead of CD entry */ | ||
blob.l += 20; | ||
var csz = blob.read_shift(4); | ||
var usz = blob.read_shift(4); | ||
var namelen = blob.read_shift(2); | ||
var efsz = blob.read_shift(2); | ||
var fcsz = blob.read_shift(2); | ||
blob.l += 8; | ||
var offset = blob.read_shift(4); | ||
var EF = parse_extra_field(/*::(*/blob.slice(blob.l+namelen, blob.l+namelen+efsz)/*:: :any)*/); | ||
blob.l += namelen + efsz + fcsz; | ||
var L = blob.l; | ||
blob.l = offset + 4; | ||
parse_local_file(blob, csz, usz, o, EF); | ||
blob.l = L; | ||
} | ||
return o; | ||
} | ||
/* head starts just after local file header signature */ | ||
function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:CFBContainer*/, EF) { | ||
/* [local file header] */ | ||
blob.l += 2; | ||
var flags = blob.read_shift(2); | ||
var meth = blob.read_shift(2); | ||
var date = parse_dos_date(blob); | ||
if(flags & 0x2041) throw new Error("Unsupported ZIP encryption"); | ||
var crc32 = blob.read_shift(4); | ||
var _csz = blob.read_shift(4); | ||
var _usz = blob.read_shift(4); | ||
var namelen = blob.read_shift(2); | ||
var efsz = blob.read_shift(2); | ||
// TODO: flags & (1<<11) // UTF8 | ||
var name = ""; for(var i = 0; i < namelen; ++i) name += String.fromCharCode(blob[blob.l++]); | ||
if(efsz) { | ||
var ef = parse_extra_field(/*::(*/blob.slice(blob.l, blob.l + efsz)/*:: :any)*/); | ||
if((ef[0x5455]||{}).mt) date = ef[0x5455].mt; | ||
if(((EF||{})[0x5455]||{}).mt) date = EF[0x5455].mt; | ||
} | ||
blob.l += efsz; | ||
/* [encryption header] */ | ||
/* [file data] */ | ||
var data = blob.slice(blob.l, blob.l + _csz); | ||
switch(meth) { | ||
case 8: data = _inflateRawSync(blob, _usz); break; | ||
case 0: break; | ||
default: throw new Error("Unsupported ZIP Compression method " + meth); | ||
} | ||
/* [data descriptor] */ | ||
var wrn = false; | ||
if(flags & 8) { | ||
crc32 = blob.read_shift(4); | ||
if(crc32 == 0x08074b50) { crc32 = blob.read_shift(4); wrn = true; } | ||
_csz = blob.read_shift(4); | ||
_usz = blob.read_shift(4); | ||
} | ||
if(_csz != csz) warn_or_throw(wrn, "Bad compressed size: " + csz + " != " + _csz); | ||
if(_usz != usz) warn_or_throw(wrn, "Bad uncompressed size: " + usz + " != " + _usz); | ||
var _crc32 = CRC32.buf(data, 0); | ||
if(crc32 != _crc32) warn_or_throw(wrn, "Bad CRC32 checksum: " + crc32 + " != " + _crc32); | ||
cfb_add(o, name, data, {unsafe: true, mt: date}); | ||
} | ||
function write_zip(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/ { | ||
var _opts = options || {}; | ||
var out = [], cdirs = []; | ||
var o/*:CFBlob*/ = new_buf(1); | ||
var method = (_opts.compression ? 8 : 0), flags = 0; | ||
var desc = false; | ||
if(desc) flags |= 8; | ||
var i = 0, j = 0; | ||
var start_cd = 0, fcnt = 0; | ||
var root = cfb.FullPaths[0], fp = root, fi = cfb.FileIndex[0]; | ||
var crcs = []; | ||
var sz_cd = 0; | ||
for(i = 1; i < cfb.FullPaths.length; ++i) { | ||
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i]; | ||
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue; | ||
var start = start_cd; | ||
/* TODO: CP437 filename */ | ||
var namebuf = new_buf(fp.length); | ||
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F); | ||
namebuf = namebuf.slice(0, namebuf.l); | ||
crcs[fcnt] = CRC32.buf(/*::((*/fi.content/*::||[]):any)*/, 0); | ||
var outbuf = fi.content/*::||[]*/; | ||
if(method == 8) outbuf = _deflateRawSync(outbuf); | ||
/* local file header */ | ||
o = new_buf(30); | ||
o.write_shift(4, 0x04034b50); | ||
o.write_shift(2, 20); | ||
o.write_shift(2, flags); | ||
o.write_shift(2, method); | ||
/* TODO: last mod file time/date */ | ||
if(fi.mt) write_dos_date(o, fi.mt); | ||
else o.write_shift(4, 0); | ||
o.write_shift(-4, (flags & 8) ? 0 : crcs[fcnt]); | ||
o.write_shift(4, (flags & 8) ? 0 : outbuf.length); | ||
o.write_shift(4, (flags & 8) ? 0 : /*::(*/fi.content/*::||[])*/.length); | ||
o.write_shift(2, namebuf.length); | ||
o.write_shift(2, 0); | ||
start_cd += o.length; | ||
out.push(o); | ||
start_cd += namebuf.length; | ||
out.push(namebuf); | ||
/* TODO: encryption header ? */ | ||
start_cd += outbuf.length; | ||
out.push(outbuf); | ||
/* data descriptor */ | ||
if(flags & 8) { | ||
o = new_buf(12); | ||
o.write_shift(-4, crcs[fcnt]); | ||
o.write_shift(4, outbuf.length); | ||
o.write_shift(4, /*::(*/fi.content/*::||[])*/.length); | ||
start_cd += o.l; | ||
out.push(o); | ||
} | ||
/* central directory */ | ||
o = new_buf(46); | ||
o.write_shift(4, 0x02014b50); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 20); | ||
o.write_shift(2, flags); | ||
o.write_shift(2, method); | ||
o.write_shift(4, 0); /* TODO: last mod file time/date */ | ||
o.write_shift(-4, crcs[fcnt]); | ||
o.write_shift(4, outbuf.length); | ||
o.write_shift(4, /*::(*/fi.content/*::||[])*/.length); | ||
o.write_shift(2, namebuf.length); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(4, 0); | ||
o.write_shift(4, start); | ||
sz_cd += o.l; | ||
cdirs.push(o); | ||
sz_cd += namebuf.length; | ||
cdirs.push(namebuf); | ||
++fcnt; | ||
} | ||
/* end of central directory */ | ||
o = new_buf(22); | ||
o.write_shift(4, 0x06054b50); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, fcnt); | ||
o.write_shift(2, fcnt); | ||
o.write_shift(4, sz_cd); | ||
o.write_shift(4, start_cd); | ||
o.write_shift(2, 0); | ||
return bconcat(([bconcat((out/*:any*/)), bconcat(cdirs), o]/*:any*/)); | ||
} | ||
function cfb_new(opts/*:?any*/)/*:CFBContainer*/ { | ||
@@ -715,2 +1434,4 @@ var o/*:CFBContainer*/ = ({}/*:any*/); | ||
if(opts.CLSID) file.clsid = opts.CLSID; | ||
if(opts.mt) file.mt = opts.mt; | ||
if(opts.ct) file.ct = opts.ct; | ||
} | ||
@@ -759,2 +1480,5 @@ return file; | ||
bconcat: bconcat, | ||
use_zlib: use_zlib, | ||
_deflateRaw: _deflate, | ||
_inflateRaw: _inflate, | ||
consts: consts | ||
@@ -761,0 +1485,0 @@ }; |
{ | ||
"name": "cfb", | ||
"version": "1.0.8", | ||
"version": "1.1.0", | ||
"author": "sheetjs", | ||
@@ -22,13 +22,14 @@ "description": "Compound File Binary File Format extractor", | ||
"dependencies": { | ||
"commander": "^2.14.1", | ||
"adler-32": "~1.2.0", | ||
"commander": "^2.16.0", | ||
"crc-32": "~1.2.0", | ||
"printj": "~1.1.2" | ||
}, | ||
"devDependencies": { | ||
"crc-32": "~1.2.0", | ||
"mocha": "~2.5.3", | ||
"blanket": "~1.2.3", | ||
"@sheetjs/uglify-js": "~2.7.3", | ||
"@types/node": "^8.5.9", | ||
"@types/commander": "^2.9.0", | ||
"@types/node": "^8.10.25", | ||
"blanket": "~1.2.3", | ||
"dtslint": "~0.1.2", | ||
"mocha": "~2.5.3", | ||
"typescript": "2.2.0" | ||
@@ -35,0 +36,0 @@ }, |
@@ -1,5 +0,4 @@ | ||
# Compound File Binary Format | ||
# Container File Blobs | ||
Pure JS implementation of MS-CFB: Compound File Binary File Format, a container | ||
format used in many Microsoft file types (XLS, DOC, VBA blobs in XLSX and XLSB) | ||
Pure JS implementation of various container file formats, including ZIP and CFB. | ||
@@ -10,3 +9,2 @@ [![Build Status](https://travis-ci.org/SheetJS/js-cfb.svg?branch=master)](https://travis-ci.org/SheetJS/js-cfb) | ||
[![NPM Downloads](https://img.shields.io/npm/dt/cfb.svg)](https://npmjs.org/package/cfb) | ||
[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx) | ||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-cfb?pixel)](https://github.com/SheetJS/js-cfb) | ||
@@ -83,6 +81,17 @@ | ||
`CFB.read(blob, opts)` wraps `parse`. `opts.type` controls the behavior: | ||
`CFB.read(blob, opts)` wraps `parse`. | ||
`CFB.find(cfb, path)` performs a case-insensitive match for the path (or file | ||
name, if there are no slashes) and returns an entry object or null if not found. | ||
`CFB.write(cfb, opts)` generates a file based on the container. | ||
`CFB.writeFile(cfb, filename, opts)` creates a file with the specified name. | ||
### Parse Options | ||
`CFB.read` takes an options argument. `opts.type` controls the behavior: | ||
| `type` | expected input | | ||
|------------|-----------------------------------------------------------------| | ||
|------------|:----------------------------------------------------------------| | ||
| `"base64"` | string: Base64 encoding of the file | | ||
@@ -93,10 +102,11 @@ | `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) | | ||
`CFB.find(cfb, path)` performs a case-insensitive match for the path (or file | ||
name, if there are no slashes) and returns an entry object or null if not found. | ||
`CFB.write(cfb, opts)` generates a file based on the container. `opts.type` | ||
controls the behavior: | ||
### Write Options | ||
`CFB.write` and `CFB.writeFile` take options argument. | ||
`opts.type` controls the behavior: | ||
| `type` | output | | ||
|------------|-----------------------------------------------------------------| | ||
|------------|:----------------------------------------------------------------| | ||
| `"base64"` | string: Base64 encoding of the file | | ||
@@ -107,5 +117,12 @@ | `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) | | ||
`CFB.writeFile(cfb, filename, opts)` creates a file with the specified name. | ||
`opts.fileType` controls the output file type: | ||
| `fileType` | output | | ||
|:-------------------|:--------------| | ||
| `'cfb'` (default) | CFB container | | ||
| `'zip'` | ZIP file | | ||
`opts.compression` enables DEFLATE compression for ZIP file type. | ||
## Utility Functions | ||
@@ -121,4 +138,10 @@ | ||
- `.cfb_mov(cfb, old_name, new_name)` moves the old file to new path and name | ||
- `.use_zlib(require("zlib"))` loads a nodejs zlib instance. | ||
By default, the library uses a pure JS inflate/deflate implementation. NodeJS | ||
`zlib.InflateRaw` exposes the number of bytes read in versions after `8.11.0`. | ||
If a supplied `zlib` does not support the required features, a warning will be | ||
displayed in the console and the pure JS fallback will be used. | ||
## Container Object Description | ||
@@ -154,9 +177,5 @@ | ||
<details> | ||
<summary><b>OSP-covered Specifications</b> (click to show)</summary> | ||
- [MS-CFB]: Compound File Binary File Format | ||
- ZIP `APPNOTE.TXT`: https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.4.TXT | ||
- RFC1951: https://www.ietf.org/rfc/rfc1951.txt | ||
</details> | ||
@@ -17,6 +17,6 @@ /* index.d.ts (C) 2013-present SheetJS */ | ||
/** Generate a container file */ | ||
export function write(cfb: CFB$Container, options?: any): any; | ||
export function write(cfb: CFB$Container, options?: CFB$WritingOptions): any; | ||
/** Write a container file to the filesystem */ | ||
export function writeFile(cfb: CFB$Container, filename: string, options?: any): any; | ||
export function writeFile(cfb: CFB$Container, filename: string, options?: CFB$WritingOptions): any; | ||
@@ -26,5 +26,3 @@ /** Utility functions */ | ||
/** Options for read and readFile */ | ||
export interface CFB$ParsingOptions { | ||
export interface CFB$CommonOptions { | ||
/** Input data encoding */ | ||
@@ -35,3 +33,6 @@ type?: 'base64' | 'binary' | 'buffer' | 'file' | 'array'; | ||
WTF?: boolean; | ||
} | ||
/** Options for read and readFile */ | ||
export interface CFB$ParsingOptions extends CFB$CommonOptions { | ||
/** If true, include raw data in output */ | ||
@@ -41,2 +42,14 @@ raw?: boolean; | ||
/** Options for write and writeFile */ | ||
export interface CFB$WritingOptions extends CFB$CommonOptions { | ||
/** Output file type */ | ||
fileType?: 'cfb' | 'zip'; | ||
/** Override default root entry name (CFB only) */ | ||
root?: string; | ||
/** Enable compression (ZIP only) */ | ||
compression?: boolean; | ||
} | ||
export type CFB$Blob = number[] | Uint8Array; | ||
@@ -43,0 +56,0 @@ |
@@ -15,3 +15,6 @@ var DO_NOT_EXPORT_CFB = true; | ||
declare var chr1:any; | ||
declare var has_buf:boolean; | ||
declare var new_buf:any; | ||
declare var new_raw_buf:any; | ||
declare var new_unsafe_buf:any; | ||
*/ | ||
@@ -22,3 +25,3 @@ /* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||
/*exported CFB */ | ||
/*global module, require:false, process:false, Buffer:false, Uint8Array:false */ | ||
/*global module, require:false, process:false, Buffer:false, Uint8Array:false, Uint16Array:false */ | ||
@@ -40,6 +43,107 @@ /*:: | ||
*/ | ||
/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ | ||
/* vim: set ts=2: */ | ||
/*exported CRC32 */ | ||
var CRC32; | ||
(function (factory) { | ||
/*jshint ignore:start */ | ||
/*eslint-disable */ | ||
factory(CRC32 = {}); | ||
/*eslint-enable */ | ||
/*jshint ignore:end */ | ||
}(function(CRC32) { | ||
CRC32.version = '1.2.0'; | ||
/* see perf/crc32table.js */ | ||
/*global Int32Array */ | ||
function signed_crc_table()/*:any*/ { | ||
var c = 0, table/*:Array<number>*/ = new Array(256); | ||
for(var n =0; n != 256; ++n){ | ||
c = n; | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); | ||
table[n] = c; | ||
} | ||
return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; | ||
} | ||
var T = signed_crc_table(); | ||
function crc32_bstr(bstr/*:string*/, seed/*:number*/)/*:number*/ { | ||
var C = seed ^ -1, L = bstr.length - 1; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; | ||
C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; | ||
} | ||
if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_buf(buf/*:Uint8Array|Array<number>*/, seed/*:number*/)/*:number*/ { | ||
if(buf.length > 10000) return crc32_buf_8(buf, seed); | ||
var C = seed ^ -1, L = buf.length - 3; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
} | ||
while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_buf_8(buf/*:Uint8Array|Array<number>*/, seed/*:number*/)/*:number*/ { | ||
var C = seed ^ -1, L = buf.length - 7; | ||
for(var i = 0; i < L;) { | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
} | ||
while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; | ||
return C ^ -1; | ||
} | ||
function crc32_str(str/*:string*/, seed/*:number*/)/*:number*/ { | ||
var C = seed ^ -1; | ||
for(var i = 0, L=str.length, c, d; i < L;) { | ||
c = str.charCodeAt(i++); | ||
if(c < 0x80) { | ||
C = (C>>>8) ^ T[(C ^ c)&0xFF]; | ||
} else if(c < 0x800) { | ||
C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; | ||
} else if(c >= 0xD800 && c < 0xE000) { | ||
c = (c&1023)+64; d = str.charCodeAt(i++)&1023; | ||
C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; | ||
} else { | ||
C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; | ||
C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; | ||
} | ||
} | ||
return C ^ -1; | ||
} | ||
CRC32.table = T; | ||
CRC32.bstr = crc32_bstr; | ||
CRC32.buf = crc32_buf; | ||
CRC32.str = crc32_str; | ||
})); | ||
/* [MS-CFB] v20171201 */ | ||
var CFB = (function _CFB(){ | ||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/; | ||
exports.version = '1.0.8'; | ||
exports.version = '1.1.0'; | ||
/* [MS-CFB] 2.6.4 */ | ||
@@ -65,5 +169,71 @@ function namecmp(l/*:string*/, r/*:string*/)/*:number*/ { | ||
} | ||
/* -------------------------------------------------------------------------- */ | ||
/* DOS Date format: | ||
high|YYYYYYYm.mmmddddd.HHHHHMMM.MMMSSSSS|low | ||
add 1980 to stored year | ||
stored second should be doubled | ||
*/ | ||
/* write JS date to buf as a DOS date */ | ||
function write_dos_date(buf/*:CFBlob*/, date/*:Date|string*/) { | ||
if(typeof date === "string") date = new Date(date); | ||
var hms/*:number*/ = date.getHours(); | ||
hms = hms << 6 | date.getMinutes(); | ||
hms = hms << 5 | (date.getSeconds()>>>1); | ||
buf.write_shift(2, hms); | ||
var ymd/*:number*/ = (date.getFullYear() - 1980); | ||
ymd = ymd << 4 | (date.getMonth()+1); | ||
ymd = ymd << 5 | date.getDate(); | ||
buf.write_shift(2, ymd); | ||
} | ||
/* read four bytes from buf and interpret as a DOS date */ | ||
function parse_dos_date(buf/*:CFBlob*/)/*:Date*/ { | ||
var hms = buf.read_shift(2) & 0xFFFF; | ||
var ymd = buf.read_shift(2) & 0xFFFF; | ||
var val = new Date(); | ||
var d = ymd & 0x1F; ymd >>>= 5; | ||
var m = ymd & 0x0F; ymd >>>= 4; | ||
val.setMilliseconds(0); | ||
val.setFullYear(ymd + 1980); | ||
val.setMonth(m-1); | ||
val.setDate(d); | ||
var S = hms & 0x1F; hms >>>= 5; | ||
var M = hms & 0x3F; hms >>>= 6; | ||
val.setHours(hms); | ||
val.setMinutes(M); | ||
val.setSeconds(S<<1); | ||
return val; | ||
} | ||
function parse_extra_field(blob/*:CFBlob*/)/*:any*/ { | ||
prep_blob(blob, 0); | ||
var o = /*::(*/{}/*:: :any)*/; | ||
var flags = 0; | ||
while(blob.l <= blob.length - 4) { | ||
var type = blob.read_shift(2); | ||
var sz = blob.read_shift(2), tgt = blob.l + sz; | ||
var p = {}; | ||
switch(type) { | ||
/* UNIX-style Timestamps */ | ||
case 0x5455: { | ||
flags = blob.read_shift(1); | ||
if(flags & 1) p.mtime = blob.read_shift(4); | ||
/* for some reason, CD flag corresponds to LFH */ | ||
if(sz > 5) { | ||
if(flags & 2) p.atime = blob.read_shift(4); | ||
if(flags & 4) p.ctime = blob.read_shift(4); | ||
} | ||
if(p.mtime) p.mt = new Date(p.mtime*1000); | ||
} | ||
break; | ||
} | ||
blob.l = tgt; | ||
o[type] = p; | ||
} | ||
return o; | ||
} | ||
var fs/*:: = require('fs'); */; | ||
function get_fs() { return fs || (fs = require('fs')); } | ||
function parse(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ { | ||
if(file[0] == 0x50 && file[1] == 0x4b) return parse_zip(file, options); | ||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512"); | ||
@@ -89,2 +259,4 @@ var mver = 3; | ||
case 3: ssz = 512; break; case 4: ssz = 4096; break; | ||
case 0: if(mv[1] == 0) return parse_zip(file, options); | ||
/* falls through */ | ||
default: throw new Error("Major Version: Expected 3 or 4 saw " + mver); | ||
@@ -168,2 +340,3 @@ } | ||
function check_get_mver(blob/*:CFBlob*/)/*:[number, number]*/ { | ||
if(blob[blob.l] == 0x50 && blob[blob.l + 1] == 0x4b) return [0, 0]; | ||
// header signature 8 | ||
@@ -486,2 +659,3 @@ blob.chk(HEADER_SIGNATURE, 'Header Signature: '); | ||
rebuild_cfb(cfb); | ||
if(_opts.fileType == 'zip') return write_zip(cfb, _opts); | ||
var L = (function(cfb/*:CFBContainer*/)/*:Array<number>*/{ | ||
@@ -687,2 +861,547 @@ var mini_size = 0, fat_size = 0; | ||
} | ||
/* node < 8.1 zlib does not expose bytesRead, so default to pure JS */ | ||
var _zlib; | ||
function use_zlib(zlib) { try { | ||
var InflateRaw = zlib.InflateRaw; | ||
var InflRaw = new InflateRaw(); | ||
InflRaw._processChunk(new Uint8Array([3, 0]), InflRaw._finishFlushFlag); | ||
if(InflRaw.bytesRead) _zlib = zlib; | ||
else throw new Error("zlib does not expose bytesRead"); | ||
} catch(e) {console.error("cannot use native zlib: " + (e.message || e)); } } | ||
function _inflateRawSync(payload, usz) { | ||
if(!_zlib) return _inflate(payload, usz); | ||
var InflateRaw = _zlib.InflateRaw; | ||
var InflRaw = new InflateRaw(); | ||
var out = InflRaw._processChunk(payload.slice(payload.l), InflRaw._finishFlushFlag); | ||
payload.l += InflRaw.bytesRead; | ||
return out; | ||
} | ||
function _deflateRawSync(payload) { | ||
return _zlib ? _zlib.deflateRawSync(payload) : _deflate(payload); | ||
} | ||
var CLEN_ORDER = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; | ||
/* LEN_ID = [ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285 ]; */ | ||
var LEN_LN = [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13 , 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 ]; | ||
/* DST_ID = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 ]; */ | ||
var DST_LN = [ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ]; | ||
function bit_swap_8(n) { var t = (((((n<<1)|(n<<11)) & 0x22110) | (((n<<5)|(n<<15)) & 0x88440))); return ((t>>16) | (t>>8) |t)&0xFF; } | ||
var use_typed_arrays = typeof Uint8Array !== 'undefined'; | ||
var bitswap8 = use_typed_arrays ? new Uint8Array(1<<8) : []; | ||
for(var q = 0; q < (1<<8); ++q) bitswap8[q] = bit_swap_8(q); | ||
function bit_swap_n(n, b) { | ||
var rev = bitswap8[n & 0xFF]; | ||
if(b <= 8) return rev >>> (8-b); | ||
rev = (rev << 8) | bitswap8[(n>>8)&0xFF]; | ||
if(b <= 16) return rev >>> (16-b); | ||
rev = (rev << 8) | bitswap8[(n>>16)&0xFF]; | ||
return rev >>> (24-b); | ||
} | ||
/* helpers for unaligned bit reads */ | ||
function read_bits_2(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 6 ? 0 : buf[h+1]<<8))>>>w)& 0x03; } | ||
function read_bits_3(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 5 ? 0 : buf[h+1]<<8))>>>w)& 0x07; } | ||
function read_bits_4(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 4 ? 0 : buf[h+1]<<8))>>>w)& 0x0F; } | ||
function read_bits_5(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 3 ? 0 : buf[h+1]<<8))>>>w)& 0x1F; } | ||
function read_bits_7(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 1 ? 0 : buf[h+1]<<8))>>>w)& 0x7F; } | ||
/* works up to n = 3 * 8 + 1 = 25 */ | ||
function read_bits_n(buf, bl, n) { | ||
var w = (bl&7), h = (bl>>>3), f = ((1<<n)-1); | ||
var v = buf[h] >>> w; | ||
if(n < 8 - w) return v & f; | ||
v |= buf[h+1]<<(8-w); | ||
if(n < 16 - w) return v & f; | ||
v |= buf[h+2]<<(16-w); | ||
if(n < 24 - w) return v & f; | ||
v |= buf[h+3]<<(24-w); | ||
return v & f; | ||
} | ||
/* until ArrayBuffer#realloc is a thing, fake a realloc */ | ||
function realloc(b, sz/*:number*/) { | ||
var L = b.length, M = 2*L > sz ? 2*L : sz + 5, i = 0; | ||
if(L >= sz) return b; | ||
if(has_buf) { | ||
var o = new_unsafe_buf(M); | ||
// $FlowIgnore | ||
if(b.copy) b.copy(o); | ||
else for(; i < b.length; ++i) o[i] = b[i]; | ||
return o; | ||
} else if(use_typed_arrays) { | ||
var a = new Uint8Array(M); | ||
if(a.set) a.set(b); | ||
else for(; i < b.length; ++i) a[i] = b[i]; | ||
return a; | ||
} | ||
b.length = M; | ||
return b; | ||
} | ||
/* zero-filled arrays for older browsers */ | ||
function zero_fill_array(n) { | ||
var o = new Array(n); | ||
for(var i = 0; i < n; ++i) o[i] = 0; | ||
return o; | ||
}var _deflate = (function() { | ||
var _deflateRaw = (function() { | ||
return function deflateRaw(data, out) { | ||
var boff = 0; | ||
while(boff < data.length) { | ||
var L = Math.min(0xFFFF, data.length - boff); | ||
var h = boff + L == data.length; | ||
/* TODO: this is only type 0 stored */ | ||
out.write_shift(1, +h); | ||
out.write_shift(2, L); | ||
out.write_shift(2, (~L) & 0xFFFF); | ||
while(L-- > 0) out[out.l++] = data[boff++]; | ||
} | ||
return out.l; | ||
}; | ||
})(); | ||
return function(data) { | ||
var buf = new_buf(50+Math.floor(data.length*1.1)); | ||
var off = _deflateRaw(data, buf); | ||
return buf.slice(0, off); | ||
}; | ||
})(); | ||
/* modified inflate function also moves original read head */ | ||
/* build tree (used for literals and lengths) */ | ||
function build_tree(clens, cmap, MAX/*:number*/)/*:number*/ { | ||
var maxlen = 1, w = 0, i = 0, j = 0, ccode = 0, L = clens.length; | ||
var bl_count = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32); | ||
for(i = 0; i < 32; ++i) bl_count[i] = 0; | ||
for(i = L; i < MAX; ++i) clens[i] = 0; | ||
L = clens.length; | ||
var ctree = use_typed_arrays ? new Uint16Array(L) : zero_fill_array(L); // [] | ||
/* build code tree */ | ||
for(i = 0; i < L; ++i) { | ||
bl_count[(w = clens[i])]++; | ||
if(maxlen < w) maxlen = w; | ||
ctree[i] = 0; | ||
} | ||
bl_count[0] = 0; | ||
for(i = 1; i <= maxlen; ++i) bl_count[i+16] = (ccode = (ccode + bl_count[i-1])<<1); | ||
for(i = 0; i < L; ++i) { | ||
ccode = clens[i]; | ||
if(ccode != 0) ctree[i] = bl_count[ccode+16]++; | ||
} | ||
/* cmap[maxlen + 4 bits] = (off&15) + (lit<<4) reverse mapping */ | ||
var cleni = 0; | ||
for(i = 0; i < L; ++i) { | ||
cleni = clens[i]; | ||
if(cleni != 0) { | ||
ccode = bit_swap_n(ctree[i], maxlen)>>(maxlen-cleni); | ||
for(j = (1<<(maxlen + 4 - cleni)) - 1; j>=0; --j) | ||
cmap[ccode|(j<<cleni)] = (cleni&15) | (i<<4); | ||
} | ||
} | ||
return maxlen; | ||
} | ||
var fix_lmap = use_typed_arrays ? new Uint16Array(512) : zero_fill_array(512); | ||
var fix_dmap = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32); | ||
if(!use_typed_arrays) { | ||
for(var i = 0; i < 512; ++i) fix_lmap[i] = 0; | ||
for(i = 0; i < 32; ++i) fix_dmap[i] = 0; | ||
} | ||
(function() { | ||
var dlens/*:Array<number>*/ = []; | ||
var i = 0; | ||
for(;i<32; i++) dlens.push(5); | ||
build_tree(dlens, fix_dmap, 32); | ||
var clens/*:Array<number>*/ = []; | ||
i = 0; | ||
for(; i<=143; i++) clens.push(8); | ||
for(; i<=255; i++) clens.push(9); | ||
for(; i<=279; i++) clens.push(7); | ||
for(; i<=287; i++) clens.push(8); | ||
build_tree(clens, fix_lmap, 288); | ||
})(); | ||
var dyn_lmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768); | ||
var dyn_dmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768); | ||
var dyn_cmap = use_typed_arrays ? new Uint16Array(128) : zero_fill_array(128); | ||
var dyn_len_1 = 1, dyn_len_2 = 1; | ||
/* 5.5.3 Expanding Huffman Codes */ | ||
function dyn(data, boff/*:number*/) { | ||
/* nomenclature from RFC1951 refers to bit values; these are offset by the implicit constant */ | ||
var _HLIT = read_bits_5(data, boff) + 257; boff += 5; | ||
var _HDIST = read_bits_5(data, boff) + 1; boff += 5; | ||
var _HCLEN = read_bits_4(data, boff) + 4; boff += 4; | ||
var w = 0; | ||
/* grab and store code lengths */ | ||
var clens = use_typed_arrays ? new Uint8Array(19) : zero_fill_array(19); | ||
var ctree = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; | ||
var maxlen = 1; | ||
var bl_count = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8); | ||
var next_code = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8); | ||
var L = clens.length; /* 19 */ | ||
for(var i = 0; i < _HCLEN; ++i) { | ||
clens[CLEN_ORDER[i]] = w = read_bits_3(data, boff); | ||
if(maxlen < w) maxlen = w; | ||
bl_count[w]++; | ||
boff += 3; | ||
} | ||
/* build code tree */ | ||
var ccode = 0; | ||
bl_count[0] = 0; | ||
for(i = 1; i <= maxlen; ++i) next_code[i] = ccode = (ccode + bl_count[i-1])<<1; | ||
for(i = 0; i < L; ++i) if((ccode = clens[i]) != 0) ctree[i] = next_code[ccode]++; | ||
/* cmap[7 bits from stream] = (off&7) + (lit<<3) */ | ||
var cleni = 0; | ||
for(i = 0; i < L; ++i) { | ||
cleni = clens[i]; | ||
if(cleni != 0) { | ||
ccode = bitswap8[ctree[i]]>>(8-cleni); | ||
for(var j = (1<<(7-cleni))-1; j>=0; --j) dyn_cmap[ccode|(j<<cleni)] = (cleni&7) | (i<<3); | ||
} | ||
} | ||
/* read literal and dist codes at once */ | ||
var hcodes/*:Array<number>*/ = []; | ||
maxlen = 1; | ||
for(; hcodes.length < _HLIT + _HDIST;) { | ||
ccode = dyn_cmap[read_bits_7(data, boff)]; | ||
boff += ccode & 7; | ||
switch((ccode >>>= 3)) { | ||
case 16: | ||
w = 3 + read_bits_2(data, boff); boff += 2; | ||
ccode = hcodes[hcodes.length - 1]; | ||
while(w-- > 0) hcodes.push(ccode); | ||
break; | ||
case 17: | ||
w = 3 + read_bits_3(data, boff); boff += 3; | ||
while(w-- > 0) hcodes.push(0); | ||
break; | ||
case 18: | ||
w = 11 + read_bits_7(data, boff); boff += 7; | ||
while(w -- > 0) hcodes.push(0); | ||
break; | ||
default: | ||
hcodes.push(ccode); | ||
if(maxlen < ccode) maxlen = ccode; | ||
break; | ||
} | ||
} | ||
/* build literal / length trees */ | ||
var h1 = hcodes.slice(0, _HLIT), h2 = hcodes.slice(_HLIT); | ||
for(i = _HLIT; i < 286; ++i) h1[i] = 0; | ||
for(i = _HDIST; i < 30; ++i) h2[i] = 0; | ||
dyn_len_1 = build_tree(h1, dyn_lmap, 286); | ||
dyn_len_2 = build_tree(h2, dyn_dmap, 30); | ||
return boff; | ||
} | ||
/* return [ data, bytesRead ] */ | ||
function inflate(data, usz/*:number*/) { | ||
/* shortcircuit for empty buffer [0x03, 0x00] */ | ||
if(data[0] == 3 && !(data[1] & 0x3)) { return [new_raw_buf(usz), 2]; } | ||
/* bit offset */ | ||
var boff = 0; | ||
/* header includes final bit and type bits */ | ||
var header = 0; | ||
var outbuf = new_unsafe_buf(usz ? usz : (1<<18)); | ||
var woff = 0; | ||
var OL = outbuf.length>>>0; | ||
var max_len_1 = 0, max_len_2 = 0; | ||
while((header&1) == 0) { | ||
header = read_bits_3(data, boff); boff += 3; | ||
if((header >>> 1) == 0) { | ||
/* Stored block */ | ||
if(boff & 7) boff += 8 - (boff&7); | ||
/* 2 bytes sz, 2 bytes bit inverse */ | ||
var sz = data[boff>>>3] | data[(boff>>>3)+1]<<8; | ||
boff += 32; | ||
/* push sz bytes */ | ||
if(!usz && OL < woff + sz) { outbuf = realloc(outbuf, woff + sz); OL = outbuf.length; } | ||
if(typeof data.copy === 'function') { | ||
// $FlowIgnore | ||
data.copy(outbuf, woff, boff>>>3, (boff>>>3)+sz); | ||
woff += sz; boff += 8*sz; | ||
} else while(sz-- > 0) { outbuf[woff++] = data[boff>>>3]; boff += 8; } | ||
continue; | ||
} else if((header >>> 1) == 1) { | ||
/* Fixed Huffman */ | ||
max_len_1 = 9; max_len_2 = 5; | ||
} else { | ||
/* Dynamic Huffman */ | ||
boff = dyn(data, boff); | ||
max_len_1 = dyn_len_1; max_len_2 = dyn_len_2; | ||
} | ||
if(!usz && (OL < woff + 32767)) { outbuf = realloc(outbuf, woff + 32767); OL = outbuf.length; } | ||
for(;;) { // while(true) is apparently out of vogue in modern JS circles | ||
/* ingest code and move read head */ | ||
var bits = read_bits_n(data, boff, max_len_1); | ||
var code = (header>>>1) == 1 ? fix_lmap[bits] : dyn_lmap[bits]; | ||
boff += code & 15; code >>>= 4; | ||
/* 0-255 are literals, 256 is end of block token, 257+ are copy tokens */ | ||
if(((code>>>8)&0xFF) === 0) outbuf[woff++] = code; | ||
else if(code == 256) break; | ||
else { | ||
code -= 257; | ||
var len_eb = (code < 8) ? 0 : ((code-4)>>2); if(len_eb > 5) len_eb = 0; | ||
var tgt = woff + LEN_LN[code]; | ||
/* length extra bits */ | ||
if(len_eb > 0) { | ||
tgt += read_bits_n(data, boff, len_eb); | ||
boff += len_eb; | ||
} | ||
/* dist code */ | ||
bits = read_bits_n(data, boff, max_len_2); | ||
code = (header>>>1) == 1 ? fix_dmap[bits] : dyn_dmap[bits]; | ||
boff += code & 15; code >>>= 4; | ||
var dst_eb = (code < 4 ? 0 : (code-2)>>1); | ||
var dst = DST_LN[code]; | ||
/* dist extra bits */ | ||
if(dst_eb > 0) { | ||
dst += read_bits_n(data, boff, dst_eb); | ||
boff += dst_eb; | ||
} | ||
/* in the common case, manual byte copy is faster than TA set / Buffer copy */ | ||
if(!usz && OL < tgt) { outbuf = realloc(outbuf, tgt); OL = outbuf.length; } | ||
while(woff < tgt) { outbuf[woff] = outbuf[woff - dst]; ++woff; } | ||
} | ||
} | ||
} | ||
return [usz ? outbuf : outbuf.slice(0, woff), (boff+7)>>>3]; | ||
} | ||
function _inflate(payload, usz) { | ||
var data = payload.slice(payload.l||0); | ||
var out = inflate(data, usz); | ||
payload.l += out[1]; | ||
return out[0]; | ||
} | ||
function warn_or_throw(wrn, msg) { | ||
if(wrn) { if(typeof console !== 'undefined') console.error(msg); } | ||
else throw new Error(msg); | ||
} | ||
function parse_zip(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ { | ||
var blob/*:CFBlob*/ = /*::(*/file/*:: :any)*/; | ||
prep_blob(blob, 0); | ||
var FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array<string>*/ = []; | ||
var o = { | ||
FileIndex: FileIndex, | ||
FullPaths: FullPaths | ||
}; | ||
init_cfb(o, { root: options.root }); | ||
/* find end of central directory, start just after signature */ | ||
var i = blob.length - 4; | ||
while((blob[i] != 0x50 || blob[i+1] != 0x4b || blob[i+2] != 0x05 || blob[i+3] != 0x06) && i >= 0) --i; | ||
blob.l = i + 4; | ||
/* parse end of central directory */ | ||
blob.l += 4; | ||
var fcnt = blob.read_shift(2); | ||
blob.l += 6; | ||
var start_cd = blob.read_shift(4); | ||
/* parse central directory */ | ||
blob.l = start_cd; | ||
for(i = 0; i < fcnt; ++i) { | ||
/* trust local file header instead of CD entry */ | ||
blob.l += 20; | ||
var csz = blob.read_shift(4); | ||
var usz = blob.read_shift(4); | ||
var namelen = blob.read_shift(2); | ||
var efsz = blob.read_shift(2); | ||
var fcsz = blob.read_shift(2); | ||
blob.l += 8; | ||
var offset = blob.read_shift(4); | ||
var EF = parse_extra_field(/*::(*/blob.slice(blob.l+namelen, blob.l+namelen+efsz)/*:: :any)*/); | ||
blob.l += namelen + efsz + fcsz; | ||
var L = blob.l; | ||
blob.l = offset + 4; | ||
parse_local_file(blob, csz, usz, o, EF); | ||
blob.l = L; | ||
} | ||
return o; | ||
} | ||
/* head starts just after local file header signature */ | ||
function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:CFBContainer*/, EF) { | ||
/* [local file header] */ | ||
blob.l += 2; | ||
var flags = blob.read_shift(2); | ||
var meth = blob.read_shift(2); | ||
var date = parse_dos_date(blob); | ||
if(flags & 0x2041) throw new Error("Unsupported ZIP encryption"); | ||
var crc32 = blob.read_shift(4); | ||
var _csz = blob.read_shift(4); | ||
var _usz = blob.read_shift(4); | ||
var namelen = blob.read_shift(2); | ||
var efsz = blob.read_shift(2); | ||
// TODO: flags & (1<<11) // UTF8 | ||
var name = ""; for(var i = 0; i < namelen; ++i) name += String.fromCharCode(blob[blob.l++]); | ||
if(efsz) { | ||
var ef = parse_extra_field(/*::(*/blob.slice(blob.l, blob.l + efsz)/*:: :any)*/); | ||
if((ef[0x5455]||{}).mt) date = ef[0x5455].mt; | ||
if(((EF||{})[0x5455]||{}).mt) date = EF[0x5455].mt; | ||
} | ||
blob.l += efsz; | ||
/* [encryption header] */ | ||
/* [file data] */ | ||
var data = blob.slice(blob.l, blob.l + _csz); | ||
switch(meth) { | ||
case 8: data = _inflateRawSync(blob, _usz); break; | ||
case 0: break; | ||
default: throw new Error("Unsupported ZIP Compression method " + meth); | ||
} | ||
/* [data descriptor] */ | ||
var wrn = false; | ||
if(flags & 8) { | ||
crc32 = blob.read_shift(4); | ||
if(crc32 == 0x08074b50) { crc32 = blob.read_shift(4); wrn = true; } | ||
_csz = blob.read_shift(4); | ||
_usz = blob.read_shift(4); | ||
} | ||
if(_csz != csz) warn_or_throw(wrn, "Bad compressed size: " + csz + " != " + _csz); | ||
if(_usz != usz) warn_or_throw(wrn, "Bad uncompressed size: " + usz + " != " + _usz); | ||
var _crc32 = CRC32.buf(data, 0); | ||
if(crc32 != _crc32) warn_or_throw(wrn, "Bad CRC32 checksum: " + crc32 + " != " + _crc32); | ||
cfb_add(o, name, data, {unsafe: true, mt: date}); | ||
} | ||
function write_zip(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/ { | ||
var _opts = options || {}; | ||
var out = [], cdirs = []; | ||
var o/*:CFBlob*/ = new_buf(1); | ||
var method = (_opts.compression ? 8 : 0), flags = 0; | ||
var desc = false; | ||
if(desc) flags |= 8; | ||
var i = 0, j = 0; | ||
var start_cd = 0, fcnt = 0; | ||
var root = cfb.FullPaths[0], fp = root, fi = cfb.FileIndex[0]; | ||
var crcs = []; | ||
var sz_cd = 0; | ||
for(i = 1; i < cfb.FullPaths.length; ++i) { | ||
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i]; | ||
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue; | ||
var start = start_cd; | ||
/* TODO: CP437 filename */ | ||
var namebuf = new_buf(fp.length); | ||
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F); | ||
namebuf = namebuf.slice(0, namebuf.l); | ||
crcs[fcnt] = CRC32.buf(/*::((*/fi.content/*::||[]):any)*/, 0); | ||
var outbuf = fi.content/*::||[]*/; | ||
if(method == 8) outbuf = _deflateRawSync(outbuf); | ||
/* local file header */ | ||
o = new_buf(30); | ||
o.write_shift(4, 0x04034b50); | ||
o.write_shift(2, 20); | ||
o.write_shift(2, flags); | ||
o.write_shift(2, method); | ||
/* TODO: last mod file time/date */ | ||
if(fi.mt) write_dos_date(o, fi.mt); | ||
else o.write_shift(4, 0); | ||
o.write_shift(-4, (flags & 8) ? 0 : crcs[fcnt]); | ||
o.write_shift(4, (flags & 8) ? 0 : outbuf.length); | ||
o.write_shift(4, (flags & 8) ? 0 : /*::(*/fi.content/*::||[])*/.length); | ||
o.write_shift(2, namebuf.length); | ||
o.write_shift(2, 0); | ||
start_cd += o.length; | ||
out.push(o); | ||
start_cd += namebuf.length; | ||
out.push(namebuf); | ||
/* TODO: encryption header ? */ | ||
start_cd += outbuf.length; | ||
out.push(outbuf); | ||
/* data descriptor */ | ||
if(flags & 8) { | ||
o = new_buf(12); | ||
o.write_shift(-4, crcs[fcnt]); | ||
o.write_shift(4, outbuf.length); | ||
o.write_shift(4, /*::(*/fi.content/*::||[])*/.length); | ||
start_cd += o.l; | ||
out.push(o); | ||
} | ||
/* central directory */ | ||
o = new_buf(46); | ||
o.write_shift(4, 0x02014b50); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 20); | ||
o.write_shift(2, flags); | ||
o.write_shift(2, method); | ||
o.write_shift(4, 0); /* TODO: last mod file time/date */ | ||
o.write_shift(-4, crcs[fcnt]); | ||
o.write_shift(4, outbuf.length); | ||
o.write_shift(4, /*::(*/fi.content/*::||[])*/.length); | ||
o.write_shift(2, namebuf.length); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(4, 0); | ||
o.write_shift(4, start); | ||
sz_cd += o.l; | ||
cdirs.push(o); | ||
sz_cd += namebuf.length; | ||
cdirs.push(namebuf); | ||
++fcnt; | ||
} | ||
/* end of central directory */ | ||
o = new_buf(22); | ||
o.write_shift(4, 0x06054b50); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, 0); | ||
o.write_shift(2, fcnt); | ||
o.write_shift(2, fcnt); | ||
o.write_shift(4, sz_cd); | ||
o.write_shift(4, start_cd); | ||
o.write_shift(2, 0); | ||
return bconcat(([bconcat((out/*:any*/)), bconcat(cdirs), o]/*:any*/)); | ||
} | ||
function cfb_new(opts/*:?any*/)/*:CFBContainer*/ { | ||
@@ -715,2 +1434,4 @@ var o/*:CFBContainer*/ = ({}/*:any*/); | ||
if(opts.CLSID) file.clsid = opts.CLSID; | ||
if(opts.mt) file.mt = opts.mt; | ||
if(opts.ct) file.ct = opts.ct; | ||
} | ||
@@ -759,2 +1480,5 @@ return file; | ||
bconcat: bconcat, | ||
use_zlib: use_zlib, | ||
_deflateRaw: _deflate, | ||
_inflateRaw: _inflate, | ||
consts: consts | ||
@@ -761,0 +1485,0 @@ }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
293709
7
5798
176
4
+ Addedadler-32@~1.2.0
+ Addedcrc-32@~1.2.0
+ Addedadler-32@1.2.0(transitive)
+ Addedcrc-32@1.2.2(transitive)
+ Addedexit-on-epipe@1.0.1(transitive)
Updatedcommander@^2.16.0