version bump 0.3.0: name collision resolution
It is possible for multiple streams to have the same name (albeit with different paths), so: - `FileIndex` is an array of the streams - `FullPaths` is an array of the full paths - `FullPathDir` is a full path version of `Directory`
This commit is contained in:
parent
eda9dfbf13
commit
8d10376fad
50
bin/cfb
50
bin/cfb
@ -2,44 +2,24 @@
|
||||
|
||||
var CFB = require('../cfb');
|
||||
var args = process.argv.slice(2);
|
||||
|
||||
if(args.length === 0 || !require('fs').existsSync(args[0])) {
|
||||
console.error("Usage: " + process.argv[1] + " <cfb_file>");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var cfb = CFB.read(args[0], {type:'file'});
|
||||
cfb.Paths.unshift(cfb.Paths.root);
|
||||
|
||||
var dir = cfb.Directory;
|
||||
|
||||
var dad = new Array(cfb.Paths.length);
|
||||
var paths = new Array(cfb.Paths.length);
|
||||
|
||||
var q = new Array(paths.length);
|
||||
|
||||
for(var i=0; i != dad.length; ++i) { dad[i]=q[i]=i; paths[i]=cfb.Paths[i]; }
|
||||
|
||||
for(var i = q[0]; q.length != 0; i = q.shift()) {
|
||||
if(dir[paths[i]].child) dad[dir[paths[i]].child] = i;
|
||||
if(dir[paths[i]].left) { dad[dir[paths[i]].left] = dad[i]; q.push(dir[paths[i]].left); }
|
||||
if(dir[paths[i]].right) { dad[dir[paths[i]].right] = dad[i]; q.push(dir[paths[i]].right); }
|
||||
if(args[1] === "-q") {
|
||||
console.log(cfb);
|
||||
return;
|
||||
}
|
||||
|
||||
for(var i=1; i != paths.length; ++i) {
|
||||
var j = dad[i];
|
||||
if(j === 0) paths[i] = paths[0] + "/" + paths[i];
|
||||
else while(j != 0) {
|
||||
paths[i] = paths[j] + "/" + paths[i];
|
||||
j = dad[j];
|
||||
}
|
||||
dad[i] = 0;
|
||||
}
|
||||
|
||||
paths[0] += "/";
|
||||
for(var i=1; i != paths.length; ++i) if(dir[cfb.Paths[i]].type != 'stream') paths[i] += "/";
|
||||
|
||||
var fs = require('fs');
|
||||
for(var i=0; i != paths.length; ++i) {
|
||||
if(paths[i].slice(-1) === "/") {
|
||||
console.error("mkdir " + paths[i]);
|
||||
fs.mkdirSync(paths[i]);
|
||||
for(var i=0; i != cfb.FullPaths.length; ++i) {
|
||||
if(cfb.FullPaths[i].slice(-1) === "/") {
|
||||
console.error("mkdir " + cfb.FullPaths[i]);
|
||||
fs.mkdirSync(cfb.FullPaths[i]);
|
||||
} else {
|
||||
console.error("writing " + paths[i]);
|
||||
fs.writeFile(paths[i], dir[cfb.Paths[i]].content);
|
||||
console.error("writing " + cfb.FullPaths[i]);
|
||||
fs.writeFileSync(cfb.FullPaths[i], cfb.FileIndex[i].content);
|
||||
}
|
||||
}
|
||||
|
36
cfb.js
36
cfb.js
@ -288,7 +288,7 @@ if(nmfs > 0) sector_list[minifat_start].name = "!MiniFAT";
|
||||
sector_list[fat_addrs[0]].name = "!FAT";
|
||||
|
||||
/* [MS-CFB] 2.6.1 Compound File Directory Entry */
|
||||
var files = {}, Paths = [];
|
||||
var files = {}, Paths = [], FileIndex = [], FullPaths = [], FullPathDir = {};
|
||||
function read_directory(idx) {
|
||||
var blob, read, w;
|
||||
var sector = sector_list[idx].data;
|
||||
@ -338,16 +338,50 @@ function read_directory(idx) {
|
||||
o.mt = new Date((m2 - 11644473600)*1000);
|
||||
}
|
||||
files[name] = o;
|
||||
FileIndex.push(o);
|
||||
}
|
||||
}
|
||||
read_directory(dir_start);
|
||||
|
||||
function build_full_paths(Dir, pathobj, paths, patharr) {
|
||||
var i;
|
||||
var dad = new Array(patharr.length);
|
||||
|
||||
var q = new Array(patharr.length);
|
||||
|
||||
for(i=0; i != dad.length; ++i) { dad[i]=q[i]=i; paths[i]=patharr[i]; }
|
||||
|
||||
for(i = q[0]; q.length !== 0; 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) {
|
||||
var j = dad[i];
|
||||
if(j === 0) paths[i] = paths[0] + "/" + paths[i];
|
||||
else while(j != 0) {
|
||||
paths[i] = paths[j] + "/" + paths[i];
|
||||
j = dad[j];
|
||||
}
|
||||
dad[i] = 0;
|
||||
}
|
||||
|
||||
paths[0] += "/";
|
||||
for(i=1; i !== paths.length; ++i) if(Dir[i].type !== 'stream') paths[i] += "/";
|
||||
for(i=0; i !== paths.length; ++i) pathobj[paths[i]] = FileIndex[i];
|
||||
}
|
||||
build_full_paths(FileIndex, FullPathDir, FullPaths, Paths);
|
||||
|
||||
var root_name = Paths.shift();
|
||||
Paths.root = root_name;
|
||||
|
||||
var rval = {
|
||||
raw: {header: header, sectors: sectors},
|
||||
Paths: Paths,
|
||||
FileIndex: FileIndex,
|
||||
FullPaths: FullPaths,
|
||||
FullPathDir: FullPathDir,
|
||||
Directory: files
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cfb",
|
||||
"version": "0.2.1",
|
||||
"version": "0.3.0",
|
||||
"author": "Niggler",
|
||||
"description": "Compound File Binary File Format extractor",
|
||||
"keywords": [ "cfb", "compression", "office" ],
|
||||
|
Loading…
Reference in New Issue
Block a user