version bump 0.4.0: Fixes from JS-XLS + travis

This commit is contained in:
SheetJS 2013-10-26 13:20:19 -07:00
parent 8d10376fad
commit 3bc2923826
5 changed files with 61 additions and 15 deletions

8
.travis.yml Normal file

@ -0,0 +1,8 @@
language: node_js
node_js:
- "0.10"
- "0.8"
before_install:
- "npm install -g mocha"
before_script:
- "make init"

10
Makefile Normal file

@ -0,0 +1,10 @@
.PHONY: init test clean
test: init
mocha -R spec
init:
if [ ! -e test_files ]; then git clone https://github.com/Niggler/test_files; fi
cd test_files; make
clean:
rm -rf ./test_files/

42
cfb.js

@ -112,16 +112,19 @@ function ReadShift(size, t) {
}
this.l+=size; return o;
}
function CheckField(hexstr, fld) {
var m = this.slice(this.l, this.l+hexstr.length/2).hexlify('hex');
if(m !== hexstr) throw (fld||"") + 'Expected ' + hexstr + ' saw ' + m;
this.l += hexstr.length/2;
}
function WarnField(hexstr, fld) {
var m = this.slice(this.l, this.l+hexstr.length/2).hexlify('hex');
if(m !== hexstr) console.error((fld||"") + 'Expected ' + hexstr +' saw ' + m);
this.l += hexstr.length/2;
}
function prep_blob(blob, pos) {
blob.read_shift = ReadShift.bind(blob);
blob.chk = CheckField;
@ -237,9 +240,9 @@ for(j = 0; blob.l != 512; ) {
/** Break the file up into sectors */
if(file.length%ssz!==0) throw "File Length: Expected multiple of "+ssz;
if(file.length%ssz!==0) console.error("CFB: size " + file.length + " % "+ssz);
var nsectors = (file.length - ssz)/ssz;
var nsectors = Math.ceil((file.length - ssz)/ssz);
var sectors = [];
for(var i=1; i != nsectors + 1; ++i) sectors[i-1] = file.slice(i*ssz,(i+1)*ssz);
@ -250,12 +253,14 @@ function sleuth_fat(idx, cnt) {
if(cnt !== 0) throw "DIFAT chain shorter than expected";
return;
}
var sector = sectors[idx];
for(var i = 0; i != ssz/4-1; ++i) {
if((q = sector.readUInt32LE(i*4)) === ENDOFCHAIN) break;
fat_addrs.push(q);
if(idx !== FREESECT) {
var sector = sectors[idx];
for(var i = 0; i != ssz/4-1; ++i) {
if((q = sector.readUInt32LE(i*4)) === ENDOFCHAIN) break;
fat_addrs.push(q);
}
sleuth_fat(sector.readUInt32LE(ssz-4),cnt - 1);
}
sleuth_fat(sector.readUInt32LE(ssz-4),cnt - 1);
}
sleuth_fat(difat_start, ndfs);
@ -284,7 +289,7 @@ for(i=0; i != sectors.length; ++i) {
sector_list[i].data = Array(buf.map(get_sector)).toBuffer();
}
sector_list[dir_start].name = "!Directory";
if(nmfs > 0) sector_list[minifat_start].name = "!MiniFAT";
if(nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT";
sector_list[fat_addrs[0]].name = "!FAT";
/* [MS-CFB] 2.6.1 Compound File Directory Entry */
@ -314,18 +319,26 @@ function read_directory(idx) {
o.size = read(4);
if(o.type === 'root') { //root entry
minifat_store = o.start;
if(nmfs > 0) sector_list[minifat_store].name = "!StreamData";
if(nmfs > 0 && minifat_store !== ENDOFCHAIN) sector_list[minifat_store].name = "!StreamData";
minifat_size = o.size;
} else if(o.size >= ms_cutoff_size) {
o.storage = 'fat';
try {
sector_list[o.start].name = o.name;
o.content = sector_list[o.start].data.slice(0,o.size);
} catch(e) {
o.start = o.start - 1;
sector_list[o.start].name = o.name;
o.content = sector_list[o.start].data.slice(0,o.size);
}
prep_blob(o.content);
} else {
o.storage = 'minifat';
w = o.start * mssz;
o.content = sector_list[minifat_store].data.slice(w,w+o.size);
prep_blob(o.content);
if(minifat_store !== ENDOFCHAIN) {
o.content = sector_list[minifat_store].data.slice(w,w+o.size);
prep_blob(o.content);
}
}
if(o.ctime) {
var ct = blob.slice(blob.l-24, blob.l-16);
@ -351,13 +364,14 @@ function build_full_paths(Dir, pathobj, paths, patharr) {
for(i=0; i != dad.length; ++i) { dad[i]=q[i]=i; paths[i]=patharr[i]; }
for(i = q[0]; q.length !== 0; i = q.shift()) {
for(i = q[0]; typeof i !== "undefined"; i = q.shift()) {
if(Dir[i].child) dad[Dir[i].child] = i;
if(Dir[i].left) { dad[Dir[i].left] = dad[i]; q.push(Dir[i].left); }
if(Dir[i].right) { dad[Dir[i].right] = dad[i]; q.push(Dir[i].right); }
}
for(i=1; i !== paths.length; ++i) {
if(Dir[i].type === "unknown") continue;
var j = dad[i];
if(j === 0) paths[i] = paths[0] + "/" + paths[i];
else while(j != 0) {
@ -426,14 +440,14 @@ return this;
var NOSTREAM = 0xFFFFFFFF;
var HEADER_CLSID = '00000000000000000000000000000000';
/* 2.6.1 Compound File Directory Entry */
var EntryTypes = ['unknown','storage','stream',null,null,'root'];
var EntryTypes = ['unknown','storage','stream','lockbytes','property','root'];
}
var CFB_utils = {
ReadShift: ReadShift,
WarnField: WarnField,
CheckField: CheckField,
prep_blob: prep_blob,
prep_blob: prep_blob,
bconcat: bconcat
};

@ -1,6 +1,6 @@
{
"name": "cfb",
"version": "0.3.0",
"version": "0.4.0",
"author": "Niggler",
"description": "Compound File Binary File Format extractor",
"keywords": [ "cfb", "compression", "office" ],
@ -9,6 +9,9 @@
},
"main": "./cfb",
"repository": { "type":"git", "url":"git://github.com/Niggler/js-cfb.git" },
"scripts": {
"test": "make test"
},
"bugs": { "url": "https://github.com/Niggler/js-cfb/issues" },
"license": "Apache 2.0"
}

11
test.js Normal file

@ -0,0 +1,11 @@
var CFB;
var fs = require('fs');
describe('source', function() { it('should load', function() { CFB = require('./'); }); });
var files = fs.readdirSync('test_files').filter(function(x){return x.substr(-4)==".xls";});
files.forEach(function(x) {
describe(x, function() {
it('should parse ' + x, function() {
var cfb = CFB.read('./test_files/' + x, {type: "file"});
});
});
});