From ec9ab571320f408fc9b5f6e367d20357bdb2b4be Mon Sep 17 00:00:00 2001 From: SheetJS Date: Sat, 4 Nov 2017 20:15:50 -0400 Subject: [PATCH] version bump 0.14.0: removed FullPathDir - CLI tool properly handles empty files - node 9 added to travis --- .travis.yml | 2 +- CHANGELOG.md | 10 ++++++++++ bin/cfb.njs | 2 +- bits/31_version.js | 2 +- bits/40_parse.js | 7 +++---- bits/43_rbtree.js | 3 +-- cfb.flow.js | 12 +++++------- cfb.js | 12 +++++------- dist/cfb.js | 12 +++++------- dist/cfb.min.js | 2 +- dist/cfb.min.map | 2 +- dist/xlscfb.js | 12 +++++------- misc/flow.js | 5 ----- package.json | 2 +- types/index.d.ts | 11 ----------- xlscfb.flow.js | 12 +++++------- xlscfb.js | 12 +++++------- 17 files changed, 50 insertions(+), 70 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.travis.yml b/.travis.yml index 6871faf..a50105e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: node_js node_js: + - "9" - "8" - "7" - "6" @@ -7,7 +8,6 @@ node_js: - "4" - "0.12" - "0.10" - - "0.9" - "0.8" before_install: - "npm install -g npm@4.3.0" diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d236aeb --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# CHANGELOG + +This log is intended to keep track of backwards-incompatible changes, including +but not limited to API changes and file location changes. Minor behavioral +changes may not be included if they are not expected to break existing code. + +## 0.14.0 (2017-11-04) + +* Completely removed `FullPathDir` + diff --git a/bin/cfb.njs b/bin/cfb.njs index eb9ebc3..72d6df2 100755 --- a/bin/cfb.njs +++ b/bin/cfb.njs @@ -88,7 +88,7 @@ function mkdirp(path/*:string*/) { path.split("/").reduce(function(acc/*:string* function write(path/*:string*/, data/*:CFBEntry*/) { logit("write", fix_string(path)); - fs.writeFileSync(path, /*::new Buffer((*/data.content/*:: :any))*/); + fs.writeFileSync(path, /*::new Buffer((*/data.content/*:: :any))*/ || new Buffer(0)); } if(program.create || program.append) { diff --git a/bits/31_version.js b/bits/31_version.js index 726dd00..b87138e 100644 --- a/bits/31_version.js +++ b/bits/31_version.js @@ -1 +1 @@ -exports.version = '0.13.2'; +exports.version = '0.14.0'; diff --git a/bits/40_parse.js b/bits/40_parse.js index 961c10e..a583e5f 100644 --- a/bits/40_parse.js +++ b/bits/40_parse.js @@ -78,16 +78,15 @@ sector_list.fat_addrs = fat_addrs; sector_list.ssz = ssz; /* [MS-CFB] 2.6.1 Compound File Directory Entry */ -var files/*:CFBFiles*/ = {}, Paths/*:Array*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array*/ = [], FullPathDir = {}; +var files/*:CFBFiles*/ = {}, Paths/*:Array*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array*/ = []; read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); -build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); +build_full_paths(FileIndex, FullPaths, Paths); Paths.shift(); var o = { FileIndex: FileIndex, - FullPaths: FullPaths, - FullPathDir: FullPathDir + FullPaths: FullPaths }; // $FlowIgnore diff --git a/bits/43_rbtree.js b/bits/43_rbtree.js index 51f0414..7e95175 100644 --- a/bits/43_rbtree.js +++ b/bits/43_rbtree.js @@ -1,5 +1,5 @@ /* [MS-CFB] 2.6.4 Red-Black Tree */ -function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Array*/, Paths/*:Array*/)/*:void*/ { +function build_full_paths(FI/*:CFBFileIndex*/, FP/*:Array*/, Paths/*:Array*/)/*:void*/ { var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; var dad/*:Array*/ = [], q/*:Array*/ = []; @@ -35,7 +35,6 @@ function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Arra FP[0] += "/"; for(i=1; i < pl; ++i) { if(FI[i].type !== 2 /* stream */) FP[i] += "/"; - FPD[FP[i]] = FI[i]; } } diff --git a/cfb.flow.js b/cfb.flow.js index 1f01792..8318ff5 100644 --- a/cfb.flow.js +++ b/cfb.flow.js @@ -179,7 +179,7 @@ type CFBFiles = {[n:string]:CFBEntry}; /* [MS-CFB] v20130118 */ var CFB = (function _CFB(){ var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/; -exports.version = '0.13.2'; +exports.version = '0.14.0'; /* [MS-CFB] 2.6.4 */ function namecmp(l/*:string*/, r/*:string*/)/*:number*/ { var L = l.split("/"), R = r.split("/"); @@ -282,16 +282,15 @@ sector_list.fat_addrs = fat_addrs; sector_list.ssz = ssz; /* [MS-CFB] 2.6.1 Compound File Directory Entry */ -var files/*:CFBFiles*/ = {}, Paths/*:Array*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array*/ = [], FullPathDir = {}; +var files/*:CFBFiles*/ = {}, Paths/*:Array*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array*/ = []; read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); -build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); +build_full_paths(FileIndex, FullPaths, Paths); Paths.shift(); var o = { FileIndex: FileIndex, - FullPaths: FullPaths, - FullPathDir: FullPathDir + FullPaths: FullPaths }; // $FlowIgnore @@ -343,7 +342,7 @@ function sectorify(file/*:RawBytes*/, ssz/*:number*/)/*:Array*/ { } /* [MS-CFB] 2.6.4 Red-Black Tree */ -function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Array*/, Paths/*:Array*/)/*:void*/ { +function build_full_paths(FI/*:CFBFileIndex*/, FP/*:Array*/, Paths/*:Array*/)/*:void*/ { var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; var dad/*:Array*/ = [], q/*:Array*/ = []; @@ -379,7 +378,6 @@ function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Arra FP[0] += "/"; for(i=1; i < pl; ++i) { if(FI[i].type !== 2 /* stream */) FP[i] += "/"; - FPD[FP[i]] = FI[i]; } } diff --git a/cfb.js b/cfb.js index 393e7df..f5a33b5 100644 --- a/cfb.js +++ b/cfb.js @@ -161,7 +161,7 @@ function new_buf(sz) { /* [MS-CFB] v20130118 */ var CFB = (function _CFB(){ var exports = {}; -exports.version = '0.13.2'; +exports.version = '0.14.0'; /* [MS-CFB] 2.6.4 */ function namecmp(l, r) { var L = l.split("/"), R = r.split("/"); @@ -264,16 +264,15 @@ sector_list.fat_addrs = fat_addrs; sector_list.ssz = ssz; /* [MS-CFB] 2.6.1 Compound File Directory Entry */ -var files = {}, Paths = [], FileIndex = [], FullPaths = [], FullPathDir = {}; +var files = {}, Paths = [], FileIndex = [], FullPaths = []; read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); -build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); +build_full_paths(FileIndex, FullPaths, Paths); Paths.shift(); var o = { FileIndex: FileIndex, - FullPaths: FullPaths, - FullPathDir: FullPathDir + FullPaths: FullPaths }; // $FlowIgnore @@ -325,7 +324,7 @@ function sectorify(file, ssz) { } /* [MS-CFB] 2.6.4 Red-Black Tree */ -function build_full_paths(FI, FPD, FP, Paths) { +function build_full_paths(FI, FP, Paths) { var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; var dad = [], q = []; @@ -361,7 +360,6 @@ function build_full_paths(FI, FPD, FP, Paths) { FP[0] += "/"; for(i=1; i < pl; ++i) { if(FI[i].type !== 2 /* stream */) FP[i] += "/"; - FPD[FP[i]] = FI[i]; } } diff --git a/dist/cfb.js b/dist/cfb.js index 393e7df..f5a33b5 100644 --- a/dist/cfb.js +++ b/dist/cfb.js @@ -161,7 +161,7 @@ function new_buf(sz) { /* [MS-CFB] v20130118 */ var CFB = (function _CFB(){ var exports = {}; -exports.version = '0.13.2'; +exports.version = '0.14.0'; /* [MS-CFB] 2.6.4 */ function namecmp(l, r) { var L = l.split("/"), R = r.split("/"); @@ -264,16 +264,15 @@ sector_list.fat_addrs = fat_addrs; sector_list.ssz = ssz; /* [MS-CFB] 2.6.1 Compound File Directory Entry */ -var files = {}, Paths = [], FileIndex = [], FullPaths = [], FullPathDir = {}; +var files = {}, Paths = [], FileIndex = [], FullPaths = []; read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); -build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); +build_full_paths(FileIndex, FullPaths, Paths); Paths.shift(); var o = { FileIndex: FileIndex, - FullPaths: FullPaths, - FullPathDir: FullPathDir + FullPaths: FullPaths }; // $FlowIgnore @@ -325,7 +324,7 @@ function sectorify(file, ssz) { } /* [MS-CFB] 2.6.4 Red-Black Tree */ -function build_full_paths(FI, FPD, FP, Paths) { +function build_full_paths(FI, FP, Paths) { var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; var dad = [], q = []; @@ -361,7 +360,6 @@ function build_full_paths(FI, FPD, FP, Paths) { FP[0] += "/"; for(i=1; i < pl; ++i) { if(FI[i].type !== 2 /* stream */) FP[i] += "/"; - FPD[FP[i]] = FI[i]; } } diff --git a/dist/cfb.min.js b/dist/cfb.min.js index a5c553d..ea8cc40 100644 --- a/dist/cfb.min.js +++ b/dist/cfb.min.js @@ -1,2 +1,2 @@ /* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ -var Base64=function e(){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{encode:function(r){var t="";var i,n,a;var f,s,h,l;for(var o=0;o>2;n=r.charCodeAt(o++);s=(i&3)<<4|n>>4;a=r.charCodeAt(o++);h=(n&15)<<2|a>>6;l=a&63;if(isNaN(n)){h=l=64}else if(isNaN(a)){l=64}t+=e.charAt(f)+e.charAt(s)+e.charAt(h)+e.charAt(l)}return t},decode:function r(t){var i="";var n,a,f;var s,h,l,o;t=t.replace(/[^\w\+\/\=]/g,"");for(var c=0;c>4;i+=String.fromCharCode(n);l=e.indexOf(t.charAt(c++));a=(h&15)<<4|l>>2;if(l!==64){i+=String.fromCharCode(a)}o=e.indexOf(t.charAt(c++));f=(l&3)<<6|o;if(o!==64){i+=String.fromCharCode(f)}}return i}}}();var has_buf=typeof Buffer!=="undefined"&&typeof process!=="undefined"&&typeof process.versions!=="undefined"&&process.versions.node;function new_raw_buf(e){return new(has_buf?Buffer:Array)(e)}var s2a=function r(e){if(has_buf)return new Buffer(e,"binary");return e.split("").map(function(e){return e.charCodeAt(0)&255})};var chr0=/\u0000/g,chr1=/[\u0001-\u0006]/;var __toBuffer=function(e){var r=[];for(var t=0;t0&&Buffer.isBuffer(e[0][0])?Buffer.concat(e[0]):___toBuffer(e)};s2a=function(e){return new Buffer(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>8}while(this.l>>=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="0.13.2";function r(e,r){var t=e.split("/"),i=r.split("/");for(var n=0,a=0,f=Math.min(t.length,i.length);n0&&u!==C)y[u].name="!MiniFAT";y[w[0]].name="!FAT";y.fat_addrs=w;y.ssz=i;var S={},A=[],m=[],B=[],k={};d(f,y,E,A,n,S,m);o(m,k,B,A);A.shift();var L={FileIndex:m,FullPaths:B,FullPathDir:k};if(r&&r.raw)L.raw={header:g,sectors:E};return L}function s(e){e.chk(y,"Header Signature: ");e.chk(A,"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>>2)-1;if(!f)return;for(var h=0;h=0;){n[h]=true;a[a.length]=h;f.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:a,data:__toBuffer([f])}}function _(e,r,t,i){var n=e.length,a=[];var f=[],s=[],h=[];var l=i-1,o=0,c=0,u=0,_=0;for(o=0;o=n)u-=n;if(f[u])continue;h=[];for(c=u;c>=0;){f[c]=true;s[s.length]=c;h.push(e[c]);var d=t[Math.floor(c*4/i)];_=c*4&l;if(i<4+_)throw new Error("FAT boundary crossed: "+c+" 4 "+i);if(!e[d])break;c=__readInt32LE(e[d],_)}a[u]={nodes:s,data:__toBuffer([h])}}return a}function d(e,r,t,i,n,a,f){var s=0,h=i.length?2:0;var l=r[e].data;var o=0,c=0,_;for(;o0&&s!==C)r[s].name="!StreamData"}else if(w.size>=4096){w.storage="fat";if(r[w.start]===undefined)r[w.start]=u(t,w.start,r.fat_addrs,r.ssz);r[w.start].name=w.name;w.content=r[w.start].data.slice(0,w.size);prep_blob(w.content,0)}else{w.storage="minifat";if(s!==C&&w.start!==C&&r[s]){w.content=r[s].data.slice(w.start*E,w.start*E+w.size);prep_blob(w.content,0)}}a[_]=w;f.push(w)}}function v(e,r){return new Date((__readUInt32LE(e,r+4)/1e7*Math.pow(2,32)+__readUInt32LE(e,r)/1e7-11644473600)*1e3)}function w(e,r){a();return f(n.readFileSync(e),r)}function p(e,r){switch(r&&r.type||"base64"){case"file":return w(e,r);case"base64":return f(s2a(Base64.decode(e)),r);case"binary":return f(s2a(e),r);}return f(e,r)}function F(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;g(e)}function g(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);I(e)}function I(e,n){F(e);var a=false,f=false;for(var s=e.FullPaths.length-1;s>=0;--s){var h=e.FileIndex[s];switch(h.type){case 0:if(f)a=true;else{e.FileIndex.pop();e.FullPaths.pop()}break;case 1:;case 2:;case 5:f=true;if(isNaN(h.R*h.L*h.C))a=true;if(h.R>-1&&h.L>-1&&h.R==h.L)a=true;break;default:a=true;break;}}if(!a&&!n)return;var l=new Date(1987,1,19),o=0;var c=[];for(s=0;s1?1:-1;_.size=0;_.type=5}else if(d.slice(-1)=="/"){for(o=s+1;o=c.length?-1:o;for(o=s+1;o=c.length?-1:o;_.type=1}else{if(t(e.FullPaths[s+1]||"")==t(d))_.R=s+1;_.type=2}}}function b(e,r){I(e);var t=function(e){var r=0,t=0;for(var i=0;i>6;else t+=a+511>>9}var f=e.FullPaths.length+3>>2;var s=r+7>>3;var h=r+127>>7;var l=s+t+f+h;var o=l+127>>7;var c=o<=109?0:Math.ceil((o-109)/127);while(l+o+c+127>>7>o)c=++o<=109?0:Math.ceil((o-109)/127);var u=[1,c,o,h,f,t,r,0];e.FileIndex[0].size=r<<6;u[7]=(e.FileIndex[0].start=u[0]+u[1]+u[2]+u[3]+u[4]+u[5])+(u[6]+7>>3);return u}(e);var i=new_buf(t[7]<<9);var n=0,a=0;{for(n=0;n<8;++n)i.write_shift(1,S[n]);for(n=0;n<8;++n)i.write_shift(2,0);i.write_shift(2,62);i.write_shift(2,3);i.write_shift(2,65534);i.write_shift(2,9);i.write_shift(2,6);for(n=0;n<3;++n)i.write_shift(2,0);i.write_shift(4,0);i.write_shift(4,t[2]);i.write_shift(4,t[0]+t[1]+t[2]+t[3]-1);i.write_shift(4,0);i.write_shift(4,1<<12);i.write_shift(4,t[3]?t[0]+t[1]+t[2]-1:C);i.write_shift(4,t[3]);i.write_shift(-4,t[1]?t[0]-1:C);i.write_shift(4,t[1]);for(n=0;n<109;++n)i.write_shift(-4,n>9)}f(t[6]+7>>3);while(i.l&511)i.write_shift(-4,m.ENDOFCHAIN);a=n=0;for(s=0;s=4096)continue;l.start=a;f(h+63>>6)}while(i.l&511)i.write_shift(-4,m.ENDOFCHAIN);for(n=0;n=4096){i.l=l.start+1<<9;for(s=0;s0&&l.size<4096){for(s=0;s>2;n=r.charCodeAt(o++);s=(i&3)<<4|n>>4;a=r.charCodeAt(o++);h=(n&15)<<2|a>>6;l=a&63;if(isNaN(n)){h=l=64}else if(isNaN(a)){l=64}t+=e.charAt(f)+e.charAt(s)+e.charAt(h)+e.charAt(l)}return t},decode:function r(t){var i="";var n,a,f;var s,h,l,o;t=t.replace(/[^\w\+\/\=]/g,"");for(var c=0;c>4;i+=String.fromCharCode(n);l=e.indexOf(t.charAt(c++));a=(h&15)<<4|l>>2;if(l!==64){i+=String.fromCharCode(a)}o=e.indexOf(t.charAt(c++));f=(l&3)<<6|o;if(o!==64){i+=String.fromCharCode(f)}}return i}}}();var has_buf=typeof Buffer!=="undefined"&&typeof process!=="undefined"&&typeof process.versions!=="undefined"&&process.versions.node;function new_raw_buf(e){return new(has_buf?Buffer:Array)(e)}var s2a=function r(e){if(has_buf)return new Buffer(e,"binary");return e.split("").map(function(e){return e.charCodeAt(0)&255})};var chr0=/\u0000/g,chr1=/[\u0001-\u0006]/;var __toBuffer=function(e){var r=[];for(var t=0;t0&&Buffer.isBuffer(e[0][0])?Buffer.concat(e[0]):___toBuffer(e)};s2a=function(e){return new Buffer(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>8}while(this.l>>=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="0.14.0";function r(e,r){var t=e.split("/"),i=r.split("/");for(var n=0,a=0,f=Math.min(t.length,i.length);n0&&u!==C)y[u].name="!MiniFAT";y[w[0]].name="!FAT";y.fat_addrs=w;y.ssz=i;var S={},A=[],m=[],B=[];d(f,y,E,A,n,S,m);o(m,B,A);A.shift();var k={FileIndex:m,FullPaths:B};if(r&&r.raw)k.raw={header:g,sectors:E};return k}function s(e){e.chk(y,"Header Signature: ");e.chk(A,"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>>2)-1;if(!f)return;for(var h=0;h=0;){n[h]=true;a[a.length]=h;f.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:a,data:__toBuffer([f])}}function _(e,r,t,i){var n=e.length,a=[];var f=[],s=[],h=[];var l=i-1,o=0,c=0,u=0,_=0;for(o=0;o=n)u-=n;if(f[u])continue;h=[];for(c=u;c>=0;){f[c]=true;s[s.length]=c;h.push(e[c]);var d=t[Math.floor(c*4/i)];_=c*4&l;if(i<4+_)throw new Error("FAT boundary crossed: "+c+" 4 "+i);if(!e[d])break;c=__readInt32LE(e[d],_)}a[u]={nodes:s,data:__toBuffer([h])}}return a}function d(e,r,t,i,n,a,f){var s=0,h=i.length?2:0;var l=r[e].data;var o=0,c=0,_;for(;o0&&s!==C)r[s].name="!StreamData"}else if(w.size>=4096){w.storage="fat";if(r[w.start]===undefined)r[w.start]=u(t,w.start,r.fat_addrs,r.ssz);r[w.start].name=w.name;w.content=r[w.start].data.slice(0,w.size);prep_blob(w.content,0)}else{w.storage="minifat";if(s!==C&&w.start!==C&&r[s]){w.content=r[s].data.slice(w.start*E,w.start*E+w.size);prep_blob(w.content,0)}}a[_]=w;f.push(w)}}function v(e,r){return new Date((__readUInt32LE(e,r+4)/1e7*Math.pow(2,32)+__readUInt32LE(e,r)/1e7-11644473600)*1e3)}function w(e,r){a();return f(n.readFileSync(e),r)}function p(e,r){switch(r&&r.type||"base64"){case"file":return w(e,r);case"base64":return f(s2a(Base64.decode(e)),r);case"binary":return f(s2a(e),r);}return f(e,r)}function F(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;g(e)}function g(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);I(e)}function I(e,n){F(e);var a=false,f=false;for(var s=e.FullPaths.length-1;s>=0;--s){var h=e.FileIndex[s];switch(h.type){case 0:if(f)a=true;else{e.FileIndex.pop();e.FullPaths.pop()}break;case 1:;case 2:;case 5:f=true;if(isNaN(h.R*h.L*h.C))a=true;if(h.R>-1&&h.L>-1&&h.R==h.L)a=true;break;default:a=true;break;}}if(!a&&!n)return;var l=new Date(1987,1,19),o=0;var c=[];for(s=0;s1?1:-1;_.size=0;_.type=5}else if(d.slice(-1)=="/"){for(o=s+1;o=c.length?-1:o;for(o=s+1;o=c.length?-1:o;_.type=1}else{if(t(e.FullPaths[s+1]||"")==t(d))_.R=s+1;_.type=2}}}function b(e,r){I(e);var t=function(e){var r=0,t=0;for(var i=0;i>6;else t+=a+511>>9}var f=e.FullPaths.length+3>>2;var s=r+7>>3;var h=r+127>>7;var l=s+t+f+h;var o=l+127>>7;var c=o<=109?0:Math.ceil((o-109)/127);while(l+o+c+127>>7>o)c=++o<=109?0:Math.ceil((o-109)/127);var u=[1,c,o,h,f,t,r,0];e.FileIndex[0].size=r<<6;u[7]=(e.FileIndex[0].start=u[0]+u[1]+u[2]+u[3]+u[4]+u[5])+(u[6]+7>>3);return u}(e);var i=new_buf(t[7]<<9);var n=0,a=0;{for(n=0;n<8;++n)i.write_shift(1,S[n]);for(n=0;n<8;++n)i.write_shift(2,0);i.write_shift(2,62);i.write_shift(2,3);i.write_shift(2,65534);i.write_shift(2,9);i.write_shift(2,6);for(n=0;n<3;++n)i.write_shift(2,0);i.write_shift(4,0);i.write_shift(4,t[2]);i.write_shift(4,t[0]+t[1]+t[2]+t[3]-1);i.write_shift(4,0);i.write_shift(4,1<<12);i.write_shift(4,t[3]?t[0]+t[1]+t[2]-1:C);i.write_shift(4,t[3]);i.write_shift(-4,t[1]?t[0]-1:C);i.write_shift(4,t[1]);for(n=0;n<109;++n)i.write_shift(-4,n>9)}f(t[6]+7>>3);while(i.l&511)i.write_shift(-4,m.ENDOFCHAIN);a=n=0;for(s=0;s=4096)continue;l.start=a;f(h+63>>6)}while(i.l&511)i.write_shift(-4,m.ENDOFCHAIN);for(n=0;n=4096){i.l=l.start+1<<9;for(s=0;s0&&l.size<4096){for(s=0;s*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array*/ = [], FullPathDir = {}; +var files/*:CFBFiles*/ = {}, Paths/*:Array*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array*/ = []; read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); -build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); +build_full_paths(FileIndex, FullPaths, Paths); Paths.shift(); var o = { FileIndex: FileIndex, - FullPaths: FullPaths, - FullPathDir: FullPathDir + FullPaths: FullPaths }; // $FlowIgnore @@ -202,7 +201,7 @@ function sectorify(file/*:RawBytes*/, ssz/*:number*/)/*:Array*/ { } /* [MS-CFB] 2.6.4 Red-Black Tree */ -function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Array*/, Paths/*:Array*/)/*:void*/ { +function build_full_paths(FI/*:CFBFileIndex*/, FP/*:Array*/, Paths/*:Array*/)/*:void*/ { var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; var dad/*:Array*/ = [], q/*:Array*/ = []; @@ -238,7 +237,6 @@ function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Arra FP[0] += "/"; for(i=1; i < pl; ++i) { if(FI[i].type !== 2 /* stream */) FP[i] += "/"; - FPD[FP[i]] = FI[i]; } } diff --git a/misc/flow.js b/misc/flow.js index fd2c8dd..87ec703 100644 --- a/misc/flow.js +++ b/misc/flow.js @@ -10,10 +10,6 @@ type CFBModule = { utils:CFBUtils; }; -type CFBFullPathDir = { - [n:string]: CFBEntry; -} - type CFBUtils = any; type ReadShiftFunc = { @@ -80,7 +76,6 @@ type CFBContainer = { sectors:Array; }; FileIndex:CFBFileIndex; - FullPathDir:CFBFullPathDir; FullPaths:Array; } diff --git a/package.json b/package.json index 7b1a136..332b952 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cfb", - "version": "0.13.2", + "version": "0.14.0", "author": "sheetjs", "description": "Compound File Binary File Format extractor", "keywords": [ "cfb", "compression", "office" ], diff --git a/types/index.d.ts b/types/index.d.ts index 6cfb4a0..cd5aef9 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -74,22 +74,11 @@ export interface CFBEntry { storage?: string; } - -/* cfb.FullPathDir Directory object */ -export interface CFBDirectory { - /* cfb.FullPathDir keys are paths; cfb.Directory keys are file names */ - [key: string]: CFBEntry; -} - - /* File object */ export interface CFBContainer { /* list of streams and storages */ FullPaths: string[]; - /* Path -> CFB object mapping */ - FullPathDir: CFBDirectory; - /* Array of entries in the same order as FullPaths */ FileIndex: CFBEntry[]; diff --git a/xlscfb.flow.js b/xlscfb.flow.js index c46d5ab..3c079d6 100644 --- a/xlscfb.flow.js +++ b/xlscfb.flow.js @@ -38,7 +38,7 @@ type CFBFiles = {[n:string]:CFBEntry}; /* [MS-CFB] v20130118 */ var CFB = (function _CFB(){ var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/; -exports.version = '0.13.2'; +exports.version = '0.14.0'; /* [MS-CFB] 2.6.4 */ function namecmp(l/*:string*/, r/*:string*/)/*:number*/ { var L = l.split("/"), R = r.split("/"); @@ -141,16 +141,15 @@ sector_list.fat_addrs = fat_addrs; sector_list.ssz = ssz; /* [MS-CFB] 2.6.1 Compound File Directory Entry */ -var files/*:CFBFiles*/ = {}, Paths/*:Array*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array*/ = [], FullPathDir = {}; +var files/*:CFBFiles*/ = {}, Paths/*:Array*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array*/ = []; read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); -build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); +build_full_paths(FileIndex, FullPaths, Paths); Paths.shift(); var o = { FileIndex: FileIndex, - FullPaths: FullPaths, - FullPathDir: FullPathDir + FullPaths: FullPaths }; // $FlowIgnore @@ -202,7 +201,7 @@ function sectorify(file/*:RawBytes*/, ssz/*:number*/)/*:Array*/ { } /* [MS-CFB] 2.6.4 Red-Black Tree */ -function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Array*/, Paths/*:Array*/)/*:void*/ { +function build_full_paths(FI/*:CFBFileIndex*/, FP/*:Array*/, Paths/*:Array*/)/*:void*/ { var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; var dad/*:Array*/ = [], q/*:Array*/ = []; @@ -238,7 +237,6 @@ function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Arra FP[0] += "/"; for(i=1; i < pl; ++i) { if(FI[i].type !== 2 /* stream */) FP[i] += "/"; - FPD[FP[i]] = FI[i]; } } diff --git a/xlscfb.js b/xlscfb.js index 9055e9c..3ccbaaf 100644 --- a/xlscfb.js +++ b/xlscfb.js @@ -8,7 +8,7 @@ var DO_NOT_EXPORT_CFB = true; /* [MS-CFB] v20130118 */ var CFB = (function _CFB(){ var exports = {}; -exports.version = '0.13.2'; +exports.version = '0.14.0'; /* [MS-CFB] 2.6.4 */ function namecmp(l, r) { var L = l.split("/"), R = r.split("/"); @@ -111,16 +111,15 @@ sector_list.fat_addrs = fat_addrs; sector_list.ssz = ssz; /* [MS-CFB] 2.6.1 Compound File Directory Entry */ -var files = {}, Paths = [], FileIndex = [], FullPaths = [], FullPathDir = {}; +var files = {}, Paths = [], FileIndex = [], FullPaths = []; read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); -build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); +build_full_paths(FileIndex, FullPaths, Paths); Paths.shift(); var o = { FileIndex: FileIndex, - FullPaths: FullPaths, - FullPathDir: FullPathDir + FullPaths: FullPaths }; // $FlowIgnore @@ -172,7 +171,7 @@ function sectorify(file, ssz) { } /* [MS-CFB] 2.6.4 Red-Black Tree */ -function build_full_paths(FI, FPD, FP, Paths) { +function build_full_paths(FI, FP, Paths) { var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; var dad = [], q = []; @@ -208,7 +207,6 @@ function build_full_paths(FI, FPD, FP, Paths) { FP[0] += "/"; for(i=1; i < pl; ++i) { if(FI[i].type !== 2 /* stream */) FP[i] += "/"; - FPD[FP[i]] = FI[i]; } }