@@ -112,16 +112,19 @@ function ReadShift(size, t) {
112
112
}
113
113
this . l += size ; return o ;
114
114
}
115
+
115
116
function CheckField ( hexstr , fld ) {
116
117
var m = this . slice ( this . l , this . l + hexstr . length / 2 ) . hexlify ( 'hex' ) ;
117
118
if ( m !== hexstr ) throw ( fld || "" ) + 'Expected ' + hexstr + ' saw ' + m ;
118
119
this . l += hexstr . length / 2 ;
119
120
}
121
+
120
122
function WarnField ( hexstr , fld ) {
121
123
var m = this . slice ( this . l , this . l + hexstr . length / 2 ) . hexlify ( 'hex' ) ;
122
124
if ( m !== hexstr ) console . error ( ( fld || "" ) + 'Expected ' + hexstr + ' saw ' + m ) ;
123
125
this . l += hexstr . length / 2 ;
124
126
}
127
+
125
128
function prep_blob ( blob , pos ) {
126
129
blob . read_shift = ReadShift . bind ( blob ) ;
127
130
blob . chk = CheckField ;
@@ -237,9 +240,9 @@ for(j = 0; blob.l != 512; ) {
237
240
238
241
239
242
/** Break the file up into sectors */
240
- if ( file . length % ssz !== 0 ) throw "File Length: Expected multiple of "+ ssz ;
243
+ if ( file . length % ssz !== 0 ) console . error ( "CFB: size " + file . length + " % "+ ssz ) ;
241
244
242
- var nsectors = ( file . length - ssz ) / ssz ;
245
+ var nsectors = Math . ceil ( ( file . length - ssz ) / ssz ) ;
243
246
var sectors = [ ] ;
244
247
for ( var i = 1 ; i != nsectors + 1 ; ++ i ) sectors [ i - 1 ] = file . slice ( i * ssz , ( i + 1 ) * ssz ) ;
245
248
@@ -250,12 +253,14 @@ function sleuth_fat(idx, cnt) {
250
253
if ( cnt !== 0 ) throw "DIFAT chain shorter than expected" ;
251
254
return ;
252
255
}
253
- var sector = sectors [ idx ] ;
254
- for ( var i = 0 ; i != ssz / 4 - 1 ; ++ i ) {
255
- if ( ( q = sector . readUInt32LE ( i * 4 ) ) === ENDOFCHAIN ) break ;
256
- fat_addrs . push ( q ) ;
256
+ if ( idx !== FREESECT ) {
257
+ var sector = sectors [ idx ] ;
258
+ for ( var i = 0 ; i != ssz / 4 - 1 ; ++ i ) {
259
+ if ( ( q = sector . readUInt32LE ( i * 4 ) ) === ENDOFCHAIN ) break ;
260
+ fat_addrs . push ( q ) ;
261
+ }
262
+ sleuth_fat ( sector . readUInt32LE ( ssz - 4 ) , cnt - 1 ) ;
257
263
}
258
- sleuth_fat ( sector . readUInt32LE ( ssz - 4 ) , cnt - 1 ) ;
259
264
}
260
265
sleuth_fat ( difat_start , ndfs ) ;
261
266
@@ -284,7 +289,7 @@ for(i=0; i != sectors.length; ++i) {
284
289
sector_list [ i ] . data = Array ( buf . map ( get_sector ) ) . toBuffer ( ) ;
285
290
}
286
291
sector_list [ dir_start ] . name = "!Directory" ;
287
- if ( nmfs > 0 ) sector_list [ minifat_start ] . name = "!MiniFAT" ;
292
+ if ( nmfs > 0 && minifat_start !== ENDOFCHAIN ) sector_list [ minifat_start ] . name = "!MiniFAT" ;
288
293
sector_list [ fat_addrs [ 0 ] ] . name = "!FAT" ;
289
294
290
295
/* [MS-CFB] 2.6.1 Compound File Directory Entry */
@@ -314,18 +319,26 @@ function read_directory(idx) {
314
319
o . size = read ( 4 ) ;
315
320
if ( o . type === 'root' ) { //root entry
316
321
minifat_store = o . start ;
317
- if ( nmfs > 0 ) sector_list [ minifat_store ] . name = "!StreamData" ;
322
+ if ( nmfs > 0 && minifat_store !== ENDOFCHAIN ) sector_list [ minifat_store ] . name = "!StreamData" ;
318
323
minifat_size = o . size ;
319
324
} else if ( o . size >= ms_cutoff_size ) {
320
325
o . storage = 'fat' ;
326
+ try {
327
+ sector_list [ o . start ] . name = o . name ;
328
+ o . content = sector_list [ o . start ] . data . slice ( 0 , o . size ) ;
329
+ } catch ( e ) {
330
+ o . start = o . start - 1 ;
321
331
sector_list [ o . start ] . name = o . name ;
322
332
o . content = sector_list [ o . start ] . data . slice ( 0 , o . size ) ;
333
+ }
323
334
prep_blob ( o . content ) ;
324
335
} else {
325
336
o . storage = 'minifat' ;
326
337
w = o . start * mssz ;
327
- o . content = sector_list [ minifat_store ] . data . slice ( w , w + o . size ) ;
328
- prep_blob ( o . content ) ;
338
+ if ( minifat_store !== ENDOFCHAIN ) {
339
+ o . content = sector_list [ minifat_store ] . data . slice ( w , w + o . size ) ;
340
+ prep_blob ( o . content ) ;
341
+ }
329
342
}
330
343
if ( o . ctime ) {
331
344
var ct = blob . slice ( blob . l - 24 , blob . l - 16 ) ;
@@ -351,13 +364,14 @@ function build_full_paths(Dir, pathobj, paths, patharr) {
351
364
352
365
for ( i = 0 ; i != dad . length ; ++ i ) { dad [ i ] = q [ i ] = i ; paths [ i ] = patharr [ i ] ; }
353
366
354
- for ( i = q [ 0 ] ; q . length !== 0 ; i = q . shift ( ) ) {
367
+ for ( i = q [ 0 ] ; typeof i !== "undefined" ; i = q . shift ( ) ) {
355
368
if ( Dir [ i ] . child ) dad [ Dir [ i ] . child ] = i ;
356
369
if ( Dir [ i ] . left ) { dad [ Dir [ i ] . left ] = dad [ i ] ; q . push ( Dir [ i ] . left ) ; }
357
370
if ( Dir [ i ] . right ) { dad [ Dir [ i ] . right ] = dad [ i ] ; q . push ( Dir [ i ] . right ) ; }
358
371
}
359
372
360
373
for ( i = 1 ; i !== paths . length ; ++ i ) {
374
+ if ( Dir [ i ] . type === "unknown" ) continue ;
361
375
var j = dad [ i ] ;
362
376
if ( j === 0 ) paths [ i ] = paths [ 0 ] + "/" + paths [ i ] ;
363
377
else while ( j != 0 ) {
@@ -426,14 +440,14 @@ return this;
426
440
var NOSTREAM = 0xFFFFFFFF ;
427
441
var HEADER_CLSID = '00000000000000000000000000000000' ;
428
442
/* 2.6.1 Compound File Directory Entry */
429
- var EntryTypes = [ 'unknown' , 'storage' , 'stream' , null , null , 'root' ] ;
443
+ var EntryTypes = [ 'unknown' , 'storage' , 'stream' , 'lockbytes' , 'property' , 'root' ] ;
430
444
}
431
445
432
446
var CFB_utils = {
433
447
ReadShift : ReadShift ,
434
448
WarnField : WarnField ,
435
449
CheckField : CheckField ,
436
- prep_blob : prep_blob ,
450
+ prep_blob : prep_blob ,
437
451
bconcat : bconcat
438
452
} ;
439
453
0 commit comments