version bump 1.0.3: handle negative sizes
This commit is contained in:
parent
b0e076f003
commit
25688e28fe
@ -34,3 +34,6 @@ module.file_ext=.js
|
||||
module.file_ext=.njs
|
||||
module.ignore_non_literal_requires=true
|
||||
suppress_comment= \\(.\\|\n\\)*\\$FlowIgnore
|
||||
|
||||
[lints]
|
||||
deprecated-declare-exports=off
|
||||
|
@ -1 +1 @@
|
||||
exports.version = '1.0.2';
|
||||
exports.version = '1.0.3';
|
||||
|
@ -37,14 +37,14 @@ function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sector
|
||||
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)/*:any*/);
|
||||
prep_blob(o.content, 0);
|
||||
} else {
|
||||
o.storage = 'minifat';
|
||||
if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
if(o.size < 0) o.size = 0;
|
||||
else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);
|
||||
prep_blob(o.content, 0);
|
||||
}
|
||||
}
|
||||
if(o.content) prep_blob(o.content, 0);
|
||||
files[name] = o;
|
||||
FileIndex.push(o);
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ type CFBFiles = {[n:string]:CFBEntry};
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
|
||||
exports.version = '1.0.2';
|
||||
exports.version = '1.0.3';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -495,14 +495,14 @@ function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sector
|
||||
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)/*:any*/);
|
||||
prep_blob(o.content, 0);
|
||||
} else {
|
||||
o.storage = 'minifat';
|
||||
if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
if(o.size < 0) o.size = 0;
|
||||
else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);
|
||||
prep_blob(o.content, 0);
|
||||
}
|
||||
}
|
||||
if(o.content) prep_blob(o.content, 0);
|
||||
files[name] = o;
|
||||
FileIndex.push(o);
|
||||
}
|
||||
|
8
cfb.js
8
cfb.js
@ -162,7 +162,7 @@ function new_buf(sz) {
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '1.0.2';
|
||||
exports.version = '1.0.3';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l, r) {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -477,14 +477,14 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
||||
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 && sector_list[minifat_store]) {
|
||||
if(o.size < 0) o.size = 0;
|
||||
else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);
|
||||
prep_blob(o.content, 0);
|
||||
}
|
||||
}
|
||||
if(o.content) prep_blob(o.content, 0);
|
||||
files[name] = o;
|
||||
FileIndex.push(o);
|
||||
}
|
||||
|
8
dist/cfb.js
vendored
8
dist/cfb.js
vendored
@ -162,7 +162,7 @@ function new_buf(sz) {
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '1.0.2';
|
||||
exports.version = '1.0.3';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l, r) {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -477,14 +477,14 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
||||
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 && sector_list[minifat_store]) {
|
||||
if(o.size < 0) o.size = 0;
|
||||
else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);
|
||||
prep_blob(o.content, 0);
|
||||
}
|
||||
}
|
||||
if(o.content) prep_blob(o.content, 0);
|
||||
files[name] = o;
|
||||
FileIndex.push(o);
|
||||
}
|
||||
|
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
8
dist/xlscfb.js
vendored
8
dist/xlscfb.js
vendored
@ -38,7 +38,7 @@ type CFBFiles = {[n:string]:CFBEntry};
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
|
||||
exports.version = '1.0.2';
|
||||
exports.version = '1.0.3';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -353,14 +353,14 @@ function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sector
|
||||
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)/*:any*/);
|
||||
prep_blob(o.content, 0);
|
||||
} else {
|
||||
o.storage = 'minifat';
|
||||
if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
if(o.size < 0) o.size = 0;
|
||||
else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);
|
||||
prep_blob(o.content, 0);
|
||||
}
|
||||
}
|
||||
if(o.content) prep_blob(o.content, 0);
|
||||
files[name] = o;
|
||||
FileIndex.push(o);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cfb",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"author": "sheetjs",
|
||||
"description": "Compound File Binary File Format extractor",
|
||||
"keywords": [
|
||||
|
7
test.js
7
test.js
@ -1,6 +1,7 @@
|
||||
/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*jshint mocha:true */
|
||||
/* eslint-env mocha */
|
||||
/*global process, require */
|
||||
/*::
|
||||
declare type EmptyFunc = (() => void) | null;
|
||||
@ -58,6 +59,9 @@ function parsetest(x, cfb) {
|
||||
it('should handle "!" aliases', function() {
|
||||
names.forEach(function(n) { if(CFB.find(cfb,n[0]) != CFB.find(cfb,n[1])) throw new Error("Bad name: " + n.join(" != ")); });
|
||||
});
|
||||
it('should handle size < 0', function() {
|
||||
cfb.FileIndex.forEach(function(p, i) { if(p.size < 0) throw new Error(cfb.FullPaths[i] + " size=" + p.size); });
|
||||
});
|
||||
});
|
||||
describe(x + ' should roundtrip', function() {
|
||||
var data, newcfb;
|
||||
@ -164,5 +168,8 @@ describe('api', function() {
|
||||
var file = CFB.find(cfb, '/dafuq');
|
||||
if(!file || !file.content) throw new Error("Cannot find /dafuq");
|
||||
if(file.content.length != 3) throw new Error("Bad content length " + file.content.length);
|
||||
file = CFB.find(newcfb, '/dafuq');
|
||||
if(!file || !file.content) throw new Error("Cannot find /dafuq");
|
||||
if(file.content.length != 3) throw new Error("Bad content length " + file.content.length);
|
||||
});
|
||||
});
|
||||
|
@ -36,10 +36,10 @@ if(program.create) {
|
||||
|
||||
if(!fs.existsSync(program.args[0])) die(1, "must specify a filename");
|
||||
|
||||
const opts: X.CFBParsingOptions = {type:'file'};
|
||||
const opts: X.CFB$ParsingOptions = {type:'file'};
|
||||
if(program.dev) opts.WTF = true;
|
||||
|
||||
const cfb: X.CFBContainer = X.read(program.args[0], opts);
|
||||
const cfb: X.CFB$Container = X.read(program.args[0], opts);
|
||||
if(program.quiet) exit(0);
|
||||
|
||||
if(program.dump) {
|
||||
@ -61,7 +61,7 @@ if(program.listFiles) {
|
||||
let cnt = 0, rootsize = 0, filesize = 0;
|
||||
console.log(" Length Date Time Name");
|
||||
console.log(" -------- ---- ---- ----");
|
||||
cfb.FileIndex.forEach((file: X.CFBEntry, i: number) => {
|
||||
cfb.FileIndex.forEach((file: X.CFB$Entry, i: number) => {
|
||||
switch(file.type) {
|
||||
case 5:
|
||||
basetime = file.ct || file.mt || basetime;
|
||||
@ -85,7 +85,7 @@ const mkdirp = (path: string) => { path.split("/").reduce((acc: string, p: strin
|
||||
return acc;
|
||||
}, ""); };
|
||||
|
||||
const write = (path: string, data: X.CFBEntry) => {
|
||||
const write = (path: string, data: X.CFB$Entry) => {
|
||||
logit("write", fix_string(path));
|
||||
fs.writeFileSync(path, /*::new Buffer((*/data.content/*:: :any))*/);
|
||||
};
|
||||
@ -110,7 +110,7 @@ if(program.delete) {
|
||||
|
||||
if(program.args.length > 1) {
|
||||
program.args.slice(1).forEach((x: string) => {
|
||||
const data/*:?CFBEntry*/ = X.find(cfb, x);
|
||||
const data: X.CFB$Entry = X.find(cfb, x);
|
||||
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];
|
||||
|
116
types/index.d.ts
vendored
116
types/index.d.ts
vendored
@ -5,100 +5,102 @@
|
||||
export const version: string;
|
||||
|
||||
/** Parse a buffer or array */
|
||||
export function parse(f: CFB$Blob, options?: CFBParsingOptions): CFBContainer;
|
||||
export function parse(f: CFB$Blob, options?: CFB$ParsingOptions): CFB$Container;
|
||||
|
||||
/** Read a blob or file or binary string */
|
||||
export function read(f: CFB$Blob | string, options?: CFBParsingOptions): CFBContainer;
|
||||
export function read(f: CFB$Blob | string, options?: CFB$ParsingOptions): CFB$Container;
|
||||
|
||||
/** Find a file entry given a path or file name */
|
||||
export function find(cfb: CFBContainer, path: string): CFBEntry | null;
|
||||
export function find(cfb: CFB$Container, path: string): CFB$Entry | null;
|
||||
|
||||
/** Generate a container file */
|
||||
export function write(cfb: CFBContainer, options?: any): any;
|
||||
export function write(cfb: CFB$Container, options?: any): any;
|
||||
|
||||
/** Write a container file to the filesystem */
|
||||
export function writeFile(cfb: CFBContainer, filename: string, options?: any): any;
|
||||
export function writeFile(cfb: CFB$Container, filename: string, options?: any): any;
|
||||
|
||||
/** Utility functions */
|
||||
export const utils: CFB$Utils;
|
||||
|
||||
|
||||
/** Options for read and readFile */
|
||||
export interface CFBParsingOptions {
|
||||
/** Input data encoding */
|
||||
type?: 'base64' | 'binary' | 'buffer' | 'file' | 'array';
|
||||
/** If true, throw errors when features are not understood */
|
||||
WTF?: boolean;
|
||||
/** If true, include raw data in output */
|
||||
raw?: boolean;
|
||||
export interface CFB$ParsingOptions {
|
||||
/** Input data encoding */
|
||||
type?: 'base64' | 'binary' | 'buffer' | 'file' | 'array';
|
||||
|
||||
/** If true, throw errors when features are not understood */
|
||||
WTF?: boolean;
|
||||
|
||||
/** If true, include raw data in output */
|
||||
raw?: boolean;
|
||||
}
|
||||
|
||||
export type CFB$Blob = Buffer | number[] | Uint8Array;
|
||||
|
||||
export enum CFBEntryType { unknown, storage, stream, lockbytes, property, root }
|
||||
export enum CFBStorageType { fat, minifat }
|
||||
export enum CFB$EntryType { unknown, storage, stream, lockbytes, property, root }
|
||||
export enum CFB$StorageType { fat, minifat }
|
||||
|
||||
/** CFB File Entry Object */
|
||||
export interface CFBEntry {
|
||||
/** Case-sensitive internal name */
|
||||
name: string;
|
||||
export interface CFB$Entry {
|
||||
/** Case-sensitive internal name */
|
||||
name: string;
|
||||
|
||||
/** CFB type (salient types: stream, storage) -- see CFBEntryType */
|
||||
type: number;
|
||||
/** CFB type (salient types: stream, storage) -- see CFB$EntryType */
|
||||
type: number;
|
||||
|
||||
/** Raw Content (Buffer when available, Array of bytes otherwise) */
|
||||
content: CFB$Blob;
|
||||
/** Raw Content (Buffer when available, Array of bytes otherwise) */
|
||||
content: CFB$Blob;
|
||||
|
||||
/** Creation Time */
|
||||
ct?: Date;
|
||||
/** Creation Time */
|
||||
ct?: Date;
|
||||
|
||||
/** Modification Time */
|
||||
mt?: Date;
|
||||
/** Modification Time */
|
||||
mt?: Date;
|
||||
|
||||
/** Red/Black Tree color: 0 = red, 1 = black */
|
||||
color: number;
|
||||
/** Red/Black Tree color: 0 = red, 1 = black */
|
||||
color: number;
|
||||
|
||||
/** Class ID represented as hex string */
|
||||
clsid: string;
|
||||
/** Class ID represented as hex string */
|
||||
clsid: string;
|
||||
|
||||
/** User-Defined State Bits */
|
||||
state: number;
|
||||
/** User-Defined State Bits */
|
||||
state: number;
|
||||
|
||||
/** Starting Sector */
|
||||
start: number;
|
||||
/** Starting Sector */
|
||||
start: number;
|
||||
|
||||
/** Data Size */
|
||||
size: number;
|
||||
/** Data Size */
|
||||
size: number;
|
||||
|
||||
/** Storage location -- see CFBStorageType */
|
||||
storage?: string;
|
||||
/** Storage location -- see CFB$StorageType */
|
||||
storage?: string;
|
||||
}
|
||||
|
||||
/* File object */
|
||||
export interface CFBContainer {
|
||||
/* list of streams and storages */
|
||||
FullPaths: string[];
|
||||
export interface CFB$Container {
|
||||
/* List of streams and storages */
|
||||
FullPaths: string[];
|
||||
|
||||
/* Array of entries in the same order as FullPaths */
|
||||
FileIndex: CFBEntry[];
|
||||
/* Array of entries in the same order as FullPaths */
|
||||
FileIndex: CFB$Entry[];
|
||||
|
||||
/* Raw Content, in chunks (Buffer when available, Array of bytes otherwise) */
|
||||
raw?: {
|
||||
header: CFB$Blob,
|
||||
sectors: CFB$Blob[];
|
||||
};
|
||||
/* Raw Content, in chunks (Buffer when available, Array of bytes otherwise) */
|
||||
raw?: {
|
||||
header: CFB$Blob,
|
||||
sectors: CFB$Blob[];
|
||||
};
|
||||
}
|
||||
|
||||
/** General utilities */
|
||||
export interface CFB$Utils {
|
||||
cfb_new(opts?: any): CFBContainer;
|
||||
cfb_add(cfb: CFBContainer, name: string, content: any, opts?: any): CFBEntry;
|
||||
cfb_del(cfb: CFBContainer, name: string): boolean;
|
||||
cfb_mov(cfb: CFBContainer, old_name: string, new_name: string): boolean;
|
||||
cfb_gc(cfb: CFBContainer): void;
|
||||
ReadShift(size: number, t?: string): number|string;
|
||||
WarnField(hexstr: string, fld?: string): void;
|
||||
CheckField(hexstr: string, fld?: string): void;
|
||||
prep_blob(blob: any, pos?: number): CFB$Blob;
|
||||
bconcat(bufs: any[]): any;
|
||||
cfb_new(opts?: any): CFB$Container;
|
||||
cfb_add(cfb: CFB$Container, name: string, content: any, opts?: any): CFB$Entry;
|
||||
cfb_del(cfb: CFB$Container, name: string): boolean;
|
||||
cfb_mov(cfb: CFB$Container, old_name: string, new_name: string): boolean;
|
||||
cfb_gc(cfb: CFB$Container): void;
|
||||
ReadShift(size: number, t?: string): number|string;
|
||||
WarnField(hexstr: string, fld?: string): void;
|
||||
CheckField(hexstr: string, fld?: string): void;
|
||||
prep_blob(blob: any, pos?: number): CFB$Blob;
|
||||
bconcat(bufs: any[]): any;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ type CFBFiles = {[n:string]:CFBEntry};
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
|
||||
exports.version = '1.0.2';
|
||||
exports.version = '1.0.3';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -353,14 +353,14 @@ function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sector
|
||||
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)/*:any*/);
|
||||
prep_blob(o.content, 0);
|
||||
} else {
|
||||
o.storage = 'minifat';
|
||||
if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
if(o.size < 0) o.size = 0;
|
||||
else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);
|
||||
prep_blob(o.content, 0);
|
||||
}
|
||||
}
|
||||
if(o.content) prep_blob(o.content, 0);
|
||||
files[name] = o;
|
||||
FileIndex.push(o);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ var DO_NOT_EXPORT_CFB = true;
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '1.0.2';
|
||||
exports.version = '1.0.3';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l, r) {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -323,14 +323,14 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
||||
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 && sector_list[minifat_store]) {
|
||||
if(o.size < 0) o.size = 0;
|
||||
else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
||||
o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);
|
||||
prep_blob(o.content, 0);
|
||||
}
|
||||
}
|
||||
if(o.content) prep_blob(o.content, 0);
|
||||
files[name] = o;
|
||||
FileIndex.push(o);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user