mirror of
https://github.com/simon987/antiword.git
synced 2025-04-10 13:06:41 +00:00
155 lines
3.7 KiB
C
155 lines
3.7 KiB
C
/*
|
|
* 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 */
|