123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- /*
- * 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 <stdio.h>
- #include <stdlib.h>
- #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 */
|