Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * finddata.c
3
 * Copyright (C) 2000-2002 A.J. van Os; Released under GPL
4
 *
5
 * Description:
6
 * Find the blocks that contain the data of MS Word files
7
 */
8
 
9
#include <stdio.h>
10
#include <stdlib.h>
11
#include "antiword.h"
12
 
13
 
14
/*
15
 * bAddDataBlocks - Add the blocks to the data block list
16
 *
17
 * Returns TRUE when successful, otherwise FALSE
18
 */
19
BOOL
20
bAddDataBlocks(ULONG ulDataPosFirst, ULONG ulTotalLength,
21
	ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen)
22
{
23
	data_block_type	tDataBlock;
24
	ULONG	ulDataPos, ulOffset, ulIndex;
25
	long	lToGo;
26
	BOOL	bSuccess;
27
 
28
	fail(ulTotalLength > (ULONG)LONG_MAX);
29
	fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
30
	fail(aulBBD == NULL);
31
 
32
	NO_DBG_HEX(ulDataPosFirst);
33
	NO_DBG_DEC(ulTotalLength);
34
 
35
	lToGo = (long)ulTotalLength;
36
 
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;
46
		}
47
		if (ulOffset >= BIG_BLOCK_SIZE) {
48
			ulOffset -= BIG_BLOCK_SIZE;
49
			continue;
50
		}
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;
63
		}
64
		ulDataPos += tDataBlock.ulLength;
65
		lToGo -= (long)tDataBlock.ulLength;
66
	}
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 */
74
 
75
/*
76
 * bGet6DocumentData - make a list of the data blocks of Word 6/7 files
77
 *
78
 * Code for "fast saved" files.
79
 *
80
 * Returns TRUE when successful, otherwise FALSE
81
 */
82
BOOL
83
bGet6DocumentData(FILE *pFile, ULONG ulStartBlock,
84
	const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader)
85
{
86
	UCHAR	*aucBuffer;
87
	ULONG	ulBeginTextInfo, ulOffset, ulTotLength;
88
	size_t	tTextInfoLen;
89
	int	iIndex, iOff, iType, iLen, iPieces;
90
 
91
	DBG_MSG("bGet6DocumentData");
92
 
93
	fail(pFile == NULL);
94
	fail(aulBBD == NULL);
95
	fail(aucHeader == NULL);
96
 
97
	ulBeginTextInfo = ulGetLong(0x160, aucHeader);
98
	DBG_HEX(ulBeginTextInfo);
99
	tTextInfoLen = (size_t)ulGetLong(0x164, aucHeader);
100
	DBG_DEC(tTextInfoLen);
101
 
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;
108
	}
109
	NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen);
110
 
111
	iOff = 0;
112
	while (iOff < (int)tTextInfoLen) {
113
		iType = (int)ucGetByte(iOff, aucBuffer);
114
		iOff++;
115
		if (iType == 0) {
116
			iOff++;
117
			continue;
118
		}
119
		iLen = (int)usGetWord(iOff, aucBuffer);
120
		iOff += 2;
121
		if (iType == 1) {
122
			iOff += iLen;
123
			continue;
124
		}
125
		if (iType != 2) {
126
			werr(0, "Unknown type of 'fastsaved' format");
127
			aucBuffer = xfree(aucBuffer);
128
			return FALSE;
129
		}
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;
148
			}
149
		}
150
		break;
151
	}
152
	aucBuffer = xfree(aucBuffer);
153
	return TRUE;
154
} /* end of bGet6DocumentData */