/* * finddata.c * Copyright (C) 2000-2002 A.J. van Os; Released under GPL * * Description: * Find the blocks that contain the data of MS Word files */ #include #include #include "antiword.h" /* * bAddDataBlocks - Add the blocks to the data block list * * Returns TRUE when successful, otherwise FALSE */ BOOL bAddDataBlocks(ULONG ulDataPosFirst, ULONG ulTotalLength, ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen) { data_block_type tDataBlock; ULONG ulDataPos, ulOffset, ulIndex; long lToGo; BOOL bSuccess; fail(ulTotalLength > (ULONG)LONG_MAX); fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); fail(aulBBD == NULL); NO_DBG_HEX(ulDataPosFirst); NO_DBG_DEC(ulTotalLength); lToGo = (long)ulTotalLength; ulDataPos = ulDataPosFirst; ulOffset = ulDataPosFirst; for (ulIndex = ulStartBlock; ulIndex != END_OF_CHAIN && lToGo > 0; ulIndex = aulBBD[ulIndex]) { if (ulIndex == UNUSED_BLOCK || ulIndex >= (ULONG)tBBDLen) { DBG_DEC(ulIndex); DBG_DEC(tBBDLen); return FALSE; } if (ulOffset >= BIG_BLOCK_SIZE) { ulOffset -= BIG_BLOCK_SIZE; continue; } tDataBlock.ulFileOffset = (ulIndex + 1) * BIG_BLOCK_SIZE + ulOffset; tDataBlock.ulDataPos = ulDataPos; tDataBlock.ulLength = min(BIG_BLOCK_SIZE - ulOffset, (ULONG)lToGo); fail(tDataBlock.ulLength > BIG_BLOCK_SIZE); ulOffset = 0; if (!bAdd2DataBlockList(&tDataBlock)) { DBG_HEX(tDataBlock.ulFileOffset); DBG_HEX(tDataBlock.ulDataPos); DBG_DEC(tDataBlock.ulLength); return FALSE; } ulDataPos += tDataBlock.ulLength; lToGo -= (long)tDataBlock.ulLength; } bSuccess = lToGo == 0 || (ulTotalLength == (ULONG)LONG_MAX && ulIndex == END_OF_CHAIN); DBG_DEC_C(!bSuccess, lToGo); DBG_DEC_C(!bSuccess, ulTotalLength); DBG_DEC_C(!bSuccess, ulIndex); return bSuccess; } /* end of bAddDataBlocks */ /* * bGet6DocumentData - make a list of the data blocks of Word 6/7 files * * Code for "fast saved" files. * * Returns TRUE when successful, otherwise FALSE */ BOOL bGet6DocumentData(FILE *pFile, ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) { UCHAR *aucBuffer; ULONG ulBeginTextInfo, ulOffset, ulTotLength; size_t tTextInfoLen; int iIndex, iOff, iType, iLen, iPieces; DBG_MSG("bGet6DocumentData"); fail(pFile == NULL); fail(aulBBD == NULL); fail(aucHeader == NULL); ulBeginTextInfo = ulGetLong(0x160, aucHeader); DBG_HEX(ulBeginTextInfo); tTextInfoLen = (size_t)ulGetLong(0x164, aucHeader); DBG_DEC(tTextInfoLen); aucBuffer = xmalloc(tTextInfoLen); if (!bReadBuffer(pFile, ulStartBlock, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucBuffer, ulBeginTextInfo, tTextInfoLen)) { aucBuffer = xfree(aucBuffer); return FALSE; } NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen); iOff = 0; while (iOff < (int)tTextInfoLen) { iType = (int)ucGetByte(iOff, aucBuffer); iOff++; if (iType == 0) { iOff++; continue; } iLen = (int)usGetWord(iOff, aucBuffer); iOff += 2; if (iType == 1) { iOff += iLen; continue; } if (iType != 2) { werr(0, "Unknown type of 'fastsaved' format"); aucBuffer = xfree(aucBuffer); return FALSE; } /* Type 2 */ NO_DBG_DEC(iLen); iOff += 2; iPieces = (iLen - 4) / 12; DBG_DEC(iPieces); for (iIndex = 0; iIndex < iPieces; iIndex++) { ulOffset = ulGetLong( iOff + (iPieces + 1) * 4 + iIndex * 8 + 2, aucBuffer); ulTotLength = ulGetLong(iOff + (iIndex + 1) * 4, aucBuffer) - ulGetLong(iOff + iIndex * 4, aucBuffer); if (!bAddDataBlocks(ulOffset, ulTotLength, ulStartBlock, aulBBD, tBBDLen)) { aucBuffer = xfree(aucBuffer); return FALSE; } } break; } aucBuffer = xfree(aucBuffer); return TRUE; } /* end of bGet6DocumentData */