Comparing version 0.9.1 to 0.10.0
var Base64 = (function(){ | ||
var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; | ||
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); } | ||
} | ||
@@ -43,73 +28,55 @@ 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(){ | ||
var CFB = (function _CFB(){ | ||
var exports = {}; |
@@ -1,1 +0,1 @@ | ||
this.version = '0.9.1'; | ||
exports.version = '0.10.0'; |
@@ -1,15 +0,12 @@ | ||
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)); | ||
} | ||
@@ -16,0 +13,0 @@ return parse(blob); |
@@ -1,3 +0,11 @@ | ||
this.read = readSync; | ||
this.parse = parse; | ||
return this; | ||
exports.read = readSync; | ||
exports.parse = parse; | ||
exports.utils = { | ||
ReadShift: ReadShift, | ||
CheckField: CheckField, | ||
prep_blob: prep_blob, | ||
bconcat: bconcat, | ||
consts: consts | ||
}; | ||
return exports; |
@@ -1,7 +0,1 @@ | ||
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; | ||
} | ||
if(typeof require !== 'undefined' && typeof module !== 'undefined' && typeof DO_NOT_EXPORT_CFB === 'undefined') { module.exports = CFB; } |
622
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.0'; | ||
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; } |
{ | ||
"name": "cfb", | ||
"version": "0.9.1", | ||
"author": "SheetJS", | ||
"version": "0.10.0", | ||
"author": "sheetjs", | ||
"description": "Compound File Binary File Format extractor", | ||
@@ -11,9 +11,15 @@ "keywords": [ "cfb", "compression", "office" ], | ||
"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" | ||
}, | ||
"dependencies": { | ||
"commander":"" | ||
}, | ||
"config": { | ||
@@ -25,3 +31,4 @@ "blanket": { | ||
"bugs": { "url": "https://github.com/SheetJS/js-cfb/issues" }, | ||
"license": "Apache 2.0" | ||
"license": "Apache-2.0", | ||
"engines": { "node": ">=0.8" } | ||
} |
@@ -78,3 +78,3 @@ # Compound File Binary Format | ||
- `.name` is the (case sensitive) internal name | ||
- `.type` is the type (`stream` for files, `storage` for dirs, `root` for root) | ||
- `.type` is the type (`2 (stream)` for files, `1 (storage)` for dirs, `5 (root)` for root) | ||
- `.content` is a Buffer/Array with the raw content | ||
@@ -94,3 +94,7 @@ - `.ct`/`.mt` are the creation and modification time (if provided in file) | ||
[![Build Status](https://travis-ci.org/SheetJS/js-cfb.svg?branch=master)](https://travis-ci.org/SheetJS/js-cfb) | ||
[![Coverage Status](https://coveralls.io/repos/SheetJS/js-cfb/badge.png?branch=master)](https://coveralls.io/r/SheetJS/js-cfb?branch=master) | ||
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/88c2e1fd637653cd780b3c6d3dcd70ad "githalytics.com")](http://githalytics.com/SheetJS/js-cfb) | ||
12
test.js
@@ -6,6 +6,7 @@ /* vim: set ts=2: */ | ||
var ffunc = function(x){return x.substr(-4)==".xls" && fails.indexOf(x) === -1;}; | ||
var fails = fs.existsSync('./fails.lst') ? fs.readFileSync('./fails.lst', 'utf-8').split("\n") : []; | ||
var files = fs.readdirSync('test_files').filter(function(x){return x.substr(-4)==".xls" && fails.indexOf(x) === -1;}); | ||
var f2011 = fs.readdirSync('test_files/2011').filter(function(x){return x.substr(-4)==".xls" && fails.indexOf(x) === -1;}); | ||
var f2013 = fs.readdirSync('test_files/2013').filter(function(x){return x.substr(-4)==".xls" && fails.indexOf(x) === -1;}); | ||
var files = fs.readdirSync('test_files').filter(ffunc); | ||
var f2011 = fs.readdirSync('test_files/2011').filter(ffunc); | ||
var f2013 = fs.readdirSync('test_files/2013').filter(ffunc); | ||
@@ -23,4 +24,2 @@ var dir = "./test_files/"; | ||
}); | ||
describe(x + ' should ', function() { | ||
}); | ||
} | ||
@@ -58,2 +57,5 @@ | ||
}); | ||
it('should read buffers', function() { | ||
CFB.read(fs.readFileSync(dir + '/' + cp), {type: 'buffer'}); | ||
}); | ||
}); |
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
80789
38
99
7
3
1357