SheetJS
1a428c8f5b
- sector checked before reading (h/t @e12009) See https://github.com/SheetJS/js-xlsx/issues/569 - flow type checking
102 lines
2.8 KiB
JavaScript
102 lines
2.8 KiB
JavaScript
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
|
|
|