version bump 1.05: non-display char strict search
This commit is contained in:
parent
98e9d2e641
commit
17b1a8de5a
@ -2,7 +2,7 @@
|
||||
"env": { "shared-node-browser":true },
|
||||
"globals": {},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 3,
|
||||
"ecmaVersion": 3
|
||||
},
|
||||
"plugins": [ "html", "json" ],
|
||||
"extends": "eslint:recommended",
|
||||
@ -12,7 +12,13 @@
|
||||
"curly": 0,
|
||||
"no-bitwise": 0,
|
||||
"no-console": 0,
|
||||
"no-control-regex": 0,
|
||||
"no-empty": 0,
|
||||
"no-trailing-spaces": 2,
|
||||
"no-use-before-define": [ 1, {
|
||||
"functions":false, "classes":true, "variables":false
|
||||
}],
|
||||
"no-useless-escape": 0,
|
||||
"semi": [ 2, "always" ]
|
||||
}
|
||||
}
|
||||
|
4
Makefile
4
Makefile
@ -39,9 +39,9 @@ clean-data:
|
||||
|
||||
.PHONY: init
|
||||
init: ## Initial setup for development
|
||||
if [ ! -e test_files ]; then git clone https://github.com/SheetJS/test_files; fi
|
||||
if [ ! -e test_files ]; then git clone --depth=1 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
|
||||
if [ ! -e test_files_pres ]; then git clone --depth=1 https://github.com/SheetJS/test_files_pres; fi
|
||||
cd test_files_pres; git pull
|
||||
|
||||
.PHONY: dist
|
||||
|
@ -98,6 +98,7 @@ controls the behavior:
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `"base64"` | string: Base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `"file"` | string: path of file that will be created (nodejs only) |
|
||||
| (default) | buffer if available, array of 8-bit unsigned int otherwise |
|
||||
|
||||
`CFB.writeFile(cfb, filename, opts)` creates a file with the specified name.
|
||||
|
@ -3,8 +3,7 @@ var Base64 = (function make_b64(){
|
||||
return {
|
||||
encode: function(input/*:string*/)/*:string*/ {
|
||||
var o = "";
|
||||
var c1/*:number*/, c2/*:number*/, c3/*:number*/;
|
||||
var e1/*:number*/, e2/*:number*/, e3/*:number*/, e4/*:number*/;
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
for(var i = 0; i < input.length; ) {
|
||||
c1 = input.charCodeAt(i++);
|
||||
e1 = (c1 >> 2);
|
||||
@ -23,9 +22,7 @@ var Base64 = (function make_b64(){
|
||||
},
|
||||
decode: function b64_decode(input/*:string*/)/*:string*/ {
|
||||
var o = "";
|
||||
var c1/*:number*/, c2/*:number*/, c3/*:number*/;
|
||||
var e1/*:number*/, e2/*:number*/, e3/*:number*/, e4/*:number*/;
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
input = input.replace(/[^\w\+\/\=]/g, "");
|
||||
for(var i = 0; i < input.length;) {
|
||||
e1 = map.indexOf(input.charAt(i++));
|
||||
|
@ -1,3 +1,3 @@
|
||||
/* [MS-CFB] v20130118 */
|
||||
/* [MS-CFB] v20171201 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
|
||||
|
@ -1 +1 @@
|
||||
exports.version = '1.0.3';
|
||||
exports.version = '1.0.5';
|
||||
|
@ -1,4 +1,5 @@
|
||||
function parse(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ {
|
||||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
|
||||
var mver = 3;
|
||||
var ssz = 512;
|
||||
var nmfs = 0; // number of mini FAT sectors
|
||||
|
@ -16,7 +16,7 @@ function build_full_paths(FI/*:CFBFileIndex*/, FP/*:Array<string>*/, Paths/*:Arr
|
||||
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) {
|
||||
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];
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
|
||||
function find(cfb/*:CFBContainer*/, path/*:string*/)/*:?CFBEntry*/ {
|
||||
//return cfb.find(path);
|
||||
var UCFullPaths/*:Array<string>*/ = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });
|
||||
var UCPaths/*:Array<string>*/ = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });
|
||||
var k/*:boolean*/ = false;
|
||||
@ -10,10 +9,12 @@ function find(cfb/*:CFBContainer*/, path/*:string*/)/*:?CFBEntry*/ {
|
||||
var w/*:number*/ = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
||||
if(w !== -1) return cfb.FileIndex[w];
|
||||
|
||||
UCPath = UCPath.replace(chr0,'').replace(chr1,'!');
|
||||
var m = !UCPath.match(chr1);
|
||||
UCPath = UCPath.replace(chr0,'');
|
||||
if(m) UCPath = UCPath.replace(chr1,'!');
|
||||
for(w = 0; w < UCFullPaths.length; ++w) {
|
||||
if(UCFullPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if(UCPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCFullPaths[w].replace(chr1,'!') : UCFullPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCPaths[w].replace(chr1,'!') : UCPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
23
cfb.flow.js
23
cfb.flow.js
@ -9,8 +9,7 @@ var Base64 = (function make_b64(){
|
||||
return {
|
||||
encode: function(input/*:string*/)/*:string*/ {
|
||||
var o = "";
|
||||
var c1/*:number*/, c2/*:number*/, c3/*:number*/;
|
||||
var e1/*:number*/, e2/*:number*/, e3/*:number*/, e4/*:number*/;
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
for(var i = 0; i < input.length; ) {
|
||||
c1 = input.charCodeAt(i++);
|
||||
e1 = (c1 >> 2);
|
||||
@ -29,9 +28,7 @@ var Base64 = (function make_b64(){
|
||||
},
|
||||
decode: function b64_decode(input/*:string*/)/*:string*/ {
|
||||
var o = "";
|
||||
var c1/*:number*/, c2/*:number*/, c3/*:number*/;
|
||||
var e1/*:number*/, e2/*:number*/, e3/*:number*/, e4/*:number*/;
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
input = input.replace(/[^\w\+\/\=]/g, "");
|
||||
for(var i = 0; i < input.length;) {
|
||||
e1 = map.indexOf(input.charAt(i++));
|
||||
@ -177,10 +174,10 @@ type SectorList = {
|
||||
}
|
||||
type CFBFiles = {[n:string]:CFBEntry};
|
||||
*/
|
||||
/* [MS-CFB] v20130118 */
|
||||
/* [MS-CFB] v20171201 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
|
||||
exports.version = '1.0.3';
|
||||
exports.version = '1.0.5';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -204,6 +201,7 @@ function filename(p/*:string*/)/*:string*/ {
|
||||
var fs/*:: = require('fs'); */;
|
||||
function get_fs() { return fs || (fs = require('fs')); }
|
||||
function parse(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ {
|
||||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
|
||||
var mver = 3;
|
||||
var ssz = 512;
|
||||
var nmfs = 0; // number of mini FAT sectors
|
||||
@ -360,7 +358,7 @@ function build_full_paths(FI/*:CFBFileIndex*/, FP/*:Array<string>*/, Paths/*:Arr
|
||||
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) {
|
||||
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];
|
||||
}
|
||||
@ -752,7 +750,6 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/ {
|
||||
}
|
||||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
|
||||
function find(cfb/*:CFBContainer*/, path/*:string*/)/*:?CFBEntry*/ {
|
||||
//return cfb.find(path);
|
||||
var UCFullPaths/*:Array<string>*/ = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });
|
||||
var UCPaths/*:Array<string>*/ = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });
|
||||
var k/*:boolean*/ = false;
|
||||
@ -762,10 +759,12 @@ function find(cfb/*:CFBContainer*/, path/*:string*/)/*:?CFBEntry*/ {
|
||||
var w/*:number*/ = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
||||
if(w !== -1) return cfb.FileIndex[w];
|
||||
|
||||
UCPath = UCPath.replace(chr0,'').replace(chr1,'!');
|
||||
var m = !UCPath.match(chr1);
|
||||
UCPath = UCPath.replace(chr0,'');
|
||||
if(m) UCPath = UCPath.replace(chr1,'!');
|
||||
for(w = 0; w < UCFullPaths.length; ++w) {
|
||||
if(UCFullPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if(UCPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCFullPaths[w].replace(chr1,'!') : UCFullPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCPaths[w].replace(chr1,'!') : UCPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
23
cfb.js
23
cfb.js
@ -9,8 +9,7 @@ var Base64 = (function make_b64(){
|
||||
return {
|
||||
encode: function(input) {
|
||||
var o = "";
|
||||
var c1, c2, c3;
|
||||
var e1, e2, e3, e4;
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
for(var i = 0; i < input.length; ) {
|
||||
c1 = input.charCodeAt(i++);
|
||||
e1 = (c1 >> 2);
|
||||
@ -29,9 +28,7 @@ var Base64 = (function make_b64(){
|
||||
},
|
||||
decode: function b64_decode(input) {
|
||||
var o = "";
|
||||
var c1, c2, c3;
|
||||
var e1, e2, e3, e4;
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
input = input.replace(/[^\w\+\/\=]/g, "");
|
||||
for(var i = 0; i < input.length;) {
|
||||
e1 = map.indexOf(input.charAt(i++));
|
||||
@ -159,10 +156,10 @@ function new_buf(sz) {
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-CFB] v20130118 */
|
||||
/* [MS-CFB] v20171201 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '1.0.3';
|
||||
exports.version = '1.0.5';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l, r) {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -186,6 +183,7 @@ function filename(p) {
|
||||
var fs;
|
||||
function get_fs() { return fs || (fs = require('fs')); }
|
||||
function parse(file, options) {
|
||||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
|
||||
var mver = 3;
|
||||
var ssz = 512;
|
||||
var nmfs = 0; // number of mini FAT sectors
|
||||
@ -342,7 +340,7 @@ function build_full_paths(FI, FP, Paths) {
|
||||
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) {
|
||||
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];
|
||||
}
|
||||
@ -729,7 +727,6 @@ if(file.size > 0 && file.size < 0x1000) {
|
||||
}
|
||||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
|
||||
function find(cfb, path) {
|
||||
//return cfb.find(path);
|
||||
var UCFullPaths = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });
|
||||
var UCPaths = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });
|
||||
var k = false;
|
||||
@ -739,10 +736,12 @@ function find(cfb, path) {
|
||||
var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
||||
if(w !== -1) return cfb.FileIndex[w];
|
||||
|
||||
UCPath = UCPath.replace(chr0,'').replace(chr1,'!');
|
||||
var m = !UCPath.match(chr1);
|
||||
UCPath = UCPath.replace(chr0,'');
|
||||
if(m) UCPath = UCPath.replace(chr1,'!');
|
||||
for(w = 0; w < UCFullPaths.length; ++w) {
|
||||
if(UCFullPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if(UCPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCFullPaths[w].replace(chr1,'!') : UCFullPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCPaths[w].replace(chr1,'!') : UCPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
23
dist/cfb.js
vendored
23
dist/cfb.js
vendored
@ -9,8 +9,7 @@ var Base64 = (function make_b64(){
|
||||
return {
|
||||
encode: function(input) {
|
||||
var o = "";
|
||||
var c1, c2, c3;
|
||||
var e1, e2, e3, e4;
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
for(var i = 0; i < input.length; ) {
|
||||
c1 = input.charCodeAt(i++);
|
||||
e1 = (c1 >> 2);
|
||||
@ -29,9 +28,7 @@ var Base64 = (function make_b64(){
|
||||
},
|
||||
decode: function b64_decode(input) {
|
||||
var o = "";
|
||||
var c1, c2, c3;
|
||||
var e1, e2, e3, e4;
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
input = input.replace(/[^\w\+\/\=]/g, "");
|
||||
for(var i = 0; i < input.length;) {
|
||||
e1 = map.indexOf(input.charAt(i++));
|
||||
@ -159,10 +156,10 @@ function new_buf(sz) {
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-CFB] v20130118 */
|
||||
/* [MS-CFB] v20171201 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '1.0.3';
|
||||
exports.version = '1.0.5';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l, r) {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -186,6 +183,7 @@ function filename(p) {
|
||||
var fs;
|
||||
function get_fs() { return fs || (fs = require('fs')); }
|
||||
function parse(file, options) {
|
||||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
|
||||
var mver = 3;
|
||||
var ssz = 512;
|
||||
var nmfs = 0; // number of mini FAT sectors
|
||||
@ -342,7 +340,7 @@ function build_full_paths(FI, FP, Paths) {
|
||||
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) {
|
||||
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];
|
||||
}
|
||||
@ -729,7 +727,6 @@ if(file.size > 0 && file.size < 0x1000) {
|
||||
}
|
||||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
|
||||
function find(cfb, path) {
|
||||
//return cfb.find(path);
|
||||
var UCFullPaths = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });
|
||||
var UCPaths = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });
|
||||
var k = false;
|
||||
@ -739,10 +736,12 @@ function find(cfb, path) {
|
||||
var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
||||
if(w !== -1) return cfb.FileIndex[w];
|
||||
|
||||
UCPath = UCPath.replace(chr0,'').replace(chr1,'!');
|
||||
var m = !UCPath.match(chr1);
|
||||
UCPath = UCPath.replace(chr0,'');
|
||||
if(m) UCPath = UCPath.replace(chr1,'!');
|
||||
for(w = 0; w < UCFullPaths.length; ++w) {
|
||||
if(UCFullPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if(UCPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCFullPaths[w].replace(chr1,'!') : UCFullPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCPaths[w].replace(chr1,'!') : UCPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
2
dist/cfb.min.js
vendored
2
dist/cfb.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/cfb.min.map
vendored
2
dist/cfb.min.map
vendored
File diff suppressed because one or more lines are too long
16
dist/xlscfb.js
vendored
16
dist/xlscfb.js
vendored
@ -35,10 +35,10 @@ type SectorList = {
|
||||
}
|
||||
type CFBFiles = {[n:string]:CFBEntry};
|
||||
*/
|
||||
/* [MS-CFB] v20130118 */
|
||||
/* [MS-CFB] v20171201 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
|
||||
exports.version = '1.0.3';
|
||||
exports.version = '1.0.5';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -62,6 +62,7 @@ function filename(p/*:string*/)/*:string*/ {
|
||||
var fs/*:: = require('fs'); */;
|
||||
function get_fs() { return fs || (fs = require('fs')); }
|
||||
function parse(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ {
|
||||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
|
||||
var mver = 3;
|
||||
var ssz = 512;
|
||||
var nmfs = 0; // number of mini FAT sectors
|
||||
@ -218,7 +219,7 @@ function build_full_paths(FI/*:CFBFileIndex*/, FP/*:Array<string>*/, Paths/*:Arr
|
||||
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) {
|
||||
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];
|
||||
}
|
||||
@ -610,7 +611,6 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/ {
|
||||
}
|
||||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
|
||||
function find(cfb/*:CFBContainer*/, path/*:string*/)/*:?CFBEntry*/ {
|
||||
//return cfb.find(path);
|
||||
var UCFullPaths/*:Array<string>*/ = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });
|
||||
var UCPaths/*:Array<string>*/ = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });
|
||||
var k/*:boolean*/ = false;
|
||||
@ -620,10 +620,12 @@ function find(cfb/*:CFBContainer*/, path/*:string*/)/*:?CFBEntry*/ {
|
||||
var w/*:number*/ = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
||||
if(w !== -1) return cfb.FileIndex[w];
|
||||
|
||||
UCPath = UCPath.replace(chr0,'').replace(chr1,'!');
|
||||
var m = !UCPath.match(chr1);
|
||||
UCPath = UCPath.replace(chr0,'');
|
||||
if(m) UCPath = UCPath.replace(chr1,'!');
|
||||
for(w = 0; w < UCFullPaths.length; ++w) {
|
||||
if(UCFullPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if(UCPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCFullPaths[w].replace(chr1,'!') : UCFullPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCPaths[w].replace(chr1,'!') : UCPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
|
||||
<script>
|
||||
/*jshint browser:true */
|
||||
/* eslint-env browser */
|
||||
/*global Uint8Array, ArrayBuffer, console */
|
||||
/*global Uint8Array, ArrayBuffer, console, alert */
|
||||
/*global CFB, out, PRINTJ, saveAs */
|
||||
/* exported savefile, download_file */
|
||||
/* eslint no-use-before-define:0 */
|
||||
@ -151,9 +151,9 @@ var savefile = (function() {
|
||||
|
||||
return function savefile() {
|
||||
if(!global_cfb) return alert("Must load a file first!");
|
||||
console.log(global_cfb);
|
||||
if(typeof console !== 'undefined') console.log(global_cfb);
|
||||
var data = CFB.write(global_cfb, {type:'binary'});
|
||||
console.log(data);
|
||||
if(typeof console !== 'undefined') console.log(data);
|
||||
saveAs(new Blob([s2ab(data)],{type:"application/octet-stream"}), "sheetjs.xls");
|
||||
};
|
||||
})();
|
||||
@ -168,7 +168,7 @@ var download_file = (function() {
|
||||
|
||||
return function download_file(i) {
|
||||
if(!global_cfb) return alert("Must load a file first!");
|
||||
console.log(global_cfb);
|
||||
if(typeof console !== 'undefined') console.log(global_cfb);
|
||||
var file = global_cfb.FileIndex[i], data = file.content;
|
||||
saveAs(new Blob([a2ab(data)],{type:"application/octet-stream"}), file.name);
|
||||
};
|
||||
|
10
package.json
10
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cfb",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"author": "sheetjs",
|
||||
"description": "Compound File Binary File Format extractor",
|
||||
"keywords": [
|
||||
@ -19,15 +19,15 @@
|
||||
"fs": false
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": "^2.12.1",
|
||||
"printj": "~1.1.1"
|
||||
"commander": "^2.14.1",
|
||||
"printj": "~1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"crc-32": "~1.1.1",
|
||||
"crc-32": "~1.2.0",
|
||||
"mocha": "~2.5.3",
|
||||
"blanket": "~1.2.3",
|
||||
"@sheetjs/uglify-js": "~2.7.3",
|
||||
"@types/node": "^8.0.7",
|
||||
"@types/node": "^8.5.9",
|
||||
"@types/commander": "^2.9.0",
|
||||
"dtslint": "~0.1.2",
|
||||
"typescript": "2.2.0"
|
||||
|
388
shim.js
388
shim.js
@ -1,343 +1,49 @@
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
|
||||
if (!Object.keys) {
|
||||
Object.keys = (function () {
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty,
|
||||
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
|
||||
dontEnums = [
|
||||
'toString',
|
||||
'toLocaleString',
|
||||
'valueOf',
|
||||
'hasOwnProperty',
|
||||
'isPrototypeOf',
|
||||
'propertyIsEnumerable',
|
||||
'constructor'
|
||||
],
|
||||
dontEnumsLength = dontEnums.length;
|
||||
/* shim.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* ES3/5 Compatibility shims and other utilities for older browsers. */
|
||||
|
||||
return function (obj) {
|
||||
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
|
||||
|
||||
var result = [];
|
||||
|
||||
for (var prop in obj) {
|
||||
if (hasOwnProperty.call(obj, prop)) result.push(prop);
|
||||
}
|
||||
|
||||
if (hasDontEnumBug) {
|
||||
for (var i=0; i < dontEnumsLength; i++) {
|
||||
if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
|
||||
if (!Array.prototype.filter)
|
||||
{
|
||||
Array.prototype.filter = function(fun /*, thisp */)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
if (this == null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun != "function")
|
||||
throw new TypeError();
|
||||
|
||||
var res = [];
|
||||
var thisp = arguments[1];
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (i in t)
|
||||
{
|
||||
var val = t[i]; // in case fun mutates this
|
||||
if (fun.call(thisp, val, i, t))
|
||||
res.push(val);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
|
||||
if (!String.prototype.trim) {
|
||||
String.prototype.trim = function () {
|
||||
return this.replace(/^\s+|\s+$/g, '');
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
|
||||
if (!Array.prototype.forEach)
|
||||
{
|
||||
Array.prototype.forEach = function(fun /*, thisArg */)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
if (this === void 0 || this === null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun !== "function")
|
||||
throw new TypeError();
|
||||
|
||||
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (i in t)
|
||||
fun.call(thisArg, t[i], i, t);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Production steps of ECMA-262, Edition 5, 15.4.4.19
|
||||
// Reference: http://es5.github.com/#x15.4.4.19
|
||||
if (!Array.prototype.map) {
|
||||
Array.prototype.map = function(callback, thisArg) {
|
||||
|
||||
var T, A, k;
|
||||
|
||||
if (this == null) {
|
||||
throw new TypeError(" this is null or not defined");
|
||||
}
|
||||
|
||||
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
|
||||
var O = Object(this);
|
||||
|
||||
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
|
||||
// 3. Let len be ToUint32(lenValue).
|
||||
var len = O.length >>> 0;
|
||||
|
||||
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
||||
// See: http://es5.github.com/#x9.11
|
||||
if (typeof callback !== "function") {
|
||||
throw new TypeError(callback + " is not a function");
|
||||
}
|
||||
|
||||
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||
if (thisArg) {
|
||||
T = thisArg;
|
||||
}
|
||||
|
||||
// 6. Let A be a new array created as if by the expression new Array(len) where Array is
|
||||
// the standard built-in constructor with that name and len is the value of len.
|
||||
A = new Array(len);
|
||||
|
||||
// 7. Let k be 0
|
||||
k = 0;
|
||||
|
||||
// 8. Repeat, while k < len
|
||||
while(k < len) {
|
||||
|
||||
var kValue, mappedValue;
|
||||
|
||||
// a. Let Pk be ToString(k).
|
||||
// This is implicit for LHS operands of the in operator
|
||||
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
|
||||
// This step can be combined with c
|
||||
// c. If kPresent is true, then
|
||||
if (k in O) {
|
||||
|
||||
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
|
||||
kValue = O[ k ];
|
||||
|
||||
// ii. Let mappedValue be the result of calling the Call internal method of callback
|
||||
// with T as the this value and argument list containing kValue, k, and O.
|
||||
mappedValue = callback.call(T, kValue, k, O);
|
||||
|
||||
// iii. Call the DefineOwnProperty internal method of A with arguments
|
||||
// Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
|
||||
// and false.
|
||||
|
||||
// In browsers that support Object.defineProperty, use the following:
|
||||
// Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
|
||||
|
||||
// For best browser support, use the following:
|
||||
A[ k ] = mappedValue;
|
||||
}
|
||||
// d. Increase k by 1.
|
||||
k++;
|
||||
}
|
||||
|
||||
// 9. return A
|
||||
return A;
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
|
||||
if (!Array.prototype.indexOf) {
|
||||
Array.prototype.indexOf = function (searchElement, fromIndex) {
|
||||
if ( this === undefined || this === null ) {
|
||||
throw new TypeError( '"this" is null or not defined' );
|
||||
}
|
||||
|
||||
var length = this.length >>> 0; // Hack to convert object.length to a UInt32
|
||||
|
||||
fromIndex = +fromIndex || 0;
|
||||
|
||||
if (Math.abs(fromIndex) === Infinity) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
|
||||
if (fromIndex < 0) {
|
||||
fromIndex += length;
|
||||
if (fromIndex < 0) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (;fromIndex < length; fromIndex++) {
|
||||
if (this[fromIndex] === searchElement) {
|
||||
return fromIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
|
||||
|
||||
if (! Array.isArray) {
|
||||
Array.isArray = function(obj) {
|
||||
return Object.prototype.toString.call(obj) === "[object Array]";
|
||||
};
|
||||
}
|
||||
|
||||
// https://github.com/ttaubert/node-arraybuffer-slice
|
||||
// (c) 2013 Tim Taubert <tim@timtaubert.de>
|
||||
// arraybuffer-slice may be freely distributed under the MIT license.
|
||||
|
||||
"use strict";
|
||||
|
||||
if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
|
||||
ArrayBuffer.prototype.slice = function (begin, end) {
|
||||
begin = (begin|0) || 0;
|
||||
var num = this.byteLength;
|
||||
end = end === (void 0) ? num : (end|0);
|
||||
|
||||
// Handle negative values.
|
||||
if (begin < 0) begin += num;
|
||||
if (end < 0) end += num;
|
||||
|
||||
if (num === 0 || begin >= num || begin >= end) {
|
||||
return new ArrayBuffer(0);
|
||||
}
|
||||
|
||||
var length = Math.min(num - begin, end - begin);
|
||||
var target = new ArrayBuffer(length);
|
||||
var targetArray = new Uint8Array(target);
|
||||
targetArray.set(new Uint8Array(this, begin, length));
|
||||
return target;
|
||||
};
|
||||
}
|
||||
|
||||
// https://github.com/davidchambers/Base64.js
|
||||
// (C) 2015 David Chambers
|
||||
// Base64.js may be freely distributed under the Apache 2.0 License.
|
||||
;(function () {
|
||||
|
||||
var object =
|
||||
typeof exports != 'undefined' ? exports :
|
||||
typeof self != 'undefined' ? self : // #8: web workers
|
||||
$.global; // #31: ExtendScript
|
||||
|
||||
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
|
||||
function InvalidCharacterError(message) {
|
||||
this.message = message;
|
||||
}
|
||||
InvalidCharacterError.prototype = new Error;
|
||||
InvalidCharacterError.prototype.name = 'InvalidCharacterError';
|
||||
|
||||
// encoder
|
||||
// [https://gist.github.com/999166] by [https://github.com/nignag]
|
||||
object.btoa || (
|
||||
object.btoa = function (input) {
|
||||
var str = String(input);
|
||||
for (
|
||||
// initialize result and counter
|
||||
var block, charCode, idx = 0, map = chars, output = '';
|
||||
// if the next str index does not exist:
|
||||
// change the mapping table to "="
|
||||
// check if d has no fractional digits
|
||||
str.charAt(idx | 0) || (map = '=', idx % 1);
|
||||
// "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
|
||||
output += map.charAt(63 & block >> 8 - idx % 1 * 8)
|
||||
) {
|
||||
charCode = str.charCodeAt(idx += 3/4);
|
||||
if (charCode > 0xFF) {
|
||||
throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
|
||||
}
|
||||
block = block << 8 | charCode;
|
||||
}
|
||||
return output;
|
||||
});
|
||||
|
||||
// decoder
|
||||
// [https://gist.github.com/1020396] by [https://github.com/atk]
|
||||
object.atob || (
|
||||
object.atob = function (input) {
|
||||
var str = String(input).replace(/[=]+$/, ''); // #31: ExtendScript bad parse of /=
|
||||
if (str.length % 4 == 1) {
|
||||
throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded.");
|
||||
}
|
||||
for (
|
||||
// initialize result and counters
|
||||
var bc = 0, bs, buffer, idx = 0, output = '';
|
||||
// get next character
|
||||
buffer = str.charAt(idx++);
|
||||
// character found in table? initialize bit storage and add its ascii value;
|
||||
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
|
||||
// and if not first of each 4 characters,
|
||||
// convert the first 8 bits to one ascii character
|
||||
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
|
||||
) {
|
||||
// try to find character in table (0-63, not found => -1)
|
||||
buffer = chars.indexOf(buffer);
|
||||
}
|
||||
return output;
|
||||
});
|
||||
}());
|
||||
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
|
||||
if (!Date.prototype.toISOString) {
|
||||
(function() {
|
||||
|
||||
function pad(number) {
|
||||
if (number < 10) {
|
||||
return '0' + number;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
Date.prototype.toISOString = function() {
|
||||
return this.getUTCFullYear() +
|
||||
'-' + pad(this.getUTCMonth() + 1) +
|
||||
'-' + pad(this.getUTCDate()) +
|
||||
'T' + pad(this.getUTCHours()) +
|
||||
':' + pad(this.getUTCMinutes()) +
|
||||
':' + pad(this.getUTCSeconds()) +
|
||||
'.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) +
|
||||
'Z';
|
||||
};
|
||||
|
||||
}());
|
||||
}
|
||||
|
||||
// note: MDN shim will not work in IE
|
||||
if(typeof Uint8Array !== 'undefined' && !Uint8Array.prototype.slice) Uint8Array.prototype.slice = function(start, end) {
|
||||
if(start < 0) { start += this.length; if(start < 0) start = 0; }
|
||||
if(start >= this.length) return new Uint8Array(0);
|
||||
if(end == null) end = this.length;
|
||||
if(end < 0) { end += this.length; if(end < 0) end = 0; }
|
||||
if(end > this.length) end = this.length;
|
||||
var out = new Uint8Array(end - start);
|
||||
while(start <= --end) out[end - start] = this[end];
|
||||
return out;
|
||||
if(!Array.prototype.forEach) Array.prototype.forEach = function(cb) {
|
||||
var len = (this.length>>>0), self = (arguments[1]||void 0);
|
||||
for(var i=0; i<len; ++i) if(i in this) self ? cb.call(self, this[i], i, this) : cb(this[i], i, this);
|
||||
};
|
||||
|
||||
if(!Array.prototype.map) Array.prototype.map = function(cb) {
|
||||
var len = (this.length>>>0), self = (arguments[1]||void 0), A = new Array(len);
|
||||
for(var i=0; i<len; ++i) if(i in this) A[i] = self ? cb.call(self, this[i], i, this) : cb(this[i], i, this);
|
||||
return A;
|
||||
};
|
||||
|
||||
if(!Array.prototype.indexOf) Array.prototype.indexOf = function(needle) {
|
||||
var len = (this.length>>>0), i = ((arguments[1]|0)||0);
|
||||
for(i<0 && (i+=len)<0 && (i=0); i<len; ++i) if(this[i] === needle) return i;
|
||||
return -1;
|
||||
};
|
||||
|
||||
if(!Array.isArray) Array.isArray = function(obj) { return Object.prototype.toString.call(obj) === "[object Array]"; };
|
||||
|
||||
if(typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) ArrayBuffer.prototype.slice = function(start, end) {
|
||||
if(start == null) start = 0;
|
||||
if(start < 0) { start += this.byteLength; if(start < 0) start = 0; }
|
||||
if(start >= this.byteLength) return new Uint8Array(0);
|
||||
if(end == null) end = this.byteLength;
|
||||
if(end < 0) { end += this.byteLength; if(end < 0) end = 0; }
|
||||
if(end > this.byteLength) end = this.byteLength;
|
||||
if(start > end) return new Uint8Array(0);
|
||||
var out = new ArrayBuffer(end - start);
|
||||
var view = new Uint8Array(out);
|
||||
var data = new Uint8Array(this, start, end - start)
|
||||
/* IE10 should have Uint8Array#set */
|
||||
if(view.set) view.set(data); else while(start <= --end) view[end - start] = data[end];
|
||||
return out;
|
||||
};
|
||||
if(typeof Uint8Array !== 'undefined' && !Uint8Array.prototype.slice) Uint8Array.prototype.slice = function(start, end) {
|
||||
if(start == null) start = 0;
|
||||
if(start < 0) { start += this.length; if(start < 0) start = 0; }
|
||||
if(start >= this.length) return new Uint8Array(0);
|
||||
if(end == null) end = this.length;
|
||||
if(end < 0) { end += this.length; if(end < 0) end = 0; }
|
||||
if(end > this.length) end = this.length;
|
||||
if(start > end) return new Uint8Array(0);
|
||||
var out = new Uint8Array(end - start);
|
||||
while(start <= --end) out[end - start] = this[end];
|
||||
return out;
|
||||
};
|
||||
|
28
test.js
28
test.js
@ -26,6 +26,7 @@ var files = fs.readdirSync('test_files').filter(ffunc);
|
||||
var f2011 = fs.readdirSync('test_files/2011').filter(ffunc);
|
||||
var f2013 = fs.readdirSync('test_files/2013').filter(ffunc);
|
||||
var fpres = fs.readdirSync('test_files_pres').filter(ffunc);
|
||||
var fxlsx = fs.readdirSync('test_files').filter(function(x) { return x.slice(-5) == ".xlsx"; });
|
||||
|
||||
var dir = "./test_files/";
|
||||
var TYPE = "buffer";
|
||||
@ -34,7 +35,7 @@ var names = [
|
||||
["!DocumentSummaryInformation", "\u0005"],
|
||||
["!SummaryInformation", "\u0005"],
|
||||
["!CompObj", "\u0001"],
|
||||
["!DataSpaces", "\u0006"],
|
||||
["/!DataSpaces/Version", "\u0006"],
|
||||
["!DRMContent", "\u0009"],
|
||||
["!DRMViewerContent", "\u0009"],
|
||||
["!Ole", "\u0001"]
|
||||
@ -47,6 +48,7 @@ function parsetest(x, cfb) {
|
||||
case '.xls': if(!CFB.find(cfb, 'Workbook') && !CFB.find(cfb, 'Book')) throw new Error("Cannot find workbook for " + x); break;
|
||||
case '.ppt': if(!CFB.find(cfb, 'PowerPoint Document')) throw new Error("Cannot find presentation for " + x); break;
|
||||
case '.doc': if(!CFB.find(cfb, 'WordDocument') && !CFB.find(cfb, 'Word Document')) throw new Error("Cannot find doc for " + x); break;
|
||||
case 'xlsx': if(!CFB.find(cfb, 'Workbook') && !CFB.find(cfb, 'Book') && !CFB.find(cfb, 'WordDocument') && !CFB.find(cfb, 'EncryptedPackage') && !CFB.find(cfb, 'EncryptionInfo')) throw new Error("Cannot find workbook or encryption for " + x); break;
|
||||
}
|
||||
});
|
||||
it('should find absolute path', function() {
|
||||
@ -54,6 +56,7 @@ function parsetest(x, cfb) {
|
||||
case '.xls': if(!CFB.find(cfb, '/Workbook') && !CFB.find(cfb, '/Book')) throw new Error("Cannot find workbook for " + x); break;
|
||||
case '.ppt': if(!CFB.find(cfb, '/PowerPoint Document')) throw new Error("Cannot find presentation for " + x); break;
|
||||
case '.doc': if(!CFB.find(cfb, '/WordDocument') && !CFB.find(cfb, '/Word Document')) throw new Error("Cannot find doc for " + x); break;
|
||||
case 'xlsx': if(!CFB.find(cfb, '/Workbook') && !CFB.find(cfb, '/Book') && !CFB.find(cfb, '/WordDocument') && !CFB.find(cfb, '/EncryptedPackage') && !CFB.find(cfb, '/EncryptionInfo')) throw new Error("Cannot find workbook or encryption for " + x); break;
|
||||
}
|
||||
});
|
||||
it('should handle "!" aliases', function() {
|
||||
@ -69,7 +72,7 @@ function parsetest(x, cfb) {
|
||||
data = CFB.write(cfb, {type:TYPE});
|
||||
newcfb = CFB.read(data, {type:TYPE});
|
||||
});
|
||||
it('should preserve content', function() {
|
||||
if(x.substr(-4) !== "xlsx") it('should preserve content', function() {
|
||||
var _old, _new;
|
||||
switch(x.substr(-4)) {
|
||||
case '.xls':
|
||||
@ -120,6 +123,27 @@ describe('should parse test files', function() {
|
||||
parsetest(x, cfb);
|
||||
});
|
||||
});
|
||||
fxlsx.forEach(function(x) {
|
||||
it('should parse ' + x, function() {
|
||||
try {
|
||||
var cfb = CFB.read('./test_files/' + x, {type: "file"});
|
||||
parsetest(x, cfb);
|
||||
} catch(e) {
|
||||
if(e.message.match(/CFB file size /)) return;
|
||||
if(!e.message.match(/Header Signature: Expected d0cf11e0a1b11ae1 saw /)) throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
it('should recognize correct magic number', function() {
|
||||
var cfb = CFB.read('./test_files/AutoFilter.xls', {type: "file"});
|
||||
if(!CFB.find(cfb, '!CompObj')) throw new Error("Could not find !CompObj");
|
||||
if(!CFB.find(cfb, '\u0001CompObj')) throw new Error("Could not find 1CompObj");
|
||||
if(CFB.find(cfb, '\u0005CompObj')) throw new Error("Found 5CompObj");
|
||||
|
||||
if(!CFB.find(cfb, '!DocumentSummaryInformation')) throw new Error("Could not find !DSI");
|
||||
if(!CFB.find(cfb, '\u0005DocumentSummaryInformation')) throw new Error("Could not find 5DSI");
|
||||
if(CFB.find(cfb, '\u0001DocumentSummaryInformation')) throw new Error("Found 1DSI");
|
||||
});
|
||||
});
|
||||
|
||||
var cp = 'custom_properties.xls';
|
||||
|
@ -10,13 +10,14 @@ const sprintf = PRINTJ.sprintf;
|
||||
program
|
||||
.version(X.version)
|
||||
.usage('[options] <file> [subfiles...]')
|
||||
.option('-q, --quiet', 'process but do not report')
|
||||
.option('-l, --list-files', 'list files')
|
||||
.option('-z, --dump', 'dump internal representation but do not extract')
|
||||
.option('-r, --repair', 'attempt to repair and garbage-collect archive')
|
||||
.option('-c, --create', 'create file')
|
||||
.option('-a, --append', 'add files to CFB (overwrite existing data)')
|
||||
.option('-d, --delete', 'delete files from CFB')
|
||||
.option('-O, --to-stdout', 'extract raw contents to stdout')
|
||||
.option('-z, --dump', 'dump internal representation but do not extract')
|
||||
.option('-q, --quiet', 'process but do not report')
|
||||
.option('--dev', 'development mode')
|
||||
.option('--read', 'read but do not print out contents');
|
||||
|
||||
@ -110,16 +111,18 @@ if(program.delete) {
|
||||
|
||||
if(program.args.length > 1) {
|
||||
program.args.slice(1).forEach((x: string) => {
|
||||
const data: X.CFB$Entry = X.find(cfb, x);
|
||||
const data: X.CFB$Entry = X.find(cfb, x.replace(/\\u000\d/g,"!"));
|
||||
if(!data) { console.error(x + ": file not found"); return; }
|
||||
if(data.type !== 2) { console.error(x + ": not a file"); return; }
|
||||
const idx = cfb.FileIndex.indexOf(data), path = cfb.FullPaths[idx];
|
||||
if(program.toStdout) return process.stdout.write(new Buffer(<any>data.content));
|
||||
mkdirp(path.slice(0, path.lastIndexOf("/")));
|
||||
write(path, data);
|
||||
});
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if(program.toStdout) exit(0);
|
||||
for(let i=0; i!==cfb.FullPaths.length; ++i) {
|
||||
if(!cfb.FileIndex[i].name) continue;
|
||||
if(cfb.FullPaths[i].slice(-1) === "/") mkdirp(cfb.FullPaths[i]);
|
||||
|
@ -35,10 +35,10 @@ type SectorList = {
|
||||
}
|
||||
type CFBFiles = {[n:string]:CFBEntry};
|
||||
*/
|
||||
/* [MS-CFB] v20130118 */
|
||||
/* [MS-CFB] v20171201 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
|
||||
exports.version = '1.0.3';
|
||||
exports.version = '1.0.5';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -62,6 +62,7 @@ function filename(p/*:string*/)/*:string*/ {
|
||||
var fs/*:: = require('fs'); */;
|
||||
function get_fs() { return fs || (fs = require('fs')); }
|
||||
function parse(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ {
|
||||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
|
||||
var mver = 3;
|
||||
var ssz = 512;
|
||||
var nmfs = 0; // number of mini FAT sectors
|
||||
@ -218,7 +219,7 @@ function build_full_paths(FI/*:CFBFileIndex*/, FP/*:Array<string>*/, Paths/*:Arr
|
||||
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) {
|
||||
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];
|
||||
}
|
||||
@ -610,7 +611,6 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/ {
|
||||
}
|
||||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
|
||||
function find(cfb/*:CFBContainer*/, path/*:string*/)/*:?CFBEntry*/ {
|
||||
//return cfb.find(path);
|
||||
var UCFullPaths/*:Array<string>*/ = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });
|
||||
var UCPaths/*:Array<string>*/ = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });
|
||||
var k/*:boolean*/ = false;
|
||||
@ -620,10 +620,12 @@ function find(cfb/*:CFBContainer*/, path/*:string*/)/*:?CFBEntry*/ {
|
||||
var w/*:number*/ = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
||||
if(w !== -1) return cfb.FileIndex[w];
|
||||
|
||||
UCPath = UCPath.replace(chr0,'').replace(chr1,'!');
|
||||
var m = !UCPath.match(chr1);
|
||||
UCPath = UCPath.replace(chr0,'');
|
||||
if(m) UCPath = UCPath.replace(chr1,'!');
|
||||
for(w = 0; w < UCFullPaths.length; ++w) {
|
||||
if(UCFullPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if(UCPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCFullPaths[w].replace(chr1,'!') : UCFullPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCPaths[w].replace(chr1,'!') : UCPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
16
xlscfb.js
16
xlscfb.js
@ -5,10 +5,10 @@ var DO_NOT_EXPORT_CFB = true;
|
||||
/*exported CFB */
|
||||
/*global module, require:false, process:false, Buffer:false, Uint8Array:false */
|
||||
|
||||
/* [MS-CFB] v20130118 */
|
||||
/* [MS-CFB] v20171201 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '1.0.3';
|
||||
exports.version = '1.0.5';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l, r) {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -32,6 +32,7 @@ function filename(p) {
|
||||
var fs;
|
||||
function get_fs() { return fs || (fs = require('fs')); }
|
||||
function parse(file, options) {
|
||||
if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
|
||||
var mver = 3;
|
||||
var ssz = 512;
|
||||
var nmfs = 0; // number of mini FAT sectors
|
||||
@ -188,7 +189,7 @@ function build_full_paths(FI, FP, Paths) {
|
||||
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) {
|
||||
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];
|
||||
}
|
||||
@ -575,7 +576,6 @@ if(file.size > 0 && file.size < 0x1000) {
|
||||
}
|
||||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
|
||||
function find(cfb, path) {
|
||||
//return cfb.find(path);
|
||||
var UCFullPaths = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });
|
||||
var UCPaths = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });
|
||||
var k = false;
|
||||
@ -585,10 +585,12 @@ function find(cfb, path) {
|
||||
var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
||||
if(w !== -1) return cfb.FileIndex[w];
|
||||
|
||||
UCPath = UCPath.replace(chr0,'').replace(chr1,'!');
|
||||
var m = !UCPath.match(chr1);
|
||||
UCPath = UCPath.replace(chr0,'');
|
||||
if(m) UCPath = UCPath.replace(chr1,'!');
|
||||
for(w = 0; w < UCFullPaths.length; ++w) {
|
||||
if(UCFullPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if(UCPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCFullPaths[w].replace(chr1,'!') : UCFullPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
if((m ? UCPaths[w].replace(chr1,'!') : UCPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user