SheetJS / js-cfb

:floppy_disk: OLE File Container Format
https://sheetjs.com/cfb-editor
Apache License 2.0
69 stars 15 forks source link

XLSX broken file #14

Closed wisekaa03 closed 2 years ago

wisekaa03 commented 3 years ago
/** Chase down the rest of the DIFAT chain to build a comprehensive list
    DIFAT chains by storing the next sector number as the last 32 bits */
function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) {
        var q = ENDOFCHAIN;
        if(idx === ENDOFCHAIN) {
                // if(cnt !== 0) throw new Error("DIFAT chain shorter than expected");
                if(cnt !== 0) console.log("DIFAT chain shorter than expected");
        } else if(idx !== -1 /*FREESECT*/) {
                var sector = sectors[idx], m = (ssz>>>2)-1;
                if(!sector) return;
                for(var i = 0; i < m; ++i) {
                        if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;
                        fat_addrs.push(q);
                }
                sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs);
        }
}
SheetJSDev commented 3 years ago

Can you share a sample file that hits the error but Excel treats as valid?

SheetJSDev commented 3 years ago

We'll accept a PR for the following fix:

diff --git a/bits/45_readfat.js b/bits/45_readfat.js
index b1b4f5d..b72a13c 100644
--- a/bits/45_readfat.js
+++ b/bits/45_readfat.js
@@ -11,7 +11,7 @@ function sleuth_fat(idx/*:number*/, cnt/*:number*/, sectors/*:Array<RawBytes>*/,
                        if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;
                        fat_addrs.push(q);
                }
-               sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs);
+               if(cnt >= 1) sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs);
        }
 }