Comparing version 0.10.0 to 0.10.1
@@ -89,3 +89,3 @@ /* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ | ||
var exports = {}; | ||
exports.version = '0.10.0'; | ||
exports.version = '0.10.1'; | ||
function parse(file) { | ||
@@ -92,0 +92,0 @@ var mver = 3; // major version |
622
dist/cfb.js
@@ -8,35 +8,20 @@ /* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ | ||
return { | ||
/* (will need this for writing) encode: function(input, utf8) { | ||
decode: function(input) { | ||
var o = ""; | ||
var c1, c2, c3, e1, e2, e3, e4; | ||
for(var i = 0; i < input.length; ) { | ||
c1 = input.charCodeAt(i++); | ||
c2 = input.charCodeAt(i++); | ||
c3 = input.charCodeAt(i++); | ||
e1 = c1 >> 2; | ||
e2 = (c1 & 3) << 4 | c2 >> 4; | ||
e3 = (c2 & 15) << 2 | c3 >> 6; | ||
e4 = c3 & 63; | ||
if (isNaN(c2)) { e3 = e4 = 64; } | ||
else if (isNaN(c3)) { e4 = 64; } | ||
o += map.charAt(e1) + map.charAt(e2) + map.charAt(e3) + map.charAt(e4); | ||
} | ||
return o; | ||
},*/ | ||
decode: function(input, utf8) { | ||
var o = ""; | ||
var c1, c2, c3; | ||
var e1, e2, e3, e4; | ||
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); | ||
input = input.replace(/[^\w\+\/\=]/g, ""); | ||
for(var i = 0; i < input.length;) { | ||
e1 = map.indexOf(input.charAt(i++)); | ||
e2 = map.indexOf(input.charAt(i++)); | ||
c1 = (e1 << 2) | (e2 >> 4); | ||
o += String.fromCharCode(c1); | ||
e3 = map.indexOf(input.charAt(i++)); | ||
c2 = ((e2 & 15) << 4) | (e3 >> 2); | ||
if (e3 !== 64) { o += String.fromCharCode(c2); } | ||
e4 = map.indexOf(input.charAt(i++)); | ||
c1 = e1 << 2 | e2 >> 4; | ||
c2 = (e2 & 15) << 4 | e3 >> 2; | ||
c3 = (e3 & 3) << 6 | e4; | ||
o += String.fromCharCode(c1); | ||
if (e3 != 64) { o += String.fromCharCode(c2); } | ||
if (e4 != 64) { o += String.fromCharCode(c3); } | ||
c3 = ((e3 & 3) << 6) | e4; | ||
if (e4 !== 64) { o += String.fromCharCode(c3); } | ||
} | ||
@@ -48,85 +33,63 @@ return o; | ||
function s2a(s) { | ||
if(typeof Buffer !== 'undefined') return new Buffer(s, "binary"); | ||
var w = s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; }); | ||
return w; | ||
} | ||
var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/; | ||
var __toBuffer; | ||
var s2a, _s2a; | ||
s2a = _s2a = function _s2a(s) { return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; }); }; | ||
var __toBuffer, ___toBuffer; | ||
__toBuffer = ___toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; }; | ||
var __utf16le, ___utf16le; | ||
__utf16le = ___utf16le = function(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join("").replace(chr0,'').replace(chr1,'!'); }; | ||
var __hexlify, ___hexlify; | ||
__hexlify = ___hexlify = function(b,s,l) { return b.slice(s,(s+l)).map(function(x){return (x<16?"0":"") + x.toString(16);}).join(""); }; | ||
var bconcat = function(bufs) { return [].concat.apply([], bufs); }; | ||
if(typeof Buffer !== "undefined") { | ||
Buffer.prototype.hexlify= function() { return this.toString('hex'); }; | ||
Buffer.prototype.utf16le= function(s,e){return this.toString('utf16le',s,e).replace(/\u0000/,'').replace(/[\u0001-\u0006]/,'!');}; | ||
Buffer.prototype.utf8 = function(s,e) { return this.toString('utf8',s,e); }; | ||
__toBuffer = function(bufs) { return Buffer.concat(bufs[0]); }; | ||
} else { | ||
__toBuffer = function(bufs) { | ||
var x = []; | ||
for(var i = 0; i != bufs[0].length; ++i) { x = x.concat(bufs[0][i]); } | ||
return x; | ||
__utf16le = function(b,s,e) { | ||
if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); | ||
return b.toString('utf16le',s,e).replace(chr0,'').replace(chr1,'!'); | ||
}; | ||
__hexlify = function(b,s,l) { return Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); }; | ||
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);}; | ||
s2a = function(s) { return Buffer(s, "binary"); }; | ||
bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); }; | ||
} | ||
var __readUInt8 = function(b, idx) { return b.readUInt8 ? b.readUInt8(idx) : b[idx]; }; | ||
var __readUInt16LE = function(b, idx) { return b.readUInt16LE ? b.readUInt16LE(idx) : b[idx+1]*(1<<8)+b[idx]; }; | ||
var __readInt16LE = function(b, idx) { var u = __readUInt16LE(b,idx); if(!(u & 0x8000)) return u; return (0xffff - u + 1) * -1; }; | ||
var __readUInt32LE = function(b, idx) { return b.readUInt32LE ? b.readUInt32LE(idx) : b[idx+3]*(1<<24)+b[idx+2]*(1<<16)+b[idx+1]*(1<<8)+b[idx]; }; | ||
var __readInt32LE = function(b, idx) { if(b.readInt32LE) return b.readInt32LE(idx); var u = __readUInt32LE(b,idx); if(!(u & 0x80000000)) return u; return (0xffffffff - u + 1) * -1; }; | ||
var __hexlify = function(b) { return b.map(function(x){return (x<16?"0":"") + x.toString(16);}).join(""); }; | ||
var __readUInt8 = function(b, idx) { return b[idx]; }; | ||
var __readUInt16LE = function(b, idx) { return b[idx+1]*(1<<8)+b[idx]; }; | ||
var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; }; | ||
var __readUInt32LE = function(b, idx) { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; }; | ||
var __readInt32LE = function(b, idx) { return (b[idx+3]<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; }; | ||
var __utf16le = function(b,s,e) { if(b.utf16le) return b.utf16le(s,e); var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join("").replace(/\u0000/,'').replace(/[\u0001-\u0006]/,'!'); }; | ||
var __utf8 = function(b,s,e) { if(b.utf8) return b.utf8(s,e); var ss=[]; for(var i=s; i<e; i++) ss.push(String.fromCharCode(__readUInt8(b,i))); return ss.join(""); }; | ||
function bconcat(bufs) { return (typeof Buffer !== 'undefined') ? Buffer.concat(bufs) : [].concat.apply([], bufs); } | ||
/** Buffer helpers -- keep track of read location `.l` and move it */ | ||
function ReadShift(size, t) { | ||
var o, oo=[], w, vv; t = t || 'u'; | ||
var oI, oS, type = 0; | ||
switch(size) { | ||
case 1: o = __readUInt8(this, this.l); break; | ||
case 2: o=(t==='u' ? __readUInt16LE : __readInt16LE)(this, this.l); break; | ||
case 4: o = __readUInt32LE(this, this.l); break; | ||
case 8: | ||
case 16: o = this.toString('hex', this.l,this.l+size); break; | ||
case 'utf8': size = t; o = __utf8(this, this.l, this.l + size); break; | ||
case 'utf16le': size=2*t; o = __utf16le(this, this.l, this.l + size); break; | ||
case 'cstr': size = 0; o = ""; | ||
while((w=__readUInt8(this, this.l + size++))!==0) oo.push(String.fromCharCode(w)); | ||
o = oo.join(""); break; | ||
case 'wstr': size = 0; o = ""; | ||
while((w=__readUInt16LE(this,this.l +size))!==0){oo.push(String.fromCharCode(w));size+=2;} | ||
size+=2; break; | ||
case 1: oI = __readUInt8(this, this.l); break; | ||
case 2: oI = (t !== 'i' ? __readUInt16LE : __readInt16LE)(this, this.l); break; | ||
case 4: oI = __readInt32LE(this, this.l); break; | ||
case 16: type = 2; oS = __hexlify(this, this.l, size); | ||
} | ||
this.l+=size; return o; | ||
this.l+=size; if(type === 0) return oI; return oS; | ||
} | ||
function CheckField(hexstr, fld) { | ||
var b = this.slice(this.l, this.l+hexstr.length/2); | ||
var m = b.hexlify ? b.hexlify() : __hexlify(b); | ||
if(m !== hexstr) throw (fld||"") + 'Expected ' + hexstr + ' saw ' + m; | ||
this.l += hexstr.length/2; | ||
var m = __hexlify(this,this.l,hexstr.length>>1); | ||
if(m !== hexstr) throw fld + 'Expected ' + hexstr + ' saw ' + m; | ||
this.l += hexstr.length>>1; | ||
} | ||
function prep_blob(blob, pos) { | ||
blob.read_shift = ReadShift.bind(blob); | ||
blob.l = pos; | ||
blob.read_shift = ReadShift; | ||
blob.chk = CheckField; | ||
blob.l = pos || 0; | ||
var read = ReadShift.bind(blob), chk = CheckField.bind(blob); | ||
return [read, chk]; | ||
} | ||
/* [MS-CFB] v20130118 */ | ||
var CFB = (function(){ | ||
this.version = '0.9.1'; | ||
var CFB = (function _CFB(){ | ||
var exports = {}; | ||
exports.version = '0.10.1'; | ||
function parse(file) { | ||
var mver = 3; // major version | ||
var ssz = 512; // sector size | ||
var mssz = 64; // mini sector size | ||
var nds = 0; // number of directory sectors | ||
var nfs = 0; // number of FAT sectors | ||
var nmfs = 0; // number of mini FAT sectors | ||
@@ -138,6 +101,2 @@ var ndfs = 0; // number of DIFAT sectors | ||
var ms_cutoff_size = 4096; // mini stream cutoff size | ||
var minifat_store = 0; // first sector with minifat data | ||
var minifat_size = 0; // size of minifat data | ||
var fat_addrs = []; // locations of FAT sectors | ||
@@ -147,186 +106,277 @@ | ||
var blob = file.slice(0,512); | ||
prep_blob(blob); | ||
var read = ReadShift.bind(blob), chk = CheckField.bind(blob); | ||
var j = 0, q; | ||
prep_blob(blob, 0); | ||
// header signature 8 | ||
chk(HEADER_SIGNATURE, 'Header Signature: '); | ||
// clsid 16 | ||
chk(HEADER_CLSID, 'CLSID: '); | ||
// minor version 2 | ||
read(2); | ||
// major version 3 | ||
mver = read(2); | ||
/* major version */ | ||
mver = check_get_mver(blob); | ||
switch(mver) { | ||
case 3: ssz = 512; break; | ||
case 4: ssz = 4096; break; | ||
case 3: ssz = 512; break; case 4: ssz = 4096; break; | ||
default: throw "Major Version: Expected 3 or 4 saw " + mver; | ||
} | ||
// reprocess header | ||
var pos = blob.l; | ||
blob = file.slice(0,ssz); | ||
prep_blob(blob,pos); | ||
read = ReadShift.bind(blob); | ||
chk = CheckField.bind(blob); | ||
/* reprocess header */ | ||
if(ssz !== 512) { blob = file.slice(0,ssz); prep_blob(blob, 28 /* blob.l */); } | ||
/* Save header for final object */ | ||
var header = file.slice(0,ssz); | ||
// Byte Order TODO | ||
chk('feff', 'Byte Order: '); | ||
check_shifts(blob, mver); | ||
// Sector Shift | ||
switch((q = read(2))) { | ||
case 0x09: if(mver !== 3) throw 'MajorVersion/SectorShift Mismatch'; break; | ||
case 0x0c: if(mver !== 4) throw 'MajorVersion/SectorShift Mismatch'; break; | ||
default: throw 'Sector Shift: Expected 9 or 12 saw ' + q; | ||
} | ||
// Mini Sector Shift | ||
chk('0600', 'Mini Sector Shift: '); | ||
// Reserved | ||
chk('000000000000', 'Mini Sector Shift: '); | ||
// Number of Directory Sectors | ||
nds = read(4); | ||
var nds = blob.read_shift(4, 'i'); | ||
if(mver === 3 && nds !== 0) throw '# Directory Sectors: Expected 0 saw ' + nds; | ||
// Number of FAT Sectors | ||
nfs = read(4); | ||
//var nfs = blob.read_shift(4, 'i'); | ||
blob.l += 4; | ||
// First Directory Sector Location | ||
dir_start = read(4); | ||
dir_start = blob.read_shift(4, 'i'); | ||
// Transaction Signature TODO | ||
read(4); | ||
// Transaction Signature | ||
blob.l += 4; | ||
// Mini Stream Cutoff Size TODO | ||
chk('00100000', 'Mini Stream Cutoff Size: '); | ||
// Mini Stream Cutoff Size | ||
blob.chk('00100000', 'Mini Stream Cutoff Size: '); | ||
// First Mini FAT Sector Location | ||
minifat_start = read(4); | ||
minifat_start = blob.read_shift(4, 'i'); | ||
// Number of Mini FAT Sectors | ||
nmfs = read(4); | ||
nmfs = blob.read_shift(4, 'i'); | ||
// First DIFAT sector location | ||
difat_start = read(4); | ||
difat_start = blob.read_shift(4, 'i'); | ||
// Number of DIFAT Sectors | ||
ndfs = read(4); | ||
ndfs = blob.read_shift(4, 'i'); | ||
// Grab FAT Sector Locations | ||
for(j = 0; blob.l != 512; ) { | ||
if((q = read(4))>=MAXREGSECT) break; | ||
fat_addrs[j++] = q; | ||
for(var q, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */ | ||
q = blob.read_shift(4, 'i'); | ||
if(q<0) break; | ||
fat_addrs[j] = q; | ||
} | ||
/** Break the file up into sectors */ | ||
var sectors = sectorify(file, ssz); | ||
sleuth_fat(difat_start, ndfs, sectors, ssz, fat_addrs); | ||
/** Chains */ | ||
var sector_list = make_sector_list(sectors, dir_start, fat_addrs, ssz); | ||
sector_list[dir_start].name = "!Directory"; | ||
if(nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT"; | ||
sector_list[fat_addrs[0]].name = "!FAT"; | ||
/* [MS-CFB] 2.6.1 Compound File Directory Entry */ | ||
var files = {}, Paths = [], FileIndex = [], FullPaths = [], FullPathDir = {}; | ||
read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); | ||
build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); | ||
var root_name = Paths.shift(); | ||
Paths.root = root_name; | ||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */ | ||
var find_path = make_find_path(FullPaths, Paths, FileIndex, files, root_name); | ||
return { | ||
raw: {header: header, sectors: sectors}, | ||
FileIndex: FileIndex, | ||
FullPaths: FullPaths, | ||
FullPathDir: FullPathDir, | ||
find: find_path | ||
}; | ||
} // parse | ||
/* [MS-CFB] 2.2 Compound File Header -- read up to major version */ | ||
function check_get_mver(blob) { | ||
// header signature 8 | ||
blob.chk(HEADER_SIGNATURE, 'Header Signature: '); | ||
// clsid 16 | ||
blob.chk(HEADER_CLSID, 'CLSID: '); | ||
// minor version 2 | ||
blob.l += 2; | ||
return blob.read_shift(2,'u'); | ||
} | ||
function check_shifts(blob, mver) { | ||
var shift = 0x09; | ||
// Byte Order | ||
blob.chk('feff', 'Byte Order: '); | ||
// Sector Shift | ||
switch((shift = blob.read_shift(2))) { | ||
case 0x09: if(mver !== 3) throw 'MajorVersion/SectorShift Mismatch'; break; | ||
case 0x0c: if(mver !== 4) throw 'MajorVersion/SectorShift Mismatch'; break; | ||
default: throw 'Sector Shift: Expected 9 or 12 saw ' + shift; | ||
} | ||
// Mini Sector Shift | ||
blob.chk('0600', 'Mini Sector Shift: '); | ||
// Reserved | ||
blob.chk('000000000000', 'Reserved: '); | ||
} | ||
/** Break the file up into sectors */ | ||
var nsectors = Math.ceil((file.length - ssz)/ssz); | ||
var sectors = []; | ||
for(var i=1; i != nsectors; ++i) sectors[i-1] = file.slice(i*ssz,(i+1)*ssz); | ||
sectors[nsectors-1] = file.slice(nsectors*ssz); | ||
function sectorify(file, ssz) { | ||
var nsectors = Math.ceil(file.length/ssz)-1; | ||
var sectors = new Array(nsectors); | ||
for(var i=1; i < nsectors; ++i) sectors[i-1] = file.slice(i*ssz,(i+1)*ssz); | ||
sectors[nsectors-1] = file.slice(nsectors*ssz); | ||
return sectors; | ||
} | ||
/* [MS-CFB] 2.6.4 Red-Black Tree */ | ||
function build_full_paths(FI, FPD, FP, Paths) { | ||
var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; | ||
var dad = new Array(pl), q = new Array(pl); | ||
for(; i < pl; ++i) { dad[i]=q[i]=i; FP[i]=Paths[i]; } | ||
for(; j < q.length; ++j) { | ||
i = q[j]; | ||
L = FI[i].L; R = FI[i].R; C = FI[i].C; | ||
if(dad[i] === i) { | ||
if(L !== -1 /*NOSTREAM*/ && dad[L] !== L) dad[i] = dad[L]; | ||
if(R !== -1 && dad[R] !== R) dad[i] = dad[R]; | ||
} | ||
if(C !== -1 /*NOSTREAM*/) dad[C] = i; | ||
if(L !== -1) { dad[L] = dad[i]; q.push(L); } | ||
if(R !== -1) { dad[R] = dad[i]; q.push(R); } | ||
} | ||
for(i=1; i !== pl; ++i) if(dad[i] === i) { | ||
if(R !== -1 /*NOSTREAM*/ && dad[R] !== R) dad[i] = dad[R]; | ||
else if(L !== -1 && dad[L] !== L) dad[i] = dad[L]; | ||
} | ||
for(i=1; i < pl; ++i) { | ||
if(FI[i].type === 0 /* unknown */) continue; | ||
j = dad[i]; | ||
if(j === 0) FP[i] = FP[0] + "/" + FP[i]; | ||
else while(j !== 0) { | ||
FP[i] = FP[j] + "/" + FP[i]; | ||
j = dad[j]; | ||
} | ||
dad[i] = 0; | ||
} | ||
FP[0] += "/"; | ||
for(i=1; i < pl; ++i) { | ||
if(FI[i].type !== 2 /* stream */) FP[i] += "/"; | ||
FPD[FP[i]] = FI[i]; | ||
} | ||
} | ||
/* [MS-CFB] 2.6.4 */ | ||
function make_find_path(FullPaths, Paths, FileIndex, files, root_name) { | ||
var UCFullPaths = new Array(FullPaths.length); | ||
var UCPaths = new Array(Paths.length), i; | ||
for(i = 0; i < FullPaths.length; ++i) UCFullPaths[i] = FullPaths[i].toUpperCase(); | ||
for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase(); | ||
return function find_path(path) { | ||
var k; | ||
if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; } | ||
else k = path.indexOf("/") !== -1; | ||
var UCPath = path.toUpperCase(); | ||
var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath); | ||
if(w === -1) return null; | ||
return k === true ? FileIndex[w] : files[Paths[w]]; | ||
}; | ||
} | ||
/** Chase down the rest of the DIFAT chain to build a comprehensive list | ||
DIFAT chains by storing the next sector number as the last 32 bytes */ | ||
function sleuth_fat(idx, cnt) { | ||
function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { | ||
var q; | ||
if(idx === ENDOFCHAIN) { | ||
if(cnt !== 0) throw "DIFAT chain shorter than expected"; | ||
return; | ||
} | ||
if(idx !== FREESECT) { | ||
var sector = sectors[idx]; | ||
for(var i = 0; i != ssz/4-1; ++i) { | ||
if((q = __readUInt32LE(sector,i*4)) === ENDOFCHAIN) break; | ||
} else if(idx !== -1 /*FREESECT*/) { | ||
var sector = sectors[idx], m = (ssz>>>2)-1; | ||
for(var i = 0; i < m; ++i) { | ||
if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break; | ||
fat_addrs.push(q); | ||
} | ||
sleuth_fat(__readUInt32LE(sector,ssz-4),cnt - 1); | ||
sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs); | ||
} | ||
} | ||
sleuth_fat(difat_start, ndfs); | ||
/** DONT CAT THE FAT! Just calculate where we need to go */ | ||
function get_buffer(byte_addr, bytes) { | ||
var addr = fat_addrs[Math.floor(byte_addr*4/ssz)]; | ||
if(ssz - (byte_addr*4 % ssz) < (bytes || 0)) throw "FAT boundary crossed: " + byte_addr + " "+bytes+" "+ssz; | ||
return sectors[addr].slice((byte_addr*4 % ssz)); | ||
/** Chase down the sector linked lists */ | ||
function make_sector_list(sectors, dir_start, fat_addrs, ssz) { | ||
var sl = sectors.length, sector_list = new Array(sl); | ||
var chkd = new Array(sl), buf, buf_chain; | ||
var modulus = ssz - 1, i, j, k, jj; | ||
for(i=0; i < sl; ++i) { | ||
buf = []; | ||
k = (i + dir_start); if(k >= sl) k-=sl; | ||
if(chkd[k] === true) continue; | ||
buf_chain = []; | ||
for(j=k; j>=0;) { | ||
chkd[j] = true; | ||
buf[buf.length] = j; | ||
buf_chain.push(sectors[j]); | ||
var addr = fat_addrs[Math.floor(j*4/ssz)]; | ||
jj = ((j*4) & modulus); | ||
if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; | ||
j = __readInt32LE(sectors[addr], jj); | ||
} | ||
sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; | ||
} | ||
return sector_list; | ||
} | ||
function get_buffer_u32(byte_addr) { | ||
return __readUInt32LE(get_buffer(byte_addr,4), 0); | ||
} | ||
function get_next_sector(idx) { return get_buffer_u32(idx); } | ||
/** Chains */ | ||
var chkd = new Array(sectors.length), sector_list = []; | ||
var get_sector = function get_sector(k) { return sectors[k]; }; | ||
for(i=0; i != sectors.length; ++i) { | ||
var buf = [], k = (i + dir_start) % sectors.length; | ||
if(chkd[k]) continue; | ||
for(j=k; j<=MAXREGSECT; buf.push(j),j=get_next_sector(j)) chkd[j] = true; | ||
sector_list[k] = {nodes: buf}; | ||
sector_list[k].data = __toBuffer(Array(buf.map(get_sector))); | ||
} | ||
sector_list[dir_start].name = "!Directory"; | ||
if(nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT"; | ||
sector_list[fat_addrs[0]].name = "!FAT"; | ||
/* [MS-CFB] 2.6.1 Compound File Directory Entry */ | ||
var files = {}, Paths = [], FileIndex = [], FullPaths = [], FullPathDir = {}; | ||
function read_directory(idx) { | ||
var blob, read, w; | ||
var sector = sector_list[idx].data; | ||
for(var i = 0; i != sector.length; i+= 128) { | ||
function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex) { | ||
var blob; | ||
var minifat_store = 0, pl = (Paths.length?2:0); | ||
var sector = sector_list[dir_start].data; | ||
var i = 0, namelen = 0, name, o, ctime, mtime; | ||
for(; i < sector.length; i+= 128) { | ||
blob = sector.slice(i, i+128); | ||
prep_blob(blob, 64); | ||
read = ReadShift.bind(blob); | ||
var namelen = read(2); | ||
if(namelen === 0) return; | ||
var name = __utf16le(blob,0,namelen-(Paths.length?2:0)); // OLE | ||
namelen = blob.read_shift(2); | ||
if(namelen === 0) continue; | ||
name = __utf16le(blob,0,namelen-pl); | ||
Paths.push(name); | ||
var o = { name: name }; | ||
o.type = EntryTypes[read(1)]; | ||
o.color = read(1); | ||
o.left = read(4); if(o.left === NOSTREAM) delete o.left; | ||
o.right = read(4); if(o.right === NOSTREAM) delete o.right; | ||
o.child = read(4); if(o.child === NOSTREAM) delete o.child; | ||
o.clsid = read(16); | ||
o.state = read(4); | ||
var ctime = read(8); if(ctime != "0000000000000000") o.ctime = ctime; | ||
var mtime = read(8); if(mtime != "0000000000000000") o.mtime = mtime; | ||
o.start = read(4); | ||
o.size = read(4); | ||
if(o.type === 'root') { //root entry | ||
o = { | ||
name: name, | ||
type: blob.read_shift(1), | ||
color: blob.read_shift(1), | ||
L: blob.read_shift(4, 'i'), | ||
R: blob.read_shift(4, 'i'), | ||
C: blob.read_shift(4, 'i'), | ||
clsid: blob.read_shift(16), | ||
state: blob.read_shift(4, 'i') | ||
}; | ||
ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||
if(ctime !== 0) { | ||
o.ctime = ctime; o.ct = read_date(blob, blob.l-8); | ||
} | ||
mtime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||
if(mtime !== 0) { | ||
o.mtime = mtime; o.mt = read_date(blob, blob.l-8); | ||
} | ||
o.start = blob.read_shift(4, 'i'); | ||
o.size = blob.read_shift(4, 'i'); | ||
if(o.type === 5) { /* root */ | ||
minifat_store = o.start; | ||
if(nmfs > 0 && minifat_store !== ENDOFCHAIN) sector_list[minifat_store].name = "!StreamData"; | ||
minifat_size = o.size; | ||
} else if(o.size >= ms_cutoff_size) { | ||
/*minifat_size = o.size;*/ | ||
} else if(o.size >= 4096 /* MSCSZ */) { | ||
o.storage = 'fat'; | ||
if(!sector_list[o.start] && dir_start > 0) o.start = (o.start + dir_start) % sectors.length; | ||
if(sector_list[o.start] === undefined) if((o.start+=dir_start)>=sectors.length) o.start-=sectors.length; | ||
sector_list[o.start].name = o.name; | ||
o.content = sector_list[o.start].data.slice(0,o.size); | ||
prep_blob(o.content); | ||
prep_blob(o.content, 0); | ||
} else { | ||
o.storage = 'minifat'; | ||
w = o.start * mssz; | ||
if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN) { | ||
o.content = sector_list[minifat_store].data.slice(w,w+o.size); | ||
prep_blob(o.content); | ||
o.content = sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size); | ||
prep_blob(o.content, 0); | ||
} | ||
} | ||
if(o.ctime) { | ||
var ct = blob.slice(blob.l-24, blob.l-16); | ||
var c2 = (__readUInt32LE(ct,4)/1e7)*Math.pow(2,32)+__readUInt32LE(ct,0)/1e7; | ||
o.ct = new Date((c2 - 11644473600)*1000); | ||
} | ||
if(o.mtime) { | ||
var mt = blob.slice(blob.l-16, blob.l-8); | ||
var m2 = (__readUInt32LE(mt,4)/1e7)*Math.pow(2,32)+__readUInt32LE(mt,0)/1e7; | ||
o.mt = new Date((m2 - 11644473600)*1000); | ||
} | ||
files[name] = o; | ||
@@ -336,84 +386,18 @@ FileIndex.push(o); | ||
} | ||
read_directory(dir_start); | ||
/* [MS-CFB] 2.6.4 Red-Black Tree */ | ||
function build_full_paths(Dir, pathobj, paths, patharr) { | ||
var i; | ||
var dad = new Array(patharr.length); | ||
var q = new Array(patharr.length); | ||
for(i=0; i != dad.length; ++i) { dad[i]=q[i]=i; paths[i]=patharr[i]; } | ||
while(q.length > 0) { | ||
for(i = q[0]; typeof i !== "undefined"; i = q.shift()) { | ||
if(dad[i] === i) { | ||
if(Dir[i].left && dad[Dir[i].left] != Dir[i].left) dad[i] = dad[Dir[i].left]; | ||
if(Dir[i].right && dad[Dir[i].right] != Dir[i].right) dad[i] = dad[Dir[i].right]; | ||
} | ||
if(Dir[i].child) dad[Dir[i].child] = i; | ||
if(Dir[i].left) { dad[Dir[i].left] = dad[i]; q.push(Dir[i].left); } | ||
if(Dir[i].right) { dad[Dir[i].right] = dad[i]; q.push(Dir[i].right); } | ||
} | ||
for(i=1; i != dad.length; ++i) if(dad[i] === i) { | ||
if(Dir[i].right && dad[Dir[i].right] != Dir[i].right) dad[i] = dad[Dir[i].right]; | ||
else if(Dir[i].left && dad[Dir[i].left] != Dir[i].left) dad[i] = dad[Dir[i].left]; | ||
} | ||
} | ||
for(i=1; i !== paths.length; ++i) { | ||
if(Dir[i].type === "unknown") continue; | ||
var j = dad[i]; | ||
if(j === 0) paths[i] = paths[0] + "/" + paths[i]; | ||
else while(j !== 0) { | ||
paths[i] = paths[j] + "/" + paths[i]; | ||
j = dad[j]; | ||
} | ||
dad[i] = 0; | ||
} | ||
paths[0] += "/"; | ||
for(i=1; i !== paths.length; ++i) if(Dir[i].type !== 'stream') paths[i] += "/"; | ||
for(i=0; i !== paths.length; ++i) pathobj[paths[i]] = FileIndex[i]; | ||
function read_date(blob, offset) { | ||
return new Date(( ( (__readUInt32LE(blob,offset+4)/1e7)*Math.pow(2,32)+__readUInt32LE(blob,offset)/1e7 ) - 11644473600)*1000); | ||
} | ||
build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); | ||
var root_name = Paths.shift(); | ||
Paths.root = root_name; | ||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */ | ||
function find_path(path) { | ||
if(path[0] === "/") path = root_name + path; | ||
var UCNames = (path.indexOf("/") !== -1 ? FullPaths : Paths).map(function(x) { return x.toUpperCase(); }); | ||
var UCPath = path.toUpperCase(); | ||
var w = UCNames.indexOf(UCPath); | ||
if(w === -1) return null; | ||
return path.indexOf("/") !== -1 ? FileIndex[w] : files[Paths[w]]; | ||
} | ||
var rval = { | ||
raw: {header: header, sectors: sectors}, | ||
FileIndex: FileIndex, | ||
FullPaths: FullPaths, | ||
FullPathDir: FullPathDir, | ||
find: find_path | ||
}; | ||
return rval; | ||
} // parse | ||
var fs; | ||
function readFileSync(filename) { | ||
var fs = require('fs'); | ||
var file = fs.readFileSync(filename); | ||
return parse(file); | ||
if(fs === undefined) fs = require('fs'); | ||
return parse(fs.readFileSync(filename)); | ||
} | ||
function readSync(blob, options) { | ||
var o = options || {}; | ||
switch((o.type || "base64")) { | ||
switch(options !== undefined && options.type !== undefined ? options.type : "base64") { | ||
case "file": return readFileSync(blob); | ||
case "base64": blob = Base64.decode(blob); | ||
/* falls through */ | ||
case "binary": blob = s2a(blob); break; | ||
case "base64": return parse(s2a(Base64.decode(blob))); | ||
case "binary": return parse(s2a(blob)); | ||
} | ||
@@ -423,38 +407,40 @@ return parse(blob); | ||
this.read = readSync; | ||
this.parse = parse; | ||
return this; | ||
})(); | ||
/** CFB Constants */ | ||
{ | ||
var MSSZ = 64; /* Mini Sector Size = 1<<6 */ | ||
//var MSCSZ = 4096; /* Mini Stream Cutoff Size */ | ||
/* 2.1 Compound File Sector Numbers and Types */ | ||
var ENDOFCHAIN = -2; | ||
/* 2.2 Compound File Header */ | ||
var HEADER_SIGNATURE = 'd0cf11e0a1b11ae1'; | ||
var HEADER_CLSID = '00000000000000000000000000000000'; | ||
var consts = { | ||
/* 2.1 Compund File Sector Numbers and Types */ | ||
var MAXREGSECT = 0xFFFFFFFA; | ||
var DIFSECT = 0xFFFFFFFC; | ||
var FATSECT = 0xFFFFFFFD; | ||
var ENDOFCHAIN = 0xFFFFFFFE; | ||
var FREESECT = 0xFFFFFFFF; | ||
MAXREGSECT: -6, | ||
DIFSECT: -4, | ||
FATSECT: -3, | ||
ENDOFCHAIN: ENDOFCHAIN, | ||
FREESECT: -1, | ||
/* 2.2 Compound File Header */ | ||
var HEADER_SIGNATURE = 'd0cf11e0a1b11ae1'; | ||
var HEADER_MINOR_VERSION = '3e00'; | ||
var MAXREGSID = 0xFFFFFFFA; | ||
var NOSTREAM = 0xFFFFFFFF; | ||
var HEADER_CLSID = '00000000000000000000000000000000'; | ||
HEADER_SIGNATURE: HEADER_SIGNATURE, | ||
HEADER_MINOR_VERSION: '3e00', | ||
MAXREGSID: -6, | ||
NOSTREAM: -1, | ||
HEADER_CLSID: HEADER_CLSID, | ||
/* 2.6.1 Compound File Directory Entry */ | ||
var EntryTypes = ['unknown','storage','stream','lockbytes','property','root']; | ||
} | ||
EntryTypes: ['unknown','storage','stream','lockbytes','property','root'] | ||
}; | ||
var CFB_utils = { | ||
exports.read = readSync; | ||
exports.parse = parse; | ||
exports.utils = { | ||
ReadShift: ReadShift, | ||
CheckField: CheckField, | ||
prep_blob: prep_blob, | ||
bconcat: bconcat | ||
bconcat: bconcat, | ||
consts: consts | ||
}; | ||
if(typeof require !== 'undefined' && typeof exports !== 'undefined') { | ||
var fs = require('fs'); | ||
exports.read = CFB.read; | ||
exports.parse = CFB.parse; | ||
exports.utils = CFB_utils; | ||
exports.version = CFB.version; | ||
} | ||
return exports; | ||
})(); | ||
if(typeof require !== 'undefined' && typeof module !== 'undefined' && typeof DO_NOT_EXPORT_CFB === 'undefined') { module.exports = CFB; } |
/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ | ||
var Base64=function(){var map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{decode:function(input,utf8){var o="";var c1,c2,c3;var e1,e2,e3,e4;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var i=0;i<input.length;){e1=map.indexOf(input.charAt(i++));e2=map.indexOf(input.charAt(i++));e3=map.indexOf(input.charAt(i++));e4=map.indexOf(input.charAt(i++));c1=e1<<2|e2>>4;c2=(e2&15)<<4|e3>>2;c3=(e3&3)<<6|e4;o+=String.fromCharCode(c1);if(e3!=64){o+=String.fromCharCode(c2)}if(e4!=64){o+=String.fromCharCode(c3)}}return o}}}();function s2a(s){if(typeof Buffer!=="undefined")return new Buffer(s,"binary");var w=s.split("").map(function(x){return x.charCodeAt(0)&255});return w}var __toBuffer;if(typeof Buffer!=="undefined"){Buffer.prototype.hexlify=function(){return this.toString("hex")};Buffer.prototype.utf16le=function(s,e){return this.toString("utf16le",s,e).replace(/\u0000/,"").replace(/[\u0001-\u0006]/,"!")};Buffer.prototype.utf8=function(s,e){return this.toString("utf8",s,e)};__toBuffer=function(bufs){return Buffer.concat(bufs[0])}}else{__toBuffer=function(bufs){var x=[];for(var i=0;i!=bufs[0].length;++i){x=x.concat(bufs[0][i])}return x}}var __readUInt8=function(b,idx){return b.readUInt8?b.readUInt8(idx):b[idx]};var __readUInt16LE=function(b,idx){return b.readUInt16LE?b.readUInt16LE(idx):b[idx+1]*(1<<8)+b[idx]};var __readInt16LE=function(b,idx){var u=__readUInt16LE(b,idx);if(!(u&32768))return u;return(65535-u+1)*-1};var __readUInt32LE=function(b,idx){return b.readUInt32LE?b.readUInt32LE(idx):b[idx+3]*(1<<24)+b[idx+2]*(1<<16)+b[idx+1]*(1<<8)+b[idx]};var __readInt32LE=function(b,idx){if(b.readInt32LE)return b.readInt32LE(idx);var u=__readUInt32LE(b,idx);if(!(u&2147483648))return u;return(4294967295-u+1)*-1};var __hexlify=function(b){return b.map(function(x){return(x<16?"0":"")+x.toString(16)}).join("")};var __utf16le=function(b,s,e){if(b.utf16le)return b.utf16le(s,e);var ss=[];for(var i=s;i<e;i+=2)ss.push(String.fromCharCode(__readUInt16LE(b,i)));return ss.join("").replace(/\u0000/,"").replace(/[\u0001-\u0006]/,"!")};var __utf8=function(b,s,e){if(b.utf8)return b.utf8(s,e);var ss=[];for(var i=s;i<e;i++)ss.push(String.fromCharCode(__readUInt8(b,i)));return ss.join("")};function bconcat(bufs){return typeof Buffer!=="undefined"?Buffer.concat(bufs):[].concat.apply([],bufs)}function ReadShift(size,t){var o,oo=[],w,vv;t=t||"u";switch(size){case 1:o=__readUInt8(this,this.l);break;case 2:o=(t==="u"?__readUInt16LE:__readInt16LE)(this,this.l);break;case 4:o=__readUInt32LE(this,this.l);break;case 8:case 16:o=this.toString("hex",this.l,this.l+size);break;case"utf8":size=t;o=__utf8(this,this.l,this.l+size);break;case"utf16le":size=2*t;o=__utf16le(this,this.l,this.l+size);break;case"cstr":size=0;o="";while((w=__readUInt8(this,this.l+size++))!==0)oo.push(String.fromCharCode(w));o=oo.join("");break;case"wstr":size=0;o="";while((w=__readUInt16LE(this,this.l+size))!==0){oo.push(String.fromCharCode(w));size+=2}size+=2;break}this.l+=size;return o}function CheckField(hexstr,fld){var b=this.slice(this.l,this.l+hexstr.length/2);var m=b.hexlify?b.hexlify():__hexlify(b);if(m!==hexstr)throw(fld||"")+"Expected "+hexstr+" saw "+m;this.l+=hexstr.length/2}function prep_blob(blob,pos){blob.read_shift=ReadShift.bind(blob);blob.chk=CheckField;blob.l=pos||0;var read=ReadShift.bind(blob),chk=CheckField.bind(blob);return[read,chk]}var CFB=function(){this.version="0.9.1";function parse(file){var mver=3;var ssz=512;var mssz=64;var nds=0;var nfs=0;var nmfs=0;var ndfs=0;var dir_start=0;var minifat_start=0;var difat_start=0;var ms_cutoff_size=4096;var minifat_store=0;var minifat_size=0;var fat_addrs=[];var blob=file.slice(0,512);prep_blob(blob);var read=ReadShift.bind(blob),chk=CheckField.bind(blob);var j=0,q;chk(HEADER_SIGNATURE,"Header Signature: ");chk(HEADER_CLSID,"CLSID: ");read(2);mver=read(2);switch(mver){case 3:ssz=512;break;case 4:ssz=4096;break;default:throw"Major Version: Expected 3 or 4 saw "+mver}var pos=blob.l;blob=file.slice(0,ssz);prep_blob(blob,pos);read=ReadShift.bind(blob);chk=CheckField.bind(blob);var header=file.slice(0,ssz);chk("feff","Byte Order: ");switch(q=read(2)){case 9:if(mver!==3)throw"MajorVersion/SectorShift Mismatch";break;case 12:if(mver!==4)throw"MajorVersion/SectorShift Mismatch";break;default:throw"Sector Shift: Expected 9 or 12 saw "+q}chk("0600","Mini Sector Shift: ");chk("000000000000","Mini Sector Shift: ");nds=read(4);if(mver===3&&nds!==0)throw"# Directory Sectors: Expected 0 saw "+nds;nfs=read(4);dir_start=read(4);read(4);chk("00100000","Mini Stream Cutoff Size: ");minifat_start=read(4);nmfs=read(4);difat_start=read(4);ndfs=read(4);for(j=0;blob.l!=512;){if((q=read(4))>=MAXREGSECT)break;fat_addrs[j++]=q}var nsectors=Math.ceil((file.length-ssz)/ssz);var sectors=[];for(var i=1;i!=nsectors;++i)sectors[i-1]=file.slice(i*ssz,(i+1)*ssz);sectors[nsectors-1]=file.slice(nsectors*ssz);function sleuth_fat(idx,cnt){if(idx===ENDOFCHAIN){if(cnt!==0)throw"DIFAT chain shorter than expected";return}if(idx!==FREESECT){var sector=sectors[idx];for(var i=0;i!=ssz/4-1;++i){if((q=__readUInt32LE(sector,i*4))===ENDOFCHAIN)break;fat_addrs.push(q)}sleuth_fat(__readUInt32LE(sector,ssz-4),cnt-1)}}sleuth_fat(difat_start,ndfs);function get_buffer(byte_addr,bytes){var addr=fat_addrs[Math.floor(byte_addr*4/ssz)];if(ssz-byte_addr*4%ssz<(bytes||0))throw"FAT boundary crossed: "+byte_addr+" "+bytes+" "+ssz;return sectors[addr].slice(byte_addr*4%ssz)}function get_buffer_u32(byte_addr){return __readUInt32LE(get_buffer(byte_addr,4),0)}function get_next_sector(idx){return get_buffer_u32(idx)}var chkd=new Array(sectors.length),sector_list=[];var get_sector=function get_sector(k){return sectors[k]};for(i=0;i!=sectors.length;++i){var buf=[],k=(i+dir_start)%sectors.length;if(chkd[k])continue;for(j=k;j<=MAXREGSECT;buf.push(j),j=get_next_sector(j))chkd[j]=true;sector_list[k]={nodes:buf};sector_list[k].data=__toBuffer(Array(buf.map(get_sector)))}sector_list[dir_start].name="!Directory";if(nmfs>0&&minifat_start!==ENDOFCHAIN)sector_list[minifat_start].name="!MiniFAT";sector_list[fat_addrs[0]].name="!FAT";var files={},Paths=[],FileIndex=[],FullPaths=[],FullPathDir={};function read_directory(idx){var blob,read,w;var sector=sector_list[idx].data;for(var i=0;i!=sector.length;i+=128){blob=sector.slice(i,i+128);prep_blob(blob,64);read=ReadShift.bind(blob);var namelen=read(2);if(namelen===0)return;var name=__utf16le(blob,0,namelen-(Paths.length?2:0));Paths.push(name);var o={name:name};o.type=EntryTypes[read(1)];o.color=read(1);o.left=read(4);if(o.left===NOSTREAM)delete o.left;o.right=read(4);if(o.right===NOSTREAM)delete o.right;o.child=read(4);if(o.child===NOSTREAM)delete o.child;o.clsid=read(16);o.state=read(4);var ctime=read(8);if(ctime!="0000000000000000")o.ctime=ctime;var mtime=read(8);if(mtime!="0000000000000000")o.mtime=mtime;o.start=read(4);o.size=read(4);if(o.type==="root"){minifat_store=o.start;if(nmfs>0&&minifat_store!==ENDOFCHAIN)sector_list[minifat_store].name="!StreamData";minifat_size=o.size}else if(o.size>=ms_cutoff_size){o.storage="fat";if(!sector_list[o.start]&&dir_start>0)o.start=(o.start+dir_start)%sectors.length;sector_list[o.start].name=o.name;o.content=sector_list[o.start].data.slice(0,o.size);prep_blob(o.content)}else{o.storage="minifat";w=o.start*mssz;if(minifat_store!==ENDOFCHAIN&&o.start!==ENDOFCHAIN){o.content=sector_list[minifat_store].data.slice(w,w+o.size);prep_blob(o.content)}}if(o.ctime){var ct=blob.slice(blob.l-24,blob.l-16);var c2=__readUInt32LE(ct,4)/1e7*Math.pow(2,32)+__readUInt32LE(ct,0)/1e7;o.ct=new Date((c2-11644473600)*1e3)}if(o.mtime){var mt=blob.slice(blob.l-16,blob.l-8);var m2=__readUInt32LE(mt,4)/1e7*Math.pow(2,32)+__readUInt32LE(mt,0)/1e7;o.mt=new Date((m2-11644473600)*1e3)}files[name]=o;FileIndex.push(o)}}read_directory(dir_start);function build_full_paths(Dir,pathobj,paths,patharr){var i;var dad=new Array(patharr.length);var q=new Array(patharr.length);for(i=0;i!=dad.length;++i){dad[i]=q[i]=i;paths[i]=patharr[i]}while(q.length>0){for(i=q[0];typeof i!=="undefined";i=q.shift()){if(dad[i]===i){if(Dir[i].left&&dad[Dir[i].left]!=Dir[i].left)dad[i]=dad[Dir[i].left];if(Dir[i].right&&dad[Dir[i].right]!=Dir[i].right)dad[i]=dad[Dir[i].right]}if(Dir[i].child)dad[Dir[i].child]=i;if(Dir[i].left){dad[Dir[i].left]=dad[i];q.push(Dir[i].left)}if(Dir[i].right){dad[Dir[i].right]=dad[i];q.push(Dir[i].right)}}for(i=1;i!=dad.length;++i)if(dad[i]===i){if(Dir[i].right&&dad[Dir[i].right]!=Dir[i].right)dad[i]=dad[Dir[i].right];else if(Dir[i].left&&dad[Dir[i].left]!=Dir[i].left)dad[i]=dad[Dir[i].left]}}for(i=1;i!==paths.length;++i){if(Dir[i].type==="unknown")continue;var j=dad[i];if(j===0)paths[i]=paths[0]+"/"+paths[i];else while(j!==0){paths[i]=paths[j]+"/"+paths[i];j=dad[j]}dad[i]=0}paths[0]+="/";for(i=1;i!==paths.length;++i)if(Dir[i].type!=="stream")paths[i]+="/";for(i=0;i!==paths.length;++i)pathobj[paths[i]]=FileIndex[i]}build_full_paths(FileIndex,FullPathDir,FullPaths,Paths);var root_name=Paths.shift();Paths.root=root_name;function find_path(path){if(path[0]==="/")path=root_name+path;var UCNames=(path.indexOf("/")!==-1?FullPaths:Paths).map(function(x){return x.toUpperCase()});var UCPath=path.toUpperCase();var w=UCNames.indexOf(UCPath);if(w===-1)return null;return path.indexOf("/")!==-1?FileIndex[w]:files[Paths[w]]}var rval={raw:{header:header,sectors:sectors},FileIndex:FileIndex,FullPaths:FullPaths,FullPathDir:FullPathDir,find:find_path};return rval}function readFileSync(filename){var fs=require("fs");var file=fs.readFileSync(filename);return parse(file)}function readSync(blob,options){var o=options||{};switch(o.type||"base64"){case"file":return readFileSync(blob);case"base64":blob=Base64.decode(blob);case"binary":blob=s2a(blob);break}return parse(blob)}this.read=readSync;this.parse=parse;return this}();{var MAXREGSECT=4294967290;var DIFSECT=4294967292;var FATSECT=4294967293;var ENDOFCHAIN=4294967294;var FREESECT=4294967295;var HEADER_SIGNATURE="d0cf11e0a1b11ae1";var HEADER_MINOR_VERSION="3e00";var MAXREGSID=4294967290;var NOSTREAM=4294967295;var HEADER_CLSID="00000000000000000000000000000000";var EntryTypes=["unknown","storage","stream","lockbytes","property","root"]}var CFB_utils={ReadShift:ReadShift,CheckField:CheckField,prep_blob:prep_blob,bconcat:bconcat};if(typeof require!=="undefined"&&typeof exports!=="undefined"){var fs=require("fs");exports.read=CFB.read;exports.parse=CFB.parse;exports.utils=CFB_utils;exports.version=CFB.version} | ||
var Base64=function(){var map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{decode:function(input){var o="";var c1,c2,c3;var e1,e2,e3,e4;input=input.replace(/[^\w\+\/\=]/g,"");for(var i=0;i<input.length;){e1=map.indexOf(input.charAt(i++));e2=map.indexOf(input.charAt(i++));c1=e1<<2|e2>>4;o+=String.fromCharCode(c1);e3=map.indexOf(input.charAt(i++));c2=(e2&15)<<4|e3>>2;if(e3!==64){o+=String.fromCharCode(c2)}e4=map.indexOf(input.charAt(i++));c3=(e3&3)<<6|e4;if(e4!==64){o+=String.fromCharCode(c3)}}return o}}}();var chr0=/\u0000/g,chr1=/[\u0001-\u0006]/;var s2a,_s2a;s2a=_s2a=function _s2a(s){return s.split("").map(function(x){return x.charCodeAt(0)&255})};var __toBuffer,___toBuffer;__toBuffer=___toBuffer=function(bufs){var x=[];for(var i=0;i<bufs[0].length;++i){x.push.apply(x,bufs[0][i])}return x};var __utf16le,___utf16le;__utf16le=___utf16le=function(b,s,e){var ss=[];for(var i=s;i<e;i+=2)ss.push(String.fromCharCode(__readUInt16LE(b,i)));return ss.join("").replace(chr0,"").replace(chr1,"!")};var __hexlify,___hexlify;__hexlify=___hexlify=function(b,s,l){return b.slice(s,s+l).map(function(x){return(x<16?"0":"")+x.toString(16)}).join("")};var bconcat=function(bufs){return[].concat.apply([],bufs)};if(typeof Buffer!=="undefined"){__utf16le=function(b,s,e){if(!Buffer.isBuffer(b))return ___utf16le(b,s,e);return b.toString("utf16le",s,e).replace(chr0,"").replace(chr1,"!")};__hexlify=function(b,s,l){return Buffer.isBuffer(b)?b.toString("hex",s,s+l):___hexlify(b,s,l)};__toBuffer=function(bufs){return bufs[0].length>0&&Buffer.isBuffer(bufs[0][0])?Buffer.concat(bufs[0]):___toBuffer(bufs)};s2a=function(s){return Buffer(s,"binary")};bconcat=function(bufs){return Buffer.isBuffer(bufs[0])?Buffer.concat(bufs):[].concat.apply([],bufs)}}var __readUInt8=function(b,idx){return b[idx]};var __readUInt16LE=function(b,idx){return b[idx+1]*(1<<8)+b[idx]};var __readInt16LE=function(b,idx){var u=b[idx+1]*(1<<8)+b[idx];return u<32768?u:(65535-u+1)*-1};var __readUInt32LE=function(b,idx){return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]};var __readInt32LE=function(b,idx){return(b[idx+3]<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]};function ReadShift(size,t){var oI,oS,type=0;switch(size){case 1:oI=__readUInt8(this,this.l);break;case 2:oI=(t!=="i"?__readUInt16LE:__readInt16LE)(this,this.l);break;case 4:oI=__readInt32LE(this,this.l);break;case 16:type=2;oS=__hexlify(this,this.l,size)}this.l+=size;if(type===0)return oI;return oS}function CheckField(hexstr,fld){var m=__hexlify(this,this.l,hexstr.length>>1);if(m!==hexstr)throw fld+"Expected "+hexstr+" saw "+m;this.l+=hexstr.length>>1}function prep_blob(blob,pos){blob.l=pos;blob.read_shift=ReadShift;blob.chk=CheckField}var CFB=function _CFB(){var exports={};exports.version="0.10.1";function parse(file){var mver=3;var ssz=512;var nmfs=0;var ndfs=0;var dir_start=0;var minifat_start=0;var difat_start=0;var fat_addrs=[];var blob=file.slice(0,512);prep_blob(blob,0);mver=check_get_mver(blob);switch(mver){case 3:ssz=512;break;case 4:ssz=4096;break;default:throw"Major Version: Expected 3 or 4 saw "+mver}if(ssz!==512){blob=file.slice(0,ssz);prep_blob(blob,28)}var header=file.slice(0,ssz);check_shifts(blob,mver);var nds=blob.read_shift(4,"i");if(mver===3&&nds!==0)throw"# Directory Sectors: Expected 0 saw "+nds;blob.l+=4;dir_start=blob.read_shift(4,"i");blob.l+=4;blob.chk("00100000","Mini Stream Cutoff Size: ");minifat_start=blob.read_shift(4,"i");nmfs=blob.read_shift(4,"i");difat_start=blob.read_shift(4,"i");ndfs=blob.read_shift(4,"i");for(var q,j=0;j<109;++j){q=blob.read_shift(4,"i");if(q<0)break;fat_addrs[j]=q}var sectors=sectorify(file,ssz);sleuth_fat(difat_start,ndfs,sectors,ssz,fat_addrs);var sector_list=make_sector_list(sectors,dir_start,fat_addrs,ssz);sector_list[dir_start].name="!Directory";if(nmfs>0&&minifat_start!==ENDOFCHAIN)sector_list[minifat_start].name="!MiniFAT";sector_list[fat_addrs[0]].name="!FAT";var files={},Paths=[],FileIndex=[],FullPaths=[],FullPathDir={};read_directory(dir_start,sector_list,sectors,Paths,nmfs,files,FileIndex);build_full_paths(FileIndex,FullPathDir,FullPaths,Paths);var root_name=Paths.shift();Paths.root=root_name;var find_path=make_find_path(FullPaths,Paths,FileIndex,files,root_name);return{raw:{header:header,sectors:sectors},FileIndex:FileIndex,FullPaths:FullPaths,FullPathDir:FullPathDir,find:find_path}}function check_get_mver(blob){blob.chk(HEADER_SIGNATURE,"Header Signature: ");blob.chk(HEADER_CLSID,"CLSID: ");blob.l+=2;return blob.read_shift(2,"u")}function check_shifts(blob,mver){var shift=9;blob.chk("feff","Byte Order: ");switch(shift=blob.read_shift(2)){case 9:if(mver!==3)throw"MajorVersion/SectorShift Mismatch";break;case 12:if(mver!==4)throw"MajorVersion/SectorShift Mismatch";break;default:throw"Sector Shift: Expected 9 or 12 saw "+shift}blob.chk("0600","Mini Sector Shift: ");blob.chk("000000000000","Reserved: ")}function sectorify(file,ssz){var nsectors=Math.ceil(file.length/ssz)-1;var sectors=new Array(nsectors);for(var i=1;i<nsectors;++i)sectors[i-1]=file.slice(i*ssz,(i+1)*ssz);sectors[nsectors-1]=file.slice(nsectors*ssz);return sectors}function build_full_paths(FI,FPD,FP,Paths){var i=0,L=0,R=0,C=0,j=0,pl=Paths.length;var dad=new Array(pl),q=new Array(pl);for(;i<pl;++i){dad[i]=q[i]=i;FP[i]=Paths[i]}for(;j<q.length;++j){i=q[j];L=FI[i].L;R=FI[i].R;C=FI[i].C;if(dad[i]===i){if(L!==-1&&dad[L]!==L)dad[i]=dad[L];if(R!==-1&&dad[R]!==R)dad[i]=dad[R]}if(C!==-1)dad[C]=i;if(L!==-1){dad[L]=dad[i];q.push(L)}if(R!==-1){dad[R]=dad[i];q.push(R)}}for(i=1;i!==pl;++i)if(dad[i]===i){if(R!==-1&&dad[R]!==R)dad[i]=dad[R];else if(L!==-1&&dad[L]!==L)dad[i]=dad[L]}for(i=1;i<pl;++i){if(FI[i].type===0)continue;j=dad[i];if(j===0)FP[i]=FP[0]+"/"+FP[i];else while(j!==0){FP[i]=FP[j]+"/"+FP[i];j=dad[j]}dad[i]=0}FP[0]+="/";for(i=1;i<pl;++i){if(FI[i].type!==2)FP[i]+="/";FPD[FP[i]]=FI[i]}}function make_find_path(FullPaths,Paths,FileIndex,files,root_name){var UCFullPaths=new Array(FullPaths.length);var UCPaths=new Array(Paths.length),i;for(i=0;i<FullPaths.length;++i)UCFullPaths[i]=FullPaths[i].toUpperCase();for(i=0;i<Paths.length;++i)UCPaths[i]=Paths[i].toUpperCase();return function find_path(path){var k;if(path.charCodeAt(0)===47){k=true;path=root_name+path}else k=path.indexOf("/")!==-1;var UCPath=path.toUpperCase();var w=k===true?UCFullPaths.indexOf(UCPath):UCPaths.indexOf(UCPath);if(w===-1)return null;return k===true?FileIndex[w]:files[Paths[w]]}}function sleuth_fat(idx,cnt,sectors,ssz,fat_addrs){var q;if(idx===ENDOFCHAIN){if(cnt!==0)throw"DIFAT chain shorter than expected"}else if(idx!==-1){var sector=sectors[idx],m=(ssz>>>2)-1;for(var i=0;i<m;++i){if((q=__readInt32LE(sector,i*4))===ENDOFCHAIN)break;fat_addrs.push(q)}sleuth_fat(__readInt32LE(sector,ssz-4),cnt-1,sectors,ssz,fat_addrs)}}function make_sector_list(sectors,dir_start,fat_addrs,ssz){var sl=sectors.length,sector_list=new Array(sl);var chkd=new Array(sl),buf,buf_chain;var modulus=ssz-1,i,j,k,jj;for(i=0;i<sl;++i){buf=[];k=i+dir_start;if(k>=sl)k-=sl;if(chkd[k]===true)continue;buf_chain=[];for(j=k;j>=0;){chkd[j]=true;buf[buf.length]=j;buf_chain.push(sectors[j]);var addr=fat_addrs[Math.floor(j*4/ssz)];jj=j*4&modulus;if(ssz<4+jj)throw"FAT boundary crossed: "+j+" 4 "+ssz;j=__readInt32LE(sectors[addr],jj)}sector_list[k]={nodes:buf,data:__toBuffer([buf_chain])}}return sector_list}function read_directory(dir_start,sector_list,sectors,Paths,nmfs,files,FileIndex){var blob;var minifat_store=0,pl=Paths.length?2:0;var sector=sector_list[dir_start].data;var i=0,namelen=0,name,o,ctime,mtime;for(;i<sector.length;i+=128){blob=sector.slice(i,i+128);prep_blob(blob,64);namelen=blob.read_shift(2);if(namelen===0)continue;name=__utf16le(blob,0,namelen-pl);Paths.push(name);o={name:name,type:blob.read_shift(1),color:blob.read_shift(1),L:blob.read_shift(4,"i"),R:blob.read_shift(4,"i"),C:blob.read_shift(4,"i"),clsid:blob.read_shift(16),state:blob.read_shift(4,"i")};ctime=blob.read_shift(2)+blob.read_shift(2)+blob.read_shift(2)+blob.read_shift(2);if(ctime!==0){o.ctime=ctime;o.ct=read_date(blob,blob.l-8)}mtime=blob.read_shift(2)+blob.read_shift(2)+blob.read_shift(2)+blob.read_shift(2);if(mtime!==0){o.mtime=mtime;o.mt=read_date(blob,blob.l-8)}o.start=blob.read_shift(4,"i");o.size=blob.read_shift(4,"i");if(o.type===5){minifat_store=o.start;if(nmfs>0&&minifat_store!==ENDOFCHAIN)sector_list[minifat_store].name="!StreamData"}else if(o.size>=4096){o.storage="fat";if(sector_list[o.start]===undefined)if((o.start+=dir_start)>=sectors.length)o.start-=sectors.length;sector_list[o.start].name=o.name;o.content=sector_list[o.start].data.slice(0,o.size);prep_blob(o.content,0)}else{o.storage="minifat";if(minifat_store!==ENDOFCHAIN&&o.start!==ENDOFCHAIN){o.content=sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size);prep_blob(o.content,0)}}files[name]=o;FileIndex.push(o)}}function read_date(blob,offset){return new Date((__readUInt32LE(blob,offset+4)/1e7*Math.pow(2,32)+__readUInt32LE(blob,offset)/1e7-11644473600)*1e3)}var fs;function readFileSync(filename){if(fs===undefined)fs=require("fs");return parse(fs.readFileSync(filename))}function readSync(blob,options){switch(options!==undefined&&options.type!==undefined?options.type:"base64"){case"file":return readFileSync(blob);case"base64":return parse(s2a(Base64.decode(blob)));case"binary":return parse(s2a(blob))}return parse(blob)}var MSSZ=64;var ENDOFCHAIN=-2;var HEADER_SIGNATURE="d0cf11e0a1b11ae1";var HEADER_CLSID="00000000000000000000000000000000";var consts={MAXREGSECT:-6,DIFSECT:-4,FATSECT:-3,ENDOFCHAIN:ENDOFCHAIN,FREESECT:-1,HEADER_SIGNATURE:HEADER_SIGNATURE,HEADER_MINOR_VERSION:"3e00",MAXREGSID:-6,NOSTREAM:-1,HEADER_CLSID:HEADER_CLSID,EntryTypes:["unknown","storage","stream","lockbytes","property","root"]};exports.read=readSync;exports.parse=parse;exports.utils={ReadShift:ReadShift,CheckField:CheckField,prep_blob:prep_blob,bconcat:bconcat,consts:consts};return exports}();if(typeof require!=="undefined"&&typeof module!=="undefined"&&typeof DO_NOT_EXPORT_CFB==="undefined"){module.exports=CFB} | ||
//# sourceMappingURL=dist/cfb.min.map |
{ | ||
"name": "cfb", | ||
"version": "0.10.0", | ||
"author": "sheetjs", | ||
"description": "Compound File Binary File Format extractor", | ||
"keywords": [ "cfb", "compression", "office" ], | ||
"bin": { | ||
"cfb": "./bin/cfb" | ||
}, | ||
"main": "./cfb", | ||
"dependencies": { | ||
"commander":"" | ||
}, | ||
"devDependencies": { | ||
"mocha":"", | ||
"xlsjs":"", | ||
"uglify-js":"" | ||
}, | ||
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-cfb.git" }, | ||
"scripts": { | ||
"pretest": "make init", | ||
"test": "make test" | ||
}, | ||
"config": { | ||
"blanket": { | ||
"pattern": "cfb.js" | ||
} | ||
}, | ||
"bugs": { "url": "https://github.com/SheetJS/js-cfb/issues" }, | ||
"license": "Apache-2.0", | ||
"engines": { "node": ">=0.8" } | ||
"name": "cfb", | ||
"version": "0.10.1", | ||
"author": "sheetjs", | ||
"description": "Compound File Binary File Format extractor", | ||
"keywords": [ "cfb", "compression", "office" ], | ||
"bin": { | ||
"cfb": "./bin/cfb" | ||
}, | ||
"main": "./cfb", | ||
"files": [ | ||
"LICENSE", | ||
"README.md", | ||
"bin/", | ||
"dist/", | ||
"cfb.js" | ||
], | ||
"dependencies": { | ||
"commander":"" | ||
}, | ||
"devDependencies": { | ||
"mocha":"", | ||
"xlsjs":"", | ||
"uglify-js":"" | ||
}, | ||
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-cfb.git" }, | ||
"scripts": { | ||
"pretest": "make init", | ||
"test": "make test" | ||
}, | ||
"config": { | ||
"blanket": { | ||
"pattern": "cfb.js" | ||
} | ||
}, | ||
"bugs": { "url": "https://github.com/SheetJS/js-cfb/issues" }, | ||
"license": "Apache-2.0", | ||
"engines": { "node": ">=0.8" } | ||
} |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
3
56570
9
796
1