GS/ShrinkIt appears to update some of the archive header fields while it

is in the process of compressing the data.  By writing to an AppleTalk
network and copying the archive while it was being written, I wound up
with an archive that appeared complete but was actually truncated.  We
now try to detect that case, and the compression code will spit back an
error instead of an assertion failure.
This commit is contained in:
Andy McFadden 2002-09-23 23:56:50 +00:00
parent 6dbf0dced9
commit 9d12532e6c
2 changed files with 26 additions and 1 deletions

View File

@ -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;
}

View File

@ -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);
}