diff --git a/nufxlib-0/Archive.c b/nufxlib-0/Archive.c index c0c6f03..29eb27c 100644 --- a/nufxlib-0/Archive.c +++ b/nufxlib-0/Archive.c @@ -580,6 +580,24 @@ Nu_ReadMasterHeader(NuArchive* pArchive) } } + /* + * Check for an unusual condition. GS/ShrinkIt appears to update + * the archive structure in the disk file periodically as it writes, + * so it's possible to get an apparently complete archive (with + * correct CRCs in the master and record headers!) that is actually + * only partially written. I did this by accident when archiving a + * 3.5" disk across a slow AppleTalk network. The only obvious + * indication of brain-damage, until you try to unpack the archive, + * seems to be a bogus MasterEOF==48. + */ + if (pHeader->mhMasterEOF <= kNuMasterHeaderSize) { + err = kNuErrNoRecords; + Nu_ReportError(NU_BLOB, err, + "Master EOF is %ld, archive is probably truncated", + pHeader->mhMasterEOF); + goto bail; + } + /* * Set up a few things in the archive structure on our way out. */ @@ -672,6 +690,7 @@ bail: if (err != kNuErrNone) { if (pArchive != nil) (void) Nu_NuArchiveFree(pArchive); + *ppArchive = nil; } return err; } diff --git a/nufxlib-0/Lzw.c b/nufxlib-0/Lzw.c index 437774c..aabce1c 100644 --- a/nufxlib-0/Lzw.c +++ b/nufxlib-0/Lzw.c @@ -1456,7 +1456,13 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord, if (!isType2) { err = Nu_ExpandLZW1(lzwState, rleLen); } else { - Assert(lzwState->dataInBuffer >= lzwLen); + if (lzwState->dataInBuffer < lzwLen) { + /* rare -- GSHK will do this if you don't let it finish */ + err = kNuErrBufferUnderrun; + Nu_ReportError(NU_BLOB, err, "not enough compressed data " + "-- archive truncated during creation?"); + goto bail; + } err = Nu_ExpandLZW2(lzwState, rleLen, lzwLen); }