Imported from antiword-0.37.tar.gz.
[antiword.git] / finddata.c
blob441030c5a9e58b92f37df618e0c96f3bf111797d
1 /*
2 * finddata.c
3 * Copyright (C) 2000-2002 A.J. van Os; Released under GPL
5 * Description:
6 * Find the blocks that contain the data of MS Word files
7 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include "antiword.h"
15 * bAddDataBlocks - Add the blocks to the data block list
17 * Returns TRUE when successful, otherwise FALSE
19 BOOL
20 bAddDataBlocks(ULONG ulDataPosFirst, ULONG ulTotalLength,
21 ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen)
23 data_block_type tDataBlock;
24 ULONG ulDataPos, ulOffset, ulIndex;
25 long lToGo;
26 BOOL bSuccess;
28 fail(ulTotalLength > (ULONG)LONG_MAX);
29 fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
30 fail(aulBBD == NULL);
32 NO_DBG_HEX(ulDataPosFirst);
33 NO_DBG_DEC(ulTotalLength);
35 lToGo = (long)ulTotalLength;
37 ulDataPos = ulDataPosFirst;
38 ulOffset = ulDataPosFirst;
39 for (ulIndex = ulStartBlock;
40 ulIndex != END_OF_CHAIN && lToGo > 0;
41 ulIndex = aulBBD[ulIndex]) {
42 if (ulIndex == UNUSED_BLOCK || ulIndex >= (ULONG)tBBDLen) {
43 DBG_DEC(ulIndex);
44 DBG_DEC(tBBDLen);
45 return FALSE;
47 if (ulOffset >= BIG_BLOCK_SIZE) {
48 ulOffset -= BIG_BLOCK_SIZE;
49 continue;
51 tDataBlock.ulFileOffset =
52 (ulIndex + 1) * BIG_BLOCK_SIZE + ulOffset;
53 tDataBlock.ulDataPos = ulDataPos;
54 tDataBlock.ulLength = min(BIG_BLOCK_SIZE - ulOffset,
55 (ULONG)lToGo);
56 fail(tDataBlock.ulLength > BIG_BLOCK_SIZE);
57 ulOffset = 0;
58 if (!bAdd2DataBlockList(&tDataBlock)) {
59 DBG_HEX(tDataBlock.ulFileOffset);
60 DBG_HEX(tDataBlock.ulDataPos);
61 DBG_DEC(tDataBlock.ulLength);
62 return FALSE;
64 ulDataPos += tDataBlock.ulLength;
65 lToGo -= (long)tDataBlock.ulLength;
67 bSuccess = lToGo == 0 ||
68 (ulTotalLength == (ULONG)LONG_MAX && ulIndex == END_OF_CHAIN);
69 DBG_DEC_C(!bSuccess, lToGo);
70 DBG_DEC_C(!bSuccess, ulTotalLength);
71 DBG_DEC_C(!bSuccess, ulIndex);
72 return bSuccess;
73 } /* end of bAddDataBlocks */
76 * bGet6DocumentData - make a list of the data blocks of Word 6/7 files
78 * Code for "fast saved" files.
80 * Returns TRUE when successful, otherwise FALSE
82 BOOL
83 bGet6DocumentData(FILE *pFile, ULONG ulStartBlock,
84 const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader)
86 UCHAR *aucBuffer;
87 ULONG ulBeginTextInfo, ulOffset, ulTotLength;
88 size_t tTextInfoLen;
89 int iIndex, iOff, iType, iLen, iPieces;
91 DBG_MSG("bGet6DocumentData");
93 fail(pFile == NULL);
94 fail(aulBBD == NULL);
95 fail(aucHeader == NULL);
97 ulBeginTextInfo = ulGetLong(0x160, aucHeader);
98 DBG_HEX(ulBeginTextInfo);
99 tTextInfoLen = (size_t)ulGetLong(0x164, aucHeader);
100 DBG_DEC(tTextInfoLen);
102 aucBuffer = xmalloc(tTextInfoLen);
103 if (!bReadBuffer(pFile, ulStartBlock,
104 aulBBD, tBBDLen, BIG_BLOCK_SIZE,
105 aucBuffer, ulBeginTextInfo, tTextInfoLen)) {
106 aucBuffer = xfree(aucBuffer);
107 return FALSE;
109 NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen);
111 iOff = 0;
112 while (iOff < (int)tTextInfoLen) {
113 iType = (int)ucGetByte(iOff, aucBuffer);
114 iOff++;
115 if (iType == 0) {
116 iOff++;
117 continue;
119 iLen = (int)usGetWord(iOff, aucBuffer);
120 iOff += 2;
121 if (iType == 1) {
122 iOff += iLen;
123 continue;
125 if (iType != 2) {
126 werr(0, "Unknown type of 'fastsaved' format");
127 aucBuffer = xfree(aucBuffer);
128 return FALSE;
130 /* Type 2 */
131 NO_DBG_DEC(iLen);
132 iOff += 2;
133 iPieces = (iLen - 4) / 12;
134 DBG_DEC(iPieces);
135 for (iIndex = 0; iIndex < iPieces; iIndex++) {
136 ulOffset = ulGetLong(
137 iOff + (iPieces + 1) * 4 + iIndex * 8 + 2,
138 aucBuffer);
139 ulTotLength = ulGetLong(iOff + (iIndex + 1) * 4,
140 aucBuffer) -
141 ulGetLong(iOff + iIndex * 4,
142 aucBuffer);
143 if (!bAddDataBlocks(ulOffset, ulTotLength,
144 ulStartBlock,
145 aulBBD, tBBDLen)) {
146 aucBuffer = xfree(aucBuffer);
147 return FALSE;
150 break;
152 aucBuffer = xfree(aucBuffer);
153 return TRUE;
154 } /* end of bGet6DocumentData */