From 1a428c8f5b158fbf1358bf93e26c7dc874fcb547 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Thu, 23 Feb 2017 21:11:45 -0800 Subject: [PATCH] version bump 0.10.3: ignore bad FAT - sector checked before reading (h/t @e12009) See https://github.com/SheetJS/js-xlsx/issues/569 - flow type checking --- .flowconfig | 35 +++ .travis.yml | 7 +- LICENSE | 2 +- Makefile | 123 ++++++----- README.md | 37 ++-- bin/cfb.njs | 6 +- bits/00_header.js | 2 +- bits/08_blob.js | 18 +- bits/10_types.js | 10 + bits/31_version.js | 2 +- bits/40_parse.js | 6 +- bits/44_findpath.js | 2 +- bits/45_readfat.js | 5 +- bits/46_readdir.js | 4 +- bits/49_readutils.js | 4 +- cfb.flow.js | 476 ++++++++++++++++++++++++++++++++++++++++ cfb.js | 13 +- dist/LICENSE | 2 +- dist/cfb.js | 13 +- dist/cfb.min.js | 4 +- dist/cfb.min.map | 2 +- dist/xlscfb.js | 11 +- fails.lst | 3 + index.html | 47 +++- misc/flow.js | 5 + misc/flowdeps.js | 9 + misc/help.sh | 42 ++++ misc/spin.sh | 2 +- misc/suppress_export.js | 14 ++ package.json | 5 +- xlscfb.flow.js | 410 ++++++++++++++++++++++++++++++++++ xlscfb.js | 11 +- 32 files changed, 1212 insertions(+), 120 deletions(-) create mode 100644 .flowconfig create mode 100644 bits/10_types.js create mode 100644 cfb.flow.js create mode 100644 misc/flow.js create mode 100644 misc/flowdeps.js create mode 100755 misc/help.sh create mode 100644 xlscfb.flow.js diff --git a/.flowconfig b/.flowconfig new file mode 100644 index 0000000..99333f7 --- /dev/null +++ b/.flowconfig @@ -0,0 +1,35 @@ +[ignore] +.*/node_modules/.* +.*/dist/.* +.*/test.js + +.*/bits/.* +.*/ctest/.* +.*/misc/.* +.*/perf/.* + +.*/demo/browser.js +.*/shim.js + +.*/odsbits/.* +.*/xlscfb.js +.*/cfb.js +.*/jszip.js +.*/tests/.* +.*/demos/.* + +[include] +cfb.flow.js +xlscfb.flow.js +.*/bin/.*.njs + +[libs] +bits/10_types.js +misc/flow.js +misc/flowdeps.js + +[options] +module.file_ext=.js +module.file_ext=.njs +module.ignore_non_literal_requires=true +suppress_comment= \\(.\\|\n\\)*\\$FlowIgnore diff --git a/.travis.yml b/.travis.yml index ed1b3d7..2425423 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,14 @@ language: node_js node_js: - - "0.11" + - "7" + - "6" + - "5" + - "4" + - "0.12" - "0.10" - "0.8" before_install: + - "npm install -g npm@next" - "npm install -g mocha" - "npm install blanket" - "npm install xlsjs" diff --git a/LICENSE b/LICENSE index 6d41660..a5fc80a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2013-2014 SheetJS +Copyright (C) 2013-present SheetJS Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile index 1fa6e4f..57dc6f8 100644 --- a/Makefile +++ b/Makefile @@ -1,84 +1,58 @@ +SHELL=/bin/bash LIB=cfb FMT=xls doc ppt misc full REQS= ADDONS= AUXTARGETS=xlscfb.js +CMDS=bin/cfb.njs +HTMLLINT=index.html ULIB=$(shell echo $(LIB) | tr a-z A-Z) DEPS=$(sort $(wildcard bits/*.js)) TARGET=$(LIB).js +FLOWTARGET=$(LIB).flow.js +FLOWTGTS=$(TARGET) $(AUXTARGETS) + +## Main Targets .PHONY: all -all: $(TARGET) $(AUXTARGETS) +all: $(TARGET) $(AUXTARGETS) ## Build library and auxiliary scripts -$(TARGET): $(DEPS) +$(FLOWTGTS): %.js : %.flow.js + node -e 'process.stdout.write(require("fs").readFileSync("$<","utf8").replace(/^[ \t]*\/\*[:#][^*]*\*\/\s*(\n)?/gm,"").replace(/\/\*[:#][^*]*\*\//gm,""))' > $@ + +$(FLOWTARGET): $(DEPS) cat $^ | tr -d '\15\32' > $@ bits/31_version.js: package.json echo "exports.version = '"`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`"';" > $@ .PHONY: clean -clean: - rm -f $(TARGET) +clean: ## Remove targets and build artifacts + rm -f $(TARGET) $(FLOWTARGET) .PHONY: clean-data clean-data: rm -fr ./test_files/ ./test_files_pres/ .PHONY: init -init: +init: ## Initial setup for development if [ ! -e test_files ]; then git clone https://github.com/SheetJS/test_files; fi cd test_files; git pull; make if [ ! -e test_files_pres ]; then git clone https://github.com/SheetJS/test_files_pres; fi cd test_files_pres; git pull -.PHONY: test mocha -test mocha: test.js - mocha -R spec -t 20000 - -.PHONY: prof -prof: - cat misc/prof.js test.js > prof.js - node --prof prof.js - -TESTFMT=$(patsubst %,test_%,$(FMT)) -.PHONY: $(TESTFMT) -$(TESTFMT): test_%: - FMTS=$* make test - - -.PHONY: lint -lint: $(TARGET) - jshint --show-non-errors $(TARGET) $(AUXTARGETS) - jscs $(TARGET) $(AUXTARGETS) - -.PHONY: cov cov-spin -cov: misc/coverage.html -cov-spin: - make cov & bash misc/spin.sh $$! - -COVFMT=$(patsubst %,cov_%,$(FMT)) -.PHONY: $(COVFMT) -$(COVFMT): cov_%: - FMTS=$* make cov - -misc/coverage.html: $(TARGET) test.js - mocha --require blanket -R html-cov > $@ - -.PHONY: coveralls coveralls-spin -coveralls: - mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js - -coveralls-spin: - make coveralls & bash misc/spin.sh $$! - .PHONY: dist -dist: dist-deps $(TARGET) +dist: dist-deps $(TARGET) ## Prepare JS files for distribution cp $(TARGET) dist/ cp LICENSE dist/ uglifyjs $(TARGET) -o dist/$(LIB).min.js --source-map dist/$(LIB).min.map --preamble "$$(head -n 1 bits/00_header.js)" misc/strip_sourcemap.sh dist/$(LIB).min.js +.PHONY: dist-deps +dist-deps: xlscfb.js ## Copy dependencies for distribution + cp xlscfb.js dist/xlscfb.js + .PHONY: aux aux: $(AUXTARGETS) @@ -86,9 +60,58 @@ aux: $(AUXTARGETS) xls: xlscfb.js XLSDEPS=misc/suppress_export.js $(filter-out bits/08_blob.js,$(DEPS)) -xlscfb.js: $(XLSDEPS) +xlscfb.flow.js: $(XLSDEPS) ## Build support library cat $^ | tr -d '\15\32' > $@ -.PHONY: dist-deps -dist-deps: xlscfb.js - cp xlscfb.js dist/xlscfb.js + +## Testing + +.PHONY: test mocha +test mocha: test.js $(TARGET) ## Run test suite + mocha -R spec -t 20000 + +#* To run tests for one format, make test_ +TESTFMT=$(patsubst %,test_%,$(FMT)) +.PHONY: $(TESTFMT) +$(TESTFMT): test_%: + FMTS=$* make test + + +## Code Checking + +.PHONY: lint +lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks + @jshint --show-non-errors $(TARGET) $(AUXTARGETS) + @jshint --show-non-errors $(CMDS) + @jshint --show-non-errors package.json + @jshint --show-non-errors --extract=always $(HTMLLINT) + @jscs $(TARGET) $(AUXTARGETS) + +.PHONY: flow +flow: lint ## Run flow checker + @flow check --all --show-all-errors + +.PHONY: cov +cov: misc/coverage.html ## Run coverage test + +#* To run coverage tests for one format, make cov_ +COVFMT=$(patsubst %,cov_%,$(FMT)) +.PHONY: $(COVFMT) +$(COVFMT): cov_%: + FMTS=$* make cov + +misc/coverage.html: $(TARGET) test.js + mocha --require blanket -R html-cov -t 20000 > $@ + +.PHONY: coveralls +coveralls: ## Coverage Test + Send to coveralls.io + mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | node ./node_modules/coveralls/bin/coveralls.js + + +.PHONY: help +help: + @grep -hE '(^[a-zA-Z_-][ a-zA-Z_-]*:.*?|^#[#*])' $(MAKEFILE_LIST) | bash misc/help.sh + +#* To show a spinner, append "-spin" to any target e.g. cov-spin +%-spin: + @make $* & bash misc/spin.sh $$! diff --git a/README.md b/README.md index c2fcb31..cd7c423 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,41 @@ # Compound File Binary Format This is a Pure-JS implementation of MS-CFB: Compound File Binary File Format, a -format used in many Microsoft file types (such as XLS, DOC, and other Microsoft -Office file types). +format used in many Microsoft file types (such as XLS and DOC) # Utility Installation and Usage The package is available on NPM: -``` +```bash $ npm install -g cfb $ cfb path/to/CFB/file ``` The command will extract the storages and streams in the container, generating -files that line up with the tree-based structure of the storage. Metadata -such as the red-black tree are discarded (and in the future, new CFB containers -will exclusively use black nodes) +files that line up with the tree-based structure of the storage. Metadata such +as the red-black tree are discarded. # Library Installation and Usage In the browser: - +```html + +``` In node: - var CFB = require('cfb'); +```js +var CFB = require('cfb'); +``` For example, to get the Workbook content from an XLS file: - var cfb = CFB.read(filename, {type: 'file'}); - var workbook = cfb.find('Workbook') +```js +var cfb = CFB.read(filename, {type: 'file'}); +var workbook = cfb.find('Workbook') +``` # API @@ -86,7 +90,7 @@ Case comparison has not been verified for non-ASCII characters Writing is not supported. It is in the works, but it has not yet been released. -The `xlscfb.js` file is designed to be embedded in [js-xls](http://git.io/xls) +The `xlscfb.js` file is designed to be embedded in [js-xlsx](http://git.io/xlsx) # License @@ -95,7 +99,14 @@ This implementation is covered under Apache 2.0 license. It complies with the [![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) +[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-cfb/master.svg)](https://coveralls.io/r/SheetJS/js-cfb?branch=master) + +[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-cfb?pixel)](https://github.com/SheetJS/js-cfb) + +[![NPM Downloads](https://img.shields.io/npm/dt/cfb.svg)](https://npmjs.org/package/cfb) + +[![Dependencies Status](https://david-dm.org/sheetjs/js-cfb/status.svg)](https://david-dm.org/sheetjs/js-cfb) + +[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-cfb)](https://ghit.me/repo/sheetjs/js-cfb) -[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/88c2e1fd637653cd780b3c6d3dcd70ad "githalytics.com")](http://githalytics.com/SheetJS/js-cfb) diff --git a/bin/cfb.njs b/bin/cfb.njs index 8b18dcd..5c5ac01 100755 --- a/bin/cfb.njs +++ b/bin/cfb.njs @@ -15,14 +15,14 @@ if(program.args.length === 0 || !fs.existsSync(program.args[0])) { process.exit(1); } -var opts = {type:'file'}; +var opts = ({type:'file'}/*:any*/); if(program.dev) opts.WTF = true; var cfb = CFB.read(program.args[0], opts); if(program.dump) { - console.log("Full Paths:") + console.log("Full Paths:"); console.log(cfb.FullPaths.map(function(x) { return " " + x; }).join("\n")); - console.log("Full Path Directory:") + console.log("Full Path Directory:"); console.log(cfb.FullPathDir); } if(!program.quiet && !program.dump) for(var i=0; i!=cfb.FullPaths.length; ++i) { diff --git a/bits/00_header.js b/bits/00_header.js index 076f3cd..e6f26f7 100644 --- a/bits/00_header.js +++ b/bits/00_header.js @@ -1,4 +1,4 @@ -/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ +/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*jshint eqnull:true */ diff --git a/bits/08_blob.js b/bits/08_blob.js index a3523b6..6bf3c06 100644 --- a/bits/08_blob.js +++ b/bits/08_blob.js @@ -28,14 +28,14 @@ var Base64 = (function(){ 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) & 0xff; }); }; +s2a = _s2a = function _s2a(s/*:string*/) { 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; }; +__toBuffer = ___toBuffer = function(bufs/*:any*/) { 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 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); }; + __toBuffer = function(bufs/*:any*/) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);}; + s2a = function(s/*:string*/) { return new Buffer(s, "binary"); }; + bconcat = function(bufs/*:any*/) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); }; } @@ -56,7 +56,7 @@ var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u 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) { +function ReadShift(size/*:number*/, t/*:?any*/) { var oI, oS, type = 0; switch(size) { case 1: oI = __readUInt8(this, this.l); break; @@ -67,13 +67,13 @@ function ReadShift(size, t) { this.l+=size; if(type === 0) return oI; return oS; } -function CheckField(hexstr, fld) { +function CheckField(hexstr/*:string*/, fld/*:string*/) { 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) { +function prep_blob(blob/*:any*/, pos/*:number*/) { blob.l = pos; blob.read_shift = ReadShift; blob.chk = CheckField; diff --git a/bits/10_types.js b/bits/10_types.js new file mode 100644 index 0000000..a7cc6ae --- /dev/null +++ b/bits/10_types.js @@ -0,0 +1,10 @@ +/*:: +declare var DO_NOT_EXPORT_CFB:any; +type SectorEntry = any; +type SectorList = { + (k:string|number):SectorEntry; + name:?string; + fat_addrs:any; + ssz:number; +} +*/ diff --git a/bits/31_version.js b/bits/31_version.js index 172c898..e1a6e44 100644 --- a/bits/31_version.js +++ b/bits/31_version.js @@ -1 +1 @@ -exports.version = '0.10.2'; +exports.version = '0.10.3'; diff --git a/bits/40_parse.js b/bits/40_parse.js index a8dad2e..2b0d9fe 100644 --- a/bits/40_parse.js +++ b/bits/40_parse.js @@ -10,7 +10,7 @@ var difat_start = 0; // first mini FAT sector location var fat_addrs = []; // locations of FAT sectors /* [MS-CFB] 2.2 Compound File Header */ -var blob = file.slice(0,512); +var blob/*:any*/ = file.slice(0,512); prep_blob(blob, 0); /* major version */ @@ -70,7 +70,7 @@ 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); +var sector_list/*:SectorList*/ = 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"; @@ -79,7 +79,7 @@ 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/*:any*/ = [], FileIndex = [], FullPaths = [], FullPathDir = {}; read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); diff --git a/bits/44_findpath.js b/bits/44_findpath.js index 596279a..4d1c856 100644 --- a/bits/44_findpath.js +++ b/bits/44_findpath.js @@ -4,7 +4,7 @@ function make_find_path(FullPaths, Paths, FileIndex, files, root_name) { var UCPaths = new Array(Paths.length), i; for(i = 0; i < FullPaths.length; ++i) UCFullPaths[i] = FullPaths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); - return function find_path(path) { + return function find_path(path/*:string*/) { var k; if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; } else k = path.indexOf("/") !== -1; diff --git a/bits/45_readfat.js b/bits/45_readfat.js index 59bca6d..37aead4 100644 --- a/bits/45_readfat.js +++ b/bits/45_readfat.js @@ -6,6 +6,7 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { if(cnt !== 0) throw "DIFAT chain shorter than expected"; } else if(idx !== -1 /*FREESECT*/) { var sector = sectors[idx], m = (ssz>>>2)-1; + if(!sector) return; for(var i = 0; i < m; ++i) { if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break; fat_addrs.push(q); @@ -29,13 +30,14 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { var addr = fat_addrs[Math.floor(j*4/ssz)]; jj = ((j*4) & modulus); if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + if(!sectors[addr]) break; j = __readInt32LE(sectors[addr], jj); } return {nodes: buf, data:__toBuffer([buf_chain])}; } /** Chase down the sector linked lists */ -function make_sector_list(sectors, dir_start, fat_addrs, ssz) { +function make_sector_list(sectors, dir_start, fat_addrs, ssz/*:number*/)/*:any*/ { 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; @@ -51,6 +53,7 @@ function make_sector_list(sectors, dir_start, fat_addrs, ssz) { var addr = fat_addrs[Math.floor(j*4/ssz)]; jj = ((j*4) & modulus); if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + if(!sectors[addr]) break; j = __readInt32LE(sectors[addr], jj); } sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; diff --git a/bits/46_readdir.js b/bits/46_readdir.js index d30a99c..748d056 100644 --- a/bits/46_readdir.js +++ b/bits/46_readdir.js @@ -11,7 +11,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil if(namelen === 0) continue; name = __utf16le(blob,0,namelen-pl); Paths.push(name); - o = { + o = ({ name: name, type: blob.read_shift(1), color: blob.read_shift(1), @@ -20,7 +20,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil C: blob.read_shift(4, 'i'), clsid: blob.read_shift(16), state: blob.read_shift(4, 'i') - }; + }/*:any*/); 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); diff --git a/bits/49_readutils.js b/bits/49_readutils.js index 771bf59..c942f95 100644 --- a/bits/49_readutils.js +++ b/bits/49_readutils.js @@ -1,10 +1,10 @@ var fs; -function readFileSync(filename, options) { +function readFileSync(filename/*:string*/, options/*:any*/) { if(fs === undefined) fs = require('fs'); return parse(fs.readFileSync(filename), options); } -function readSync(blob, options) { +function readSync(blob/*:any*/, options/*:any*/) { switch(options !== undefined && options.type !== undefined ? options.type : "base64") { case "file": return readFileSync(blob, options); case "base64": return parse(s2a(Base64.decode(blob)), options); diff --git a/cfb.flow.js b/cfb.flow.js new file mode 100644 index 0000000..8e2d45c --- /dev/null +++ b/cfb.flow.js @@ -0,0 +1,476 @@ +/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +/*jshint eqnull:true */ + +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/*:string*/) { return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; }); }; +var __toBuffer, ___toBuffer; +__toBuffer = ___toBuffer = function(bufs/*:any*/) { 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 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);}; + s2a = function(s/*:string*/) { return new Buffer(s, "binary"); }; + bconcat = function(bufs/*:any*/) { 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 < 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]; }; + +function ReadShift(size/*:number*/, t/*:?any*/) { + 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/*:string*/, fld/*:string*/) { + 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/*:any*/, pos/*:number*/) { + blob.l = pos; + blob.read_shift = ReadShift; + blob.chk = CheckField; +} + +/*:: +declare var DO_NOT_EXPORT_CFB:any; +type SectorEntry = any; +type SectorList = { + (k:string|number):SectorEntry; + name:?string; + fat_addrs:any; + ssz:number; +} +*/ +/* [MS-CFB] v20130118 */ +var CFB = (function _CFB(){ +var exports = {}; +exports.version = '0.10.3'; +function parse(file) { +var mver = 3; // major version +var ssz = 512; // sector size +var nmfs = 0; // number of mini FAT sectors +var ndfs = 0; // number of DIFAT sectors +var dir_start = 0; // first directory sector location +var minifat_start = 0; // first mini FAT sector location +var difat_start = 0; // first mini FAT sector location + +var fat_addrs = []; // locations of FAT sectors + +/* [MS-CFB] 2.2 Compound File Header */ +var blob/*:any*/ = file.slice(0,512); +prep_blob(blob, 0); + +/* major version */ +var mv = check_get_mver(blob); +mver = mv[0]; +switch(mver) { + case 3: ssz = 512; break; case 4: ssz = 4096; break; + default: throw "Major Version: Expected 3 or 4 saw " + mver; +} + +/* 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); + +check_shifts(blob, mver); + +// Number of Directory Sectors +var nds = blob.read_shift(4, 'i'); +if(mver === 3 && nds !== 0) throw '# Directory Sectors: Expected 0 saw ' + nds; + +// Number of FAT Sectors +//var nfs = blob.read_shift(4, 'i'); +blob.l += 4; + +// First Directory Sector Location +dir_start = blob.read_shift(4, 'i'); + +// Transaction Signature +blob.l += 4; + +// Mini Stream Cutoff Size +blob.chk('00100000', 'Mini Stream Cutoff Size: '); + +// First Mini FAT Sector Location +minifat_start = blob.read_shift(4, 'i'); + +// Number of Mini FAT Sectors +nmfs = blob.read_shift(4, 'i'); + +// First DIFAT sector location +difat_start = blob.read_shift(4, 'i'); + +// Number of DIFAT Sectors +ndfs = blob.read_shift(4, 'i'); + +// Grab FAT Sector Locations +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/*:SectorList*/ = 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"; +sector_list.fat_addrs = fat_addrs; +sector_list.ssz = ssz; + +/* [MS-CFB] 2.6.1 Compound File Directory Entry */ +var files = {}, Paths/*:any*/ = [], 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 + var mver = blob.read_shift(2, 'u'); + + return [blob.read_shift(2,'u'), mver]; +} +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 */ +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().replace(chr0,'').replace(chr1,'!'); + for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); + return function find_path(path/*:string*/) { + var k; + if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; } + else k = path.indexOf("/") !== -1; + var UCPath = path.toUpperCase().replace(chr0,'').replace(chr1,'!'); + 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, sectors, ssz, fat_addrs) { + var q; + if(idx === ENDOFCHAIN) { + if(cnt !== 0) throw "DIFAT chain shorter than expected"; + } else if(idx !== -1 /*FREESECT*/) { + var sector = sectors[idx], m = (ssz>>>2)-1; + if(!sector) return; + 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); + } +} + +/** Follow the linked list of sectors for a given starting point */ +function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { + var sl = sectors.length; + var buf, buf_chain; + if(!chkd) chkd = new Array(sl); + var modulus = ssz - 1, j, jj; + buf = []; + buf_chain = []; + for(j=start; 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; + if(!sectors[addr]) break; + j = __readInt32LE(sectors[addr], jj); + } + return {nodes: buf, data:__toBuffer([buf_chain])}; +} + +/** Chase down the sector linked lists */ +function make_sector_list(sectors, dir_start, fat_addrs, ssz/*:number*/)/*:any*/ { + 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; + if(!sectors[addr]) break; + j = __readInt32LE(sectors[addr], jj); + } + sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; + } + return sector_list; +} + +/* [MS-CFB] 2.6.1 Compound File Directory Entry */ +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') + }/*:any*/); + 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 >= 4096 /* MSCSZ */) { + o.storage = 'fat'; + if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz); + 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)*1000); +} + +var fs; +function readFileSync(filename/*:string*/, options/*:any*/) { + if(fs === undefined) fs = require('fs'); + return parse(fs.readFileSync(filename), options); +} + +function readSync(blob/*:any*/, options/*:any*/) { + switch(options !== undefined && options.type !== undefined ? options.type : "base64") { + case "file": return readFileSync(blob, options); + case "base64": return parse(s2a(Base64.decode(blob)), options); + case "binary": return parse(s2a(blob), options); + } + return parse(blob); +} + +/** 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 */ + MAXREGSECT: -6, + DIFSECT: -4, + FATSECT: -3, + ENDOFCHAIN: ENDOFCHAIN, + FREESECT: -1, + /* 2.2 Compound File Header */ + HEADER_SIGNATURE: HEADER_SIGNATURE, + HEADER_MINOR_VERSION: '3e00', + MAXREGSID: -6, + NOSTREAM: -1, + HEADER_CLSID: HEADER_CLSID, + /* 2.6.1 Compound File Directory Entry */ + 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; } diff --git a/cfb.js b/cfb.js index 4d976a0..96561fd 100644 --- a/cfb.js +++ b/cfb.js @@ -1,4 +1,4 @@ -/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ +/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*jshint eqnull:true */ @@ -49,7 +49,7 @@ if(typeof Buffer !== "undefined") { }; __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"); }; + s2a = function(s) { return new Buffer(s, "binary"); }; bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); }; } @@ -86,7 +86,7 @@ function prep_blob(blob, pos) { /* [MS-CFB] v20130118 */ var CFB = (function _CFB(){ var exports = {}; -exports.version = '0.10.2'; +exports.version = '0.10.3'; function parse(file) { var mver = 3; // major version var ssz = 512; // sector size @@ -296,6 +296,7 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { if(cnt !== 0) throw "DIFAT chain shorter than expected"; } else if(idx !== -1 /*FREESECT*/) { var sector = sectors[idx], m = (ssz>>>2)-1; + if(!sector) return; for(var i = 0; i < m; ++i) { if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break; fat_addrs.push(q); @@ -319,6 +320,7 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { var addr = fat_addrs[Math.floor(j*4/ssz)]; jj = ((j*4) & modulus); if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + if(!sectors[addr]) break; j = __readInt32LE(sectors[addr], jj); } return {nodes: buf, data:__toBuffer([buf_chain])}; @@ -341,6 +343,7 @@ function make_sector_list(sectors, dir_start, fat_addrs, ssz) { var addr = fat_addrs[Math.floor(j*4/ssz)]; jj = ((j*4) & modulus); if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + if(!sectors[addr]) break; j = __readInt32LE(sectors[addr], jj); } sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; @@ -361,7 +364,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil if(namelen === 0) continue; name = __utf16le(blob,0,namelen-pl); Paths.push(name); - o = { + o = ({ name: name, type: blob.read_shift(1), color: blob.read_shift(1), @@ -370,7 +373,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil 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); diff --git a/dist/LICENSE b/dist/LICENSE index 6d41660..a5fc80a 100644 --- a/dist/LICENSE +++ b/dist/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2013-2014 SheetJS +Copyright (C) 2013-present SheetJS Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/dist/cfb.js b/dist/cfb.js index 4d976a0..96561fd 100644 --- a/dist/cfb.js +++ b/dist/cfb.js @@ -1,4 +1,4 @@ -/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ +/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*jshint eqnull:true */ @@ -49,7 +49,7 @@ if(typeof Buffer !== "undefined") { }; __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"); }; + s2a = function(s) { return new Buffer(s, "binary"); }; bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); }; } @@ -86,7 +86,7 @@ function prep_blob(blob, pos) { /* [MS-CFB] v20130118 */ var CFB = (function _CFB(){ var exports = {}; -exports.version = '0.10.2'; +exports.version = '0.10.3'; function parse(file) { var mver = 3; // major version var ssz = 512; // sector size @@ -296,6 +296,7 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { if(cnt !== 0) throw "DIFAT chain shorter than expected"; } else if(idx !== -1 /*FREESECT*/) { var sector = sectors[idx], m = (ssz>>>2)-1; + if(!sector) return; for(var i = 0; i < m; ++i) { if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break; fat_addrs.push(q); @@ -319,6 +320,7 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { var addr = fat_addrs[Math.floor(j*4/ssz)]; jj = ((j*4) & modulus); if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + if(!sectors[addr]) break; j = __readInt32LE(sectors[addr], jj); } return {nodes: buf, data:__toBuffer([buf_chain])}; @@ -341,6 +343,7 @@ function make_sector_list(sectors, dir_start, fat_addrs, ssz) { var addr = fat_addrs[Math.floor(j*4/ssz)]; jj = ((j*4) & modulus); if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + if(!sectors[addr]) break; j = __readInt32LE(sectors[addr], jj); } sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; @@ -361,7 +364,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil if(namelen === 0) continue; name = __utf16le(blob,0,namelen-pl); Paths.push(name); - o = { + o = ({ name: name, type: blob.read_shift(1), color: blob.read_shift(1), @@ -370,7 +373,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil 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); diff --git a/dist/cfb.min.js b/dist/cfb.min.js index eb3a884..e3d2330 100644 --- a/dist/cfb.min.js +++ b/dist/cfb.min.js @@ -1,2 +1,2 @@ -/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ -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>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;i0&&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.2";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);var mv=check_get_mver(blob);mver=mv[0];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";sector_list.fat_addrs=fat_addrs;sector_list.ssz=ssz;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: ");var mver=blob.read_shift(2,"u");return[blob.read_shift(2,"u"),mver]}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>>2)-1;for(var i=0;i=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)}return{nodes:buf,data:__toBuffer([buf_chain])}}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)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(;i0&&minifat_store!==ENDOFCHAIN)sector_list[minifat_store].name="!StreamData"}else if(o.size>=4096){o.storage="fat";if(sector_list[o.start]===undefined)sector_list[o.start]=get_sector_list(sectors,o.start,sector_list.fat_addrs,sector_list.ssz);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,options){if(fs===undefined)fs=require("fs");return parse(fs.readFileSync(filename),options)}function readSync(blob,options){switch(options!==undefined&&options.type!==undefined?options.type:"base64"){case"file":return readFileSync(blob,options);case"base64":return parse(s2a(Base64.decode(blob)),options);case"binary":return parse(s2a(blob),options)}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} +/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ +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>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;i0&&Buffer.isBuffer(bufs[0][0])?Buffer.concat(bufs[0]):___toBuffer(bufs)};s2a=function(s){return new 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.3";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);var mv=check_get_mver(blob);mver=mv[0];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";sector_list.fat_addrs=fat_addrs;sector_list.ssz=ssz;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: ");var mver=blob.read_shift(2,"u");return[blob.read_shift(2,"u"),mver]}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>>2)-1;if(!sector)return;for(var i=0;i=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;if(!sectors[addr])break;j=__readInt32LE(sectors[addr],jj)}return{nodes:buf,data:__toBuffer([buf_chain])}}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)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;if(!sectors[addr])break;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(;i0&&minifat_store!==ENDOFCHAIN)sector_list[minifat_store].name="!StreamData"}else if(o.size>=4096){o.storage="fat";if(sector_list[o.start]===undefined)sector_list[o.start]=get_sector_list(sectors,o.start,sector_list.fat_addrs,sector_list.ssz);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,options){if(fs===undefined)fs=require("fs");return parse(fs.readFileSync(filename),options)}function readSync(blob,options){switch(options!==undefined&&options.type!==undefined?options.type:"base64"){case"file":return readFileSync(blob,options);case"base64":return parse(s2a(Base64.decode(blob)),options);case"binary":return parse(s2a(blob),options)}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} diff --git a/dist/cfb.min.map b/dist/cfb.min.map index 14c4c49..37a2b33 100644 --- a/dist/cfb.min.map +++ b/dist/cfb.min.map @@ -1 +1 @@ -{"version":3,"file":"dist/cfb.min.js","sources":["cfb.js"],"names":["Base64","map","decode","input","o","c1","c2","c3","e1","e2","e3","e4","replace","i","length","indexOf","charAt","String","fromCharCode","chr0","chr1","s2a","_s2a","s","split","x","charCodeAt","__toBuffer","___toBuffer","bufs","push","apply","__utf16le","___utf16le","b","e","ss","__readUInt16LE","join","__hexlify","___hexlify","l","slice","toString","bconcat","concat","Buffer","isBuffer","__readUInt8","idx","__readInt16LE","u","__readUInt32LE","__readInt32LE","ReadShift","size","t","oI","oS","type","this","CheckField","hexstr","fld","m","prep_blob","blob","pos","read_shift","chk","CFB","_CFB","exports","version","parse","file","mver","ssz","nmfs","ndfs","dir_start","minifat_start","difat_start","fat_addrs","mv","check_get_mver","header","check_shifts","nds","q","j","sectors","sectorify","sleuth_fat","sector_list","make_sector_list","name","ENDOFCHAIN","files","Paths","FileIndex","FullPaths","FullPathDir","read_directory","build_full_paths","root_name","shift","root","find_path","make_find_path","raw","find","HEADER_SIGNATURE","HEADER_CLSID","nsectors","Math","ceil","Array","FI","FPD","FP","L","R","C","pl","dad","UCFullPaths","UCPaths","toUpperCase","path","k","UCPath","w","cnt","sector","get_sector_list","start","chkd","sl","buf","buf_chain","modulus","jj","addr","floor","nodes","data","minifat_store","namelen","ctime","mtime","color","clsid","state","ct","read_date","mt","storage","undefined","content","MSSZ","offset","Date","pow","fs","readFileSync","filename","options","require","readSync","consts","MAXREGSECT","DIFSECT","FATSECT","FREESECT","HEADER_MINOR_VERSION","MAXREGSID","NOSTREAM","EntryTypes","read","utils","module","DO_NOT_EXPORT_CFB"],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["cfb.js"],"names":["Base64","map","decode","input","o","c1","c2","c3","e1","e2","e3","e4","replace","i","length","indexOf","charAt","String","fromCharCode","chr0","chr1","s2a","_s2a","s","split","x","charCodeAt","__toBuffer","___toBuffer","bufs","push","apply","__utf16le","___utf16le","b","e","ss","__readUInt16LE","join","__hexlify","___hexlify","l","slice","toString","bconcat","concat","Buffer","isBuffer","__readUInt8","idx","__readInt16LE","u","__readUInt32LE","__readInt32LE","ReadShift","size","t","oI","oS","type","this","CheckField","hexstr","fld","m","prep_blob","blob","pos","read_shift","chk","CFB","_CFB","exports","version","parse","file","mver","ssz","nmfs","ndfs","dir_start","minifat_start","difat_start","fat_addrs","mv","check_get_mver","header","check_shifts","nds","q","j","sectors","sectorify","sleuth_fat","sector_list","make_sector_list","name","ENDOFCHAIN","files","Paths","FileIndex","FullPaths","FullPathDir","read_directory","build_full_paths","root_name","shift","root","find_path","make_find_path","raw","find","HEADER_SIGNATURE","HEADER_CLSID","nsectors","Math","ceil","Array","FI","FPD","FP","L","R","C","pl","dad","UCFullPaths","UCPaths","toUpperCase","path","k","UCPath","w","cnt","sector","get_sector_list","start","chkd","sl","buf","buf_chain","modulus","jj","addr","floor","nodes","data","minifat_store","namelen","ctime","mtime","color","clsid","state","ct","read_date","mt","storage","undefined","content","MSSZ","offset","Date","pow","fs","readFileSync","filename","options","require","readSync","consts","MAXREGSECT","DIFSECT","FATSECT","FREESECT","HEADER_MINOR_VERSION","MAXREGSID","NOSTREAM","EntryTypes","read","utils","module","DO_NOT_EXPORT_CFB"],"mappings":"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","file":"dist/cfb.min.js"} \ No newline at end of file diff --git a/dist/xlscfb.js b/dist/xlscfb.js index 2bb2335..4d115dd 100644 --- a/dist/xlscfb.js +++ b/dist/xlscfb.js @@ -1,12 +1,12 @@ var DO_NOT_EXPORT_CFB = true; -/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ +/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*jshint eqnull:true */ /* [MS-CFB] v20130118 */ var CFB = (function _CFB(){ var exports = {}; -exports.version = '0.10.2'; +exports.version = '0.10.3'; function parse(file) { var mver = 3; // major version var ssz = 512; // sector size @@ -216,6 +216,7 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { if(cnt !== 0) throw "DIFAT chain shorter than expected"; } else if(idx !== -1 /*FREESECT*/) { var sector = sectors[idx], m = (ssz>>>2)-1; + if(!sector) return; for(var i = 0; i < m; ++i) { if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break; fat_addrs.push(q); @@ -239,6 +240,7 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { var addr = fat_addrs[Math.floor(j*4/ssz)]; jj = ((j*4) & modulus); if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + if(!sectors[addr]) break; j = __readInt32LE(sectors[addr], jj); } return {nodes: buf, data:__toBuffer([buf_chain])}; @@ -261,6 +263,7 @@ function make_sector_list(sectors, dir_start, fat_addrs, ssz) { var addr = fat_addrs[Math.floor(j*4/ssz)]; jj = ((j*4) & modulus); if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + if(!sectors[addr]) break; j = __readInt32LE(sectors[addr], jj); } sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; @@ -281,7 +284,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil if(namelen === 0) continue; name = __utf16le(blob,0,namelen-pl); Paths.push(name); - o = { + o = ({ name: name, type: blob.read_shift(1), color: blob.read_shift(1), @@ -290,7 +293,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil 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); diff --git a/fails.lst b/fails.lst index 0364914..1eeb7ed 100644 --- a/fails.lst +++ b/fails.lst @@ -1,3 +1,6 @@ +apachepoi_testEXCEL_3.xls +apachepoi_testEXCEL_4.xls +xlrd_biff4_no_format_no_window2.xls roo_type_excelx.xls roo_type_openoffice.xls libreoffice_calc_csv-import_malformed-quotes.xls diff --git a/index.html b/index.html index 97af2eb..1758e7f 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,10 @@ + + + + + +JS-CFB Live Demo + + JS-CFB Live Demo
Drop an XLS file here to see the CFB structure.
+Advanced Demo Options:
+Use readAsBinaryString: (when available)

 
+ + diff --git a/misc/flow.js b/misc/flow.js new file mode 100644 index 0000000..f9a5c9f --- /dev/null +++ b/misc/flow.js @@ -0,0 +1,5 @@ +/*:: + +type CFBModule = any; + +*/ diff --git a/misc/flowdeps.js b/misc/flowdeps.js new file mode 100644 index 0000000..16cac2a --- /dev/null +++ b/misc/flowdeps.js @@ -0,0 +1,9 @@ +/*:: + +declare module 'cfb' { declare var exports:CFBModule; }; +declare module '../' { declare var exports:CFBModule; }; +declare module './' { declare var exports:CFBModule; }; + +declare module 'commander' { declare var exports:any; }; + +*/ diff --git a/misc/help.sh b/misc/help.sh new file mode 100755 index 0000000..7a1c4c4 --- /dev/null +++ b/misc/help.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# make_help.sh -- process listing of targets and special items in Makefile +# Copyright (C) 2016-present SheetJS +# +# usage in makefile: pipe the output of the following command: +# @grep -hE '(^[a-zA-Z_-][ a-zA-Z_-]*:.*?|^#[#*])' $(MAKEFILE_LIST) +# +# lines starting with "## " are treated as subtitles +# lines starting with "#* " are treated as plaintext comments +# multiple targets with "## " after the ":" are rendered as separate targets +# if the presumed default target is labeled, it will be assigned a unique color + +awk ' +BEGIN{recipes=0;} + !/#[#*] .*$/ {next;} + {multi=0; isrecipe=0;} + /^[^#]*:/ {isrecipe=1; ++recipes;} + /^[^ :]* .*:/ {multi=1} + multi==0 && isrecipe>0 { if(recipes > 1) print; else print $0, "[default]"; next} + isrecipe == 0 {print; next} + multi>0 { + k=split($0, msg, "##"); m=split($0, a, ":"); n=split(a[1], b, " "); + for(i=1; i<=n; ++i) print b[i] ":", "##" msg[2], (recipes==1 && i==1 ? "[default]" : "") + } +END {} +' | if [[ -t 1 ]]; then +awk ' +BEGIN {FS = ":.*?## "} + {color=36} + /\[default\]/ {color=35} + NF==1 && /^##/ {color=34} + NF==1 && /^#\*/ {color=20; $1 = substr($1, 4)} + {printf "\033[" color "m%-20s\033[0m %s\n", $1, $2;} +END{}' - +else +awk ' +BEGIN {FS = ":.*?## "} + /^#\* / {$1 = substr($1, 4)} + {printf "%-20s %s\n", $1, $2;} +END{}' - +fi + diff --git a/misc/spin.sh b/misc/spin.sh index 9951a57..471dfee 100755 --- a/misc/spin.sh +++ b/misc/spin.sh @@ -1,6 +1,6 @@ #!/bin/bash # spin.sh -- show a spinner (for coverage test) -# Copyright (C) 2014 SheetJS +# Copyright (C) 2014-present SheetJS wpid=$1 delay=1 diff --git a/misc/suppress_export.js b/misc/suppress_export.js index 6366ccf..c7f0105 100644 --- a/misc/suppress_export.js +++ b/misc/suppress_export.js @@ -1 +1,15 @@ var DO_NOT_EXPORT_CFB = true; +/*:: +declare var Base64:any; +declare var ReadShift:any; +declare var CheckField:any; +declare var prep_blob:any; +declare var __readUInt32LE:any; +declare var __readInt32LE:any; +declare var __toBuffer:any; +declare var __utf16le:any; +declare var bconcat:any; +declare var s2a:any; +declare var chr0:any; +declare var chr1:any; +*/ diff --git a/package.json b/package.json index a0da1dc..3c78ae2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cfb", - "version": "0.10.2-a", + "version": "0.10.3", "author": "sheetjs", "description": "Compound File Binary File Format extractor", "keywords": [ "cfb", "compression", "office" ], @@ -13,7 +13,8 @@ "README.md", "bin/", "dist/", - "cfb.js" + "cfb.js", + "xlscfb.flow.js" ], "dependencies": { "commander":"" diff --git a/xlscfb.flow.js b/xlscfb.flow.js new file mode 100644 index 0000000..aa4b49e --- /dev/null +++ b/xlscfb.flow.js @@ -0,0 +1,410 @@ +var DO_NOT_EXPORT_CFB = true; +/*:: +declare var Base64:any; +declare var ReadShift:any; +declare var CheckField:any; +declare var prep_blob:any; +declare var __readUInt32LE:any; +declare var __readInt32LE:any; +declare var __toBuffer:any; +declare var __utf16le:any; +declare var bconcat:any; +declare var s2a:any; +declare var chr0:any; +declare var chr1:any; +*/ +/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +/*jshint eqnull:true */ + +/*:: +declare var DO_NOT_EXPORT_CFB:any; +type SectorEntry = any; +type SectorList = { + (k:string|number):SectorEntry; + name:?string; + fat_addrs:any; + ssz:number; +} +*/ +/* [MS-CFB] v20130118 */ +var CFB = (function _CFB(){ +var exports = {}; +exports.version = '0.10.3'; +function parse(file) { +var mver = 3; // major version +var ssz = 512; // sector size +var nmfs = 0; // number of mini FAT sectors +var ndfs = 0; // number of DIFAT sectors +var dir_start = 0; // first directory sector location +var minifat_start = 0; // first mini FAT sector location +var difat_start = 0; // first mini FAT sector location + +var fat_addrs = []; // locations of FAT sectors + +/* [MS-CFB] 2.2 Compound File Header */ +var blob/*:any*/ = file.slice(0,512); +prep_blob(blob, 0); + +/* major version */ +var mv = check_get_mver(blob); +mver = mv[0]; +switch(mver) { + case 3: ssz = 512; break; case 4: ssz = 4096; break; + default: throw "Major Version: Expected 3 or 4 saw " + mver; +} + +/* 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); + +check_shifts(blob, mver); + +// Number of Directory Sectors +var nds = blob.read_shift(4, 'i'); +if(mver === 3 && nds !== 0) throw '# Directory Sectors: Expected 0 saw ' + nds; + +// Number of FAT Sectors +//var nfs = blob.read_shift(4, 'i'); +blob.l += 4; + +// First Directory Sector Location +dir_start = blob.read_shift(4, 'i'); + +// Transaction Signature +blob.l += 4; + +// Mini Stream Cutoff Size +blob.chk('00100000', 'Mini Stream Cutoff Size: '); + +// First Mini FAT Sector Location +minifat_start = blob.read_shift(4, 'i'); + +// Number of Mini FAT Sectors +nmfs = blob.read_shift(4, 'i'); + +// First DIFAT sector location +difat_start = blob.read_shift(4, 'i'); + +// Number of DIFAT Sectors +ndfs = blob.read_shift(4, 'i'); + +// Grab FAT Sector Locations +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/*:SectorList*/ = 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"; +sector_list.fat_addrs = fat_addrs; +sector_list.ssz = ssz; + +/* [MS-CFB] 2.6.1 Compound File Directory Entry */ +var files = {}, Paths/*:any*/ = [], 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 + var mver = blob.read_shift(2, 'u'); + + return [blob.read_shift(2,'u'), mver]; +} +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 */ +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().replace(chr0,'').replace(chr1,'!'); + for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); + return function find_path(path/*:string*/) { + var k; + if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; } + else k = path.indexOf("/") !== -1; + var UCPath = path.toUpperCase().replace(chr0,'').replace(chr1,'!'); + 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, sectors, ssz, fat_addrs) { + var q; + if(idx === ENDOFCHAIN) { + if(cnt !== 0) throw "DIFAT chain shorter than expected"; + } else if(idx !== -1 /*FREESECT*/) { + var sector = sectors[idx], m = (ssz>>>2)-1; + if(!sector) return; + 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); + } +} + +/** Follow the linked list of sectors for a given starting point */ +function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { + var sl = sectors.length; + var buf, buf_chain; + if(!chkd) chkd = new Array(sl); + var modulus = ssz - 1, j, jj; + buf = []; + buf_chain = []; + for(j=start; 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; + if(!sectors[addr]) break; + j = __readInt32LE(sectors[addr], jj); + } + return {nodes: buf, data:__toBuffer([buf_chain])}; +} + +/** Chase down the sector linked lists */ +function make_sector_list(sectors, dir_start, fat_addrs, ssz/*:number*/)/*:any*/ { + 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; + if(!sectors[addr]) break; + j = __readInt32LE(sectors[addr], jj); + } + sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; + } + return sector_list; +} + +/* [MS-CFB] 2.6.1 Compound File Directory Entry */ +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') + }/*:any*/); + 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 >= 4096 /* MSCSZ */) { + o.storage = 'fat'; + if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz); + 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)*1000); +} + +var fs; +function readFileSync(filename/*:string*/, options/*:any*/) { + if(fs === undefined) fs = require('fs'); + return parse(fs.readFileSync(filename), options); +} + +function readSync(blob/*:any*/, options/*:any*/) { + switch(options !== undefined && options.type !== undefined ? options.type : "base64") { + case "file": return readFileSync(blob, options); + case "base64": return parse(s2a(Base64.decode(blob)), options); + case "binary": return parse(s2a(blob), options); + } + return parse(blob); +} + +/** 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 */ + MAXREGSECT: -6, + DIFSECT: -4, + FATSECT: -3, + ENDOFCHAIN: ENDOFCHAIN, + FREESECT: -1, + /* 2.2 Compound File Header */ + HEADER_SIGNATURE: HEADER_SIGNATURE, + HEADER_MINOR_VERSION: '3e00', + MAXREGSID: -6, + NOSTREAM: -1, + HEADER_CLSID: HEADER_CLSID, + /* 2.6.1 Compound File Directory Entry */ + 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; } diff --git a/xlscfb.js b/xlscfb.js index 2bb2335..4d115dd 100644 --- a/xlscfb.js +++ b/xlscfb.js @@ -1,12 +1,12 @@ var DO_NOT_EXPORT_CFB = true; -/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ +/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*jshint eqnull:true */ /* [MS-CFB] v20130118 */ var CFB = (function _CFB(){ var exports = {}; -exports.version = '0.10.2'; +exports.version = '0.10.3'; function parse(file) { var mver = 3; // major version var ssz = 512; // sector size @@ -216,6 +216,7 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { if(cnt !== 0) throw "DIFAT chain shorter than expected"; } else if(idx !== -1 /*FREESECT*/) { var sector = sectors[idx], m = (ssz>>>2)-1; + if(!sector) return; for(var i = 0; i < m; ++i) { if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break; fat_addrs.push(q); @@ -239,6 +240,7 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { var addr = fat_addrs[Math.floor(j*4/ssz)]; jj = ((j*4) & modulus); if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + if(!sectors[addr]) break; j = __readInt32LE(sectors[addr], jj); } return {nodes: buf, data:__toBuffer([buf_chain])}; @@ -261,6 +263,7 @@ function make_sector_list(sectors, dir_start, fat_addrs, ssz) { var addr = fat_addrs[Math.floor(j*4/ssz)]; jj = ((j*4) & modulus); if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + if(!sectors[addr]) break; j = __readInt32LE(sectors[addr], jj); } sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; @@ -281,7 +284,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil if(namelen === 0) continue; name = __utf16le(blob,0,namelen-pl); Paths.push(name); - o = { + o = ({ name: name, type: blob.read_shift(1), color: blob.read_shift(1), @@ -290,7 +293,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil 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);