Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/cmd/aux/antiword/notes.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * notes.c
3
 * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
4
 *
5
 * Description:
6
 * Functions to tell the difference between footnotes and endnotes
7
 */
8
 
9
#include "antiword.h"
10
 
11
/*
12
 * Private structures to hide the way the information
13
 * is stored from the rest of the program
14
 */
15
typedef struct footnote_local_tag {
16
        footnote_block_type	tInfo;
17
        ULONG			ulCharPosStart;
18
        ULONG			ulCharPosNext;
19
        BOOL			bUseful;
20
} footnote_local_type;
21
 
22
/* Variables needed to write the Footnote and Endnote information */
23
static ULONG	*aulFootnoteList = NULL;
24
static size_t	tFootnoteListLength = 0;
25
static ULONG	*aulEndnoteList = NULL;
26
static size_t	tEndnoteListLength = 0;
27
/* Variables needed to write the Footnote Text */
28
static footnote_local_type	*pFootnoteText = NULL;
29
static size_t			tFootnoteTextLength = 0;
30
 
31
 
32
/*
33
 * Destroy the lists with footnote and endnote information
34
 */
35
void
36
vDestroyNotesInfoLists(void)
37
{
38
	footnote_local_type	*pRecord;
39
	size_t			tFootnote;
40
 
41
	TRACE_MSG("vDestroyNotesInfoLists");
42
 
43
	/* Free the lists and reset all control variables */
44
	aulEndnoteList = xfree(aulEndnoteList);
45
	aulFootnoteList = xfree(aulFootnoteList);
46
	tEndnoteListLength = 0;
47
	tFootnoteListLength = 0;
48
	for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) {
49
		pRecord = pFootnoteText + tFootnote;
50
		pRecord->tInfo.szText = xfree(pRecord->tInfo.szText);
51
	}
52
	pFootnoteText = xfree(pFootnoteText);
53
	tFootnoteTextLength = 0;
54
} /* end of vDestroyNotesInfoLists */
55
 
56
/*
57
 * Build the list with footnote information for Word for DOS files
58
 */
59
static void
60
vGet0FootnotesInfoAndText(FILE *pFile, const UCHAR *aucHeader)
61
{
62
	footnote_local_type	*pCurr;
63
	UCHAR	*aucBuffer;
64
	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
65
	ULONG	ulCharPos, ulBeginNextBlock;
66
	size_t	tFootnotes, tFootnoteInfoLen;
67
	size_t	tIndex;
68
	UCHAR   aucTmp[2];
69
 
70
	TRACE_MSG("vGet0FootnotesInfoAndText");
71
 
72
	fail(pFile == NULL || aucHeader == NULL);
73
 
74
	ulBeginOfText = 128;
75
	NO_DBG_HEX(ulBeginOfText);
76
	ulBeginFootnoteInfo =  128 * (ULONG)usGetWord(0x14, aucHeader);
77
	DBG_HEX(ulBeginFootnoteInfo);
78
	ulBeginNextBlock = 128 * (ULONG)usGetWord(0x16, aucHeader);
79
	DBG_HEX(ulBeginNextBlock);
80
 
81
	if (ulBeginFootnoteInfo == ulBeginNextBlock) {
82
		DBG_MSG("No Footnotes in this document");
83
		return;
84
	}
85
 
86
	/* Read the the number of footnotes + 1 */
87
	if (!bReadBytes(aucTmp, 2, ulBeginFootnoteInfo, pFile)) {
88
		return;
89
	}
90
	tFootnotes = (size_t)usGetWord(0, aucTmp);
91
	if (tFootnotes < 2) {
92
		DBG_MSG("No Footnotes in this document (2)");
93
	}
94
	DBG_DEC(tFootnotes);
95
	tFootnoteInfoLen =  8 * tFootnotes;
96
 
97
	aucBuffer = xmalloc(tFootnoteInfoLen);
98
	if (!bReadBytes(aucBuffer,
99
			tFootnoteInfoLen, ulBeginFootnoteInfo + 4, pFile)) {
100
		aucBuffer = xfree(aucBuffer);
101
		return;
102
	}
103
	DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
104
 
105
	/* Get footnote information */
106
	fail(tFootnoteListLength != 0);
107
	tFootnoteListLength = tFootnotes - 1;
108
	fail(tFootnoteListLength == 0);
109
 
110
	fail(aulFootnoteList != NULL);
111
	aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
112
 
113
	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
114
		ulOffset = ulGetLong(tIndex * 8, aucBuffer);
115
		DBG_HEX(ulOffset);
116
		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
117
		DBG_HEX(ulFileOffset);
118
		aulFootnoteList[tIndex] = ulFileOffset;
119
	}
120
 
121
	/* Get footnote text */
122
	fail(tFootnoteTextLength != 0);
123
	tFootnoteTextLength = tFootnotes - 1;
124
	fail(tFootnoteTextLength == 0);
125
 
126
	fail(pFootnoteText != NULL);
127
	pFootnoteText = xcalloc(tFootnoteTextLength,
128
				sizeof(footnote_local_type));
129
 
130
	for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
131
		pCurr = pFootnoteText + tIndex;
132
		pCurr->tInfo.szText = NULL;
133
		ulOffset = ulGetLong(tIndex * 8 + 4, aucBuffer);
134
		DBG_HEX(ulOffset);
135
		ulCharPos = ulBeginOfText + ulOffset;
136
		DBG_HEX(ulCharPos);
137
		DBG_HEX(ulCharPos2FileOffset(ulCharPos));
138
		pCurr->ulCharPosStart = ulCharPos;
139
		ulOffset = ulGetLong((tIndex + 1) * 8 + 4, aucBuffer);
140
		DBG_HEX(ulOffset);
141
		ulCharPos = ulBeginOfText + ulOffset;
142
		DBG_HEX(ulCharPos);
143
		DBG_HEX(ulCharPos2FileOffset(ulCharPos));
144
		pCurr->ulCharPosNext = ulCharPos;
145
		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
146
	}
147
	aucBuffer = xfree(aucBuffer);
148
} /* end of vGet0FootnotesInfoAndText */
149
 
150
/*
151
 * Build the lists note information for Word for DOS files
152
 */
153
static void
154
vGet0NotesInfo(FILE *pFile, const UCHAR *aucHeader)
155
{
156
	TRACE_MSG("vGet0NotesInfo");
157
 
158
	vGet0FootnotesInfoAndText(pFile, aucHeader);
159
	/* There are no endnotes in a Word for DOS file */
160
} /* end of vGet0NotesInfo */
161
 
162
/*
163
 * Build the list with footnote information for WinWord 1/2 files
164
 */
165
static void
166
vGet2FootnotesInfo(FILE *pFile, const UCHAR *aucHeader)
167
{
168
	UCHAR	*aucBuffer;
169
	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
170
	size_t	tFootnoteInfoLen;
171
	size_t	tIndex;
172
 
173
	TRACE_MSG("vGet2FootnotesInfo");
174
 
175
	fail(pFile == NULL || aucHeader == NULL);
176
 
177
	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
178
	NO_DBG_HEX(ulBeginOfText);
179
	ulBeginFootnoteInfo = ulGetLong(0x64, aucHeader); /* fcPlcffndRef */
180
	NO_DBG_HEX(ulBeginFootnoteInfo);
181
	tFootnoteInfoLen = (size_t)usGetWord(0x68, aucHeader); /* cbPlcffndRef */
182
	NO_DBG_DEC(tFootnoteInfoLen);
183
 
184
	if (tFootnoteInfoLen < 10) {
185
		DBG_MSG("No Footnotes in this document");
186
		return;
187
	}
188
 
189
	aucBuffer = xmalloc(tFootnoteInfoLen);
190
	if (!bReadBytes(aucBuffer,
191
			tFootnoteInfoLen, ulBeginFootnoteInfo, pFile)) {
192
		aucBuffer = xfree(aucBuffer);
193
		return;
194
	}
195
	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
196
 
197
	fail(tFootnoteListLength != 0);
198
	tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
199
	fail(tFootnoteListLength == 0);
200
 
201
	fail(aulFootnoteList != NULL);
202
	aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
203
 
204
	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
205
		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
206
		NO_DBG_HEX(ulOffset);
207
		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
208
		NO_DBG_HEX(ulFileOffset);
209
		aulFootnoteList[tIndex] = ulFileOffset;
210
	}
211
	aucBuffer = xfree(aucBuffer);
212
} /* end of vGet2FootnotesInfo */
213
 
214
/*
215
 * Build the list with footnote text information for WinWord 1/2 files
216
 */
217
static void
218
vGet2FootnotesText(FILE *pFile, const UCHAR *aucHeader)
219
{
220
	footnote_local_type	*pCurr;
221
	UCHAR	*aucBuffer;
222
	ULONG	ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
223
	size_t	tFootnoteTextLen;
224
	size_t	tIndex;
225
 
226
	TRACE_MSG("vGet2FootnotesText");
227
 
228
	fail(pFile == NULL || aucHeader == NULL);
229
 
230
	ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
231
	ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */
232
	NO_DBG_HEX(ulBeginOfFootnotes);
233
 
234
	ulBeginFootnoteText = ulGetLong(0x6a, aucHeader); /* fcPlcffndTxt */
235
	NO_DBG_HEX(ulBeginFootnoteText);
236
	tFootnoteTextLen =
237
		(size_t)usGetWord(0x6e, aucHeader); /* cbPlcffndTxt */
238
	NO_DBG_DEC(tFootnoteTextLen);
239
 
240
	if (tFootnoteTextLen < 12) {
241
		DBG_MSG("No Footnote text in this document");
242
		return;
243
	}
244
 
245
	aucBuffer = xmalloc(tFootnoteTextLen);
246
	if (!bReadBytes(aucBuffer,
247
			tFootnoteTextLen, ulBeginFootnoteText, pFile)) {
248
		aucBuffer = xfree(aucBuffer);
249
		return;
250
	}
251
	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
252
 
253
	fail(tFootnoteTextLength != 0);
254
	tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
255
	fail(tFootnoteTextLength == 0);
256
 
257
	fail(pFootnoteText != NULL);
258
	pFootnoteText = xcalloc(tFootnoteTextLength,
259
				sizeof(footnote_local_type));
260
 
261
	for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
262
		pCurr = pFootnoteText + tIndex;
263
		pCurr->tInfo.szText = NULL;
264
		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
265
		NO_DBG_HEX(ulOffset);
266
		ulCharPos = ulBeginOfFootnotes + ulOffset;
267
		NO_DBG_HEX(ulCharPos);
268
		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
269
		pCurr->ulCharPosStart = ulCharPos;
270
		ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
271
		NO_DBG_HEX(ulOffset);
272
		ulCharPos = ulBeginOfFootnotes + ulOffset;
273
		NO_DBG_HEX(ulCharPos);
274
		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
275
		pCurr->ulCharPosNext = ulCharPos;
276
		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
277
	}
278
	aucBuffer = xfree(aucBuffer);
279
} /* end of vGet2FootnotesText */
280
 
281
/*
282
 * Build the lists note information for WinWord 1/2 files
283
 */
284
static void
285
vGet2NotesInfo(FILE *pFile, const UCHAR *aucHeader)
286
{
287
	TRACE_MSG("vGet2NotesInfo");
288
 
289
	vGet2FootnotesInfo(pFile, aucHeader);
290
	vGet2FootnotesText(pFile, aucHeader);
291
	/* There are no endnotes in a WinWord 1/2 file */
292
} /* end of vGet2NotesInfo */
293
 
294
/*
295
 * Build the list with footnote information for Word 6/7 files
296
 */
297
static void
298
vGet6FootnotesInfo(FILE *pFile, ULONG ulStartBlock,
299
	const ULONG *aulBBD, size_t tBBDLen,
300
	const UCHAR *aucHeader)
301
{
302
	UCHAR	*aucBuffer;
303
	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
304
	size_t	tFootnoteInfoLen;
305
	size_t	tIndex;
306
 
307
	TRACE_MSG("vGet6FootnotesInfo");
308
 
309
	fail(pFile == NULL || aucHeader == NULL);
310
	fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
311
	fail(aulBBD == NULL);
312
 
313
	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
314
	NO_DBG_HEX(ulBeginOfText);
315
	ulBeginFootnoteInfo = ulGetLong(0x68, aucHeader); /* fcPlcffndRef */
316
	NO_DBG_HEX(ulBeginFootnoteInfo);
317
	tFootnoteInfoLen =
318
		(size_t)ulGetLong(0x6c, aucHeader); /* lcbPlcffndRef */
319
	NO_DBG_DEC(tFootnoteInfoLen);
320
 
321
	if (tFootnoteInfoLen < 10) {
322
		DBG_MSG("No Footnotes in this document");
323
		return;
324
	}
325
 
326
	aucBuffer = xmalloc(tFootnoteInfoLen);
327
	if (!bReadBuffer(pFile, ulStartBlock,
328
			aulBBD, tBBDLen, BIG_BLOCK_SIZE,
329
			aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) {
330
		aucBuffer = xfree(aucBuffer);
331
		return;
332
	}
333
	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
334
 
335
	fail(tFootnoteListLength != 0);
336
	tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
337
	fail(tFootnoteListLength == 0);
338
 
339
	fail(aulFootnoteList != NULL);
340
	aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
341
 
342
	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
343
		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
344
		NO_DBG_HEX(ulOffset);
345
		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
346
		NO_DBG_HEX(ulFileOffset);
347
		aulFootnoteList[tIndex] = ulFileOffset;
348
	}
349
	aucBuffer = xfree(aucBuffer);
350
} /* end of vGet6FootnotesInfo */
351
 
352
/*
353
 * Build the list with footnote text information for Word 6/7 files
354
 */
355
static void
356
vGet6FootnotesText(FILE *pFile, ULONG ulStartBlock,
357
	const ULONG *aulBBD, size_t tBBDLen,
358
	const UCHAR *aucHeader)
359
{
360
	footnote_local_type	*pCurr;
361
	UCHAR	*aucBuffer;
362
	ULONG	ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
363
	size_t	tFootnoteTextLen;
364
	size_t	tIndex;
365
 
366
	TRACE_MSG("vGet6FootnotesText");
367
 
368
	fail(pFile == NULL || aucHeader == NULL);
369
	fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
370
	fail(aulBBD == NULL);
371
 
372
	ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
373
	ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */
374
	NO_DBG_HEX(ulBeginOfFootnotes);
375
 
376
	ulBeginFootnoteText = ulGetLong(0x70, aucHeader); /* fcPlcffndTxt */
377
	NO_DBG_HEX(ulBeginFootnoteText);
378
	tFootnoteTextLen =
379
		(size_t)ulGetLong(0x74, aucHeader); /* lcbPlcffndTxt */
380
	NO_DBG_DEC(tFootnoteTextLen);
381
 
382
	if (tFootnoteTextLen < 12) {
383
		DBG_MSG("No Footnote text in this document");
384
		return;
385
	}
386
 
387
	aucBuffer = xmalloc(tFootnoteTextLen);
388
	if (!bReadBuffer(pFile, ulStartBlock,
389
			aulBBD, tBBDLen, BIG_BLOCK_SIZE,
390
			aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) {
391
		aucBuffer = xfree(aucBuffer);
392
		return;
393
	}
394
	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
395
 
396
	fail(tFootnoteTextLength != 0);
397
	tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
398
	fail(tFootnoteTextLength == 0);
399
 
400
	fail(pFootnoteText != NULL);
401
	pFootnoteText = xcalloc(tFootnoteTextLength,
402
				sizeof(footnote_local_type));
403
 
404
	for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
405
		pCurr = pFootnoteText + tIndex;
406
		pCurr->tInfo.szText = NULL;
407
		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
408
		NO_DBG_HEX(ulOffset);
409
		ulCharPos = ulBeginOfFootnotes + ulOffset;
410
		NO_DBG_HEX(ulCharPos);
411
		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
412
		pCurr->ulCharPosStart = ulCharPos;
413
		ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
414
		NO_DBG_HEX(ulOffset);
415
		ulCharPos = ulBeginOfFootnotes + ulOffset;
416
		NO_DBG_HEX(ulCharPos);
417
		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
418
		pCurr->ulCharPosNext = ulCharPos;
419
		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
420
	}
421
	aucBuffer = xfree(aucBuffer);
422
} /* end of vGet6FootnotesText */
423
 
424
/*
425
 * Build the list with endnote information for Word 6/7 files
426
 */
427
static void
428
vGet6EndnotesInfo(FILE *pFile, ULONG ulStartBlock,
429
	const ULONG *aulBBD, size_t tBBDLen,
430
	const UCHAR *aucHeader)
431
{
432
	UCHAR	*aucBuffer;
433
	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo;
434
	size_t	tEndnoteInfoLen;
435
	size_t	tIndex;
436
 
437
	TRACE_MSG("vGet6EndnotesInfo");
438
 
439
	fail(pFile == NULL || aucHeader == NULL);
440
	fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
441
	fail(aulBBD == NULL);
442
 
443
	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
444
	NO_DBG_HEX(ulBeginOfText);
445
	ulBeginEndnoteInfo = ulGetLong(0x1d2, aucHeader); /* fcPlcfendRef */
446
	NO_DBG_HEX(ulBeginEndnoteInfo);
447
	tEndnoteInfoLen =
448
		(size_t)ulGetLong(0x1d6, aucHeader); /* lcbPlcfendRef */
449
	NO_DBG_DEC(tEndnoteInfoLen);
450
 
451
	if (tEndnoteInfoLen < 10) {
452
		DBG_MSG("No Endnotes in this document");
453
		return;
454
	}
455
 
456
	aucBuffer = xmalloc(tEndnoteInfoLen);
457
	if (!bReadBuffer(pFile, ulStartBlock,
458
			aulBBD, tBBDLen, BIG_BLOCK_SIZE,
459
			aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) {
460
		aucBuffer = xfree(aucBuffer);
461
		return;
462
	}
463
	NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen);
464
 
465
	fail(tEndnoteListLength != 0);
466
	tEndnoteListLength = (tEndnoteInfoLen - 4) / 6;
467
	fail(tEndnoteListLength == 0);
468
 
469
	fail(aulEndnoteList != NULL);
470
	aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG));
471
 
472
	for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
473
		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
474
		NO_DBG_HEX(ulOffset);
475
		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
476
		NO_DBG_HEX(ulFileOffset);
477
		aulEndnoteList[tIndex] = ulFileOffset;
478
	}
479
	aucBuffer = xfree(aucBuffer);
480
} /* end of vGet6EndnotesInfo */
481
 
482
/*
483
 * Build the lists note information for Word 6/7 files
484
 */
485
static void
486
vGet6NotesInfo(FILE *pFile, ULONG ulStartBlock,
487
	const ULONG *aulBBD, size_t tBBDLen,
488
	const UCHAR *aucHeader)
489
{
490
	TRACE_MSG("vGet6NotesInfo");
491
 
492
	vGet6FootnotesInfo(pFile, ulStartBlock,
493
			aulBBD, tBBDLen, aucHeader);
494
	vGet6FootnotesText(pFile, ulStartBlock,
495
			aulBBD, tBBDLen, aucHeader);
496
	vGet6EndnotesInfo(pFile, ulStartBlock,
497
			aulBBD, tBBDLen, aucHeader);
498
} /* end of vGet6NotesInfo */
499
 
500
/*
501
 * Build the list with footnote information for Word 8/9/10 files
502
 */
503
static void
504
vGet8FootnotesInfo(FILE *pFile, const pps_info_type *pPPS,
505
	const ULONG *aulBBD, size_t tBBDLen,
506
	const ULONG *aulSBD, size_t tSBDLen,
507
	const UCHAR *aucHeader)
508
{
509
	const ULONG	*aulBlockDepot;
510
	UCHAR	*aucBuffer;
511
	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
512
	size_t	tFootnoteInfoLen, tBlockDepotLen, tBlockSize;
513
	size_t	tIndex;
514
 
515
	TRACE_MSG("vGet8FootnotesInfo");
516
 
517
	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
518
	NO_DBG_HEX(ulBeginOfText);
519
	ulBeginFootnoteInfo = ulGetLong(0xaa, aucHeader); /* fcPlcffndRef */
520
	NO_DBG_HEX(ulBeginFootnoteInfo);
521
	tFootnoteInfoLen =
522
		(size_t)ulGetLong(0xae, aucHeader); /* lcbPlcffndRef */
523
	NO_DBG_DEC(tFootnoteInfoLen);
524
 
525
	if (tFootnoteInfoLen < 10) {
526
		DBG_MSG("No Footnotes in this document");
527
		return;
528
	}
529
 
530
	NO_DBG_DEC(pPPS->tTable.ulSB);
531
	NO_DBG_HEX(pPPS->tTable.ulSize);
532
	if (pPPS->tTable.ulSize == 0) {
533
		DBG_MSG("No footnotes information");
534
		return;
535
	}
536
 
537
	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
538
	  	/* Use the Small Block Depot */
539
		aulBlockDepot = aulSBD;
540
		tBlockDepotLen = tSBDLen;
541
		tBlockSize = SMALL_BLOCK_SIZE;
542
	} else {
543
	  	/* Use the Big Block Depot */
544
		aulBlockDepot = aulBBD;
545
		tBlockDepotLen = tBBDLen;
546
		tBlockSize = BIG_BLOCK_SIZE;
547
	}
548
	aucBuffer = xmalloc(tFootnoteInfoLen);
549
	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
550
			aulBlockDepot, tBlockDepotLen, tBlockSize,
551
			aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) {
552
		aucBuffer = xfree(aucBuffer);
553
		return;
554
	}
555
	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
556
 
557
	fail(tFootnoteListLength != 0);
558
	tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
559
	fail(tFootnoteListLength == 0);
560
 
561
	fail(aulFootnoteList != NULL);
562
	aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
563
 
564
	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
565
		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
566
		NO_DBG_HEX(ulOffset);
567
		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
568
		NO_DBG_HEX(ulFileOffset);
569
		aulFootnoteList[tIndex] = ulFileOffset;
570
	}
571
	aucBuffer = xfree(aucBuffer);
572
} /* end of vGet8FootnotesInfo */
573
 
574
/*
575
 * Build the list with footnote text information for Word 8/9/10 files
576
 */
577
static void
578
vGet8FootnotesText(FILE *pFile, const pps_info_type *pPPS,
579
	const ULONG *aulBBD, size_t tBBDLen,
580
	const ULONG *aulSBD, size_t tSBDLen,
581
	const UCHAR *aucHeader)
582
{
583
	footnote_local_type	*pCurr;
584
	const ULONG	*aulBlockDepot;
585
	UCHAR	*aucBuffer;
586
	ULONG	ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
587
	size_t	tFootnoteTextLen, tBlockDepotLen, tBlockSize;
588
	size_t	tIndex;
589
 
590
	TRACE_MSG("vGet8FootnotesText");
591
 
592
	ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
593
	ulBeginOfFootnotes += ulGetLong(0x4c, aucHeader); /* ccpText */
594
	NO_DBG_HEX(ulBeginOfFootnotes);
595
 
596
	ulBeginFootnoteText = ulGetLong(0xb2, aucHeader); /* fcPlcffndTxt */
597
	NO_DBG_HEX(ulBeginFootnoteText);
598
	tFootnoteTextLen =
599
		(size_t)ulGetLong(0xb6, aucHeader); /* lcbPlcffndTxt */
600
	NO_DBG_DEC(tFootnoteTextLen);
601
 
602
	if (tFootnoteTextLen < 12) {
603
		DBG_MSG("No Footnote text in this document");
604
		return;
605
	}
606
 
607
	NO_DBG_DEC(pPPS->tTable.ulSB);
608
	NO_DBG_HEX(pPPS->tTable.ulSize);
609
	if (pPPS->tTable.ulSize == 0) {
610
		DBG_MSG("No footnote text information");
611
		return;
612
	}
613
 
614
	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
615
	  	/* Use the Small Block Depot */
616
		aulBlockDepot = aulSBD;
617
		tBlockDepotLen = tSBDLen;
618
		tBlockSize = SMALL_BLOCK_SIZE;
619
	} else {
620
	  	/* Use the Big Block Depot */
621
		aulBlockDepot = aulBBD;
622
		tBlockDepotLen = tBBDLen;
623
		tBlockSize = BIG_BLOCK_SIZE;
624
	}
625
	aucBuffer = xmalloc(tFootnoteTextLen);
626
	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
627
			aulBlockDepot, tBlockDepotLen, tBlockSize,
628
			aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) {
629
		aucBuffer = xfree(aucBuffer);
630
		return;
631
	}
632
	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
633
 
634
	fail(tFootnoteTextLength != 0);
635
	tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
636
	fail(tFootnoteTextLength == 0);
637
 
638
	fail(pFootnoteText != NULL);
639
	pFootnoteText = xcalloc(tFootnoteTextLength,
640
				sizeof(footnote_local_type));
641
 
642
	for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
643
		pCurr = pFootnoteText + tIndex;
644
		pCurr->tInfo.szText = NULL;
645
		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
646
		NO_DBG_HEX(ulOffset);
647
		ulCharPos = ulBeginOfFootnotes + ulOffset;
648
		NO_DBG_HEX(ulCharPos);
649
		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
650
		pCurr->ulCharPosStart = ulCharPos;
651
		ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
652
		NO_DBG_HEX(ulOffset);
653
		ulCharPos = ulBeginOfFootnotes + ulOffset;
654
		NO_DBG_HEX(ulCharPos);
655
		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
656
		pCurr->ulCharPosNext = ulCharPos;
657
		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
658
	}
659
	aucBuffer = xfree(aucBuffer);
660
} /* end of vGet8FootnotesText */
661
 
662
/*
663
 * Build the list with endnote information for Word 8/9/10 files
664
 */
665
static void
666
vGet8EndnotesInfo(FILE *pFile, const pps_info_type *pPPS,
667
	const ULONG *aulBBD, size_t tBBDLen,
668
	const ULONG *aulSBD, size_t tSBDLen,
669
	const UCHAR *aucHeader)
670
{
671
	const ULONG	*aulBlockDepot;
672
	UCHAR	*aucBuffer;
673
	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo;
674
	size_t	tEndnoteInfoLen, tBlockDepotLen, tBlockSize;
675
	size_t	tIndex;
676
 
677
	TRACE_MSG("vGet8EndnotesInfo");
678
 
679
	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
680
	NO_DBG_HEX(ulBeginOfText);
681
	ulBeginEndnoteInfo = ulGetLong(0x20a, aucHeader); /* fcPlcfendRef */
682
	NO_DBG_HEX(ulBeginEndnoteInfo);
683
	tEndnoteInfoLen = (size_t)ulGetLong(0x20e, aucHeader); /* lcbPlcfendRef */
684
	NO_DBG_DEC(tEndnoteInfoLen);
685
 
686
	if (tEndnoteInfoLen < 10) {
687
		DBG_MSG("No endnotes in this document");
688
		return;
689
	}
690
 
691
	NO_DBG_DEC(pPPS->tTable.ulSB);
692
	NO_DBG_HEX(pPPS->tTable.ulSize);
693
	if (pPPS->tTable.ulSize == 0) {
694
		DBG_MSG("No endnotes information");
695
		return;
696
	}
697
 
698
	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
699
	  	/* Use the Small Block Depot */
700
		aulBlockDepot = aulSBD;
701
		tBlockDepotLen = tSBDLen;
702
		tBlockSize = SMALL_BLOCK_SIZE;
703
	} else {
704
	  	/* Use the Big Block Depot */
705
		aulBlockDepot = aulBBD;
706
		tBlockDepotLen = tBBDLen;
707
		tBlockSize = BIG_BLOCK_SIZE;
708
	}
709
	aucBuffer = xmalloc(tEndnoteInfoLen);
710
	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
711
			aulBlockDepot, tBlockDepotLen, tBlockSize,
712
			aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) {
713
		aucBuffer = xfree(aucBuffer);
714
		return;
715
	}
716
	NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen);
717
 
718
	fail(tEndnoteListLength != 0);
719
	tEndnoteListLength = (tEndnoteInfoLen - 4) / 6;
720
	fail(tEndnoteListLength == 0);
721
 
722
	fail(aulEndnoteList != NULL);
723
	aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG));
724
 
725
	for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
726
		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
727
		NO_DBG_HEX(ulOffset);
728
		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
729
		NO_DBG_HEX(ulFileOffset);
730
		aulEndnoteList[tIndex] = ulFileOffset;
731
	}
732
	aucBuffer = xfree(aucBuffer);
733
} /* end of vGet8EndnotesInfo */
734
 
735
/*
736
 * Build the lists with footnote and endnote information for Word 8/9/10 files
737
 */
738
static void
739
vGet8NotesInfo(FILE *pFile, const pps_info_type *pPPS,
740
	const ULONG *aulBBD, size_t tBBDLen,
741
	const ULONG *aulSBD, size_t tSBDLen,
742
	const UCHAR *aucHeader)
743
{
744
	TRACE_MSG("vGet8NotesInfo");
745
 
746
	vGet8FootnotesInfo(pFile, pPPS,
747
			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
748
	vGet8FootnotesText(pFile, pPPS,
749
			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
750
	vGet8EndnotesInfo(pFile, pPPS,
751
			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
752
} /* end of vGet8NotesInfo */
753
 
754
/*
755
 * Build the lists with footnote and endnote information
756
 */
757
void
758
vGetNotesInfo(FILE *pFile, const pps_info_type *pPPS,
759
	const ULONG *aulBBD, size_t tBBDLen,
760
	const ULONG *aulSBD, size_t tSBDLen,
761
	const UCHAR *aucHeader, int iWordVersion)
762
{
763
	TRACE_MSG("vGetNotesInfo");
764
 
765
	fail(pFile == NULL);
766
	fail(pPPS == NULL && iWordVersion >= 6);
767
	fail(aulBBD == NULL && tBBDLen != 0);
768
	fail(aulSBD == NULL && tSBDLen != 0);
769
	fail(aucHeader == NULL);
770
 
771
	switch (iWordVersion) {
772
	case 0:
773
		vGet0NotesInfo(pFile, aucHeader);
774
		break;
775
	case 1:
776
	case 2:
777
		vGet2NotesInfo(pFile, aucHeader);
778
		break;
779
	case 4:
780
	case 5:
781
		break;
782
	case 6:
783
	case 7:
784
		vGet6NotesInfo(pFile, pPPS->tWordDocument.ulSB,
785
			aulBBD, tBBDLen, aucHeader);
786
		break;
787
	case 8:
788
		vGet8NotesInfo(pFile, pPPS,
789
			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
790
		break;
791
	default:
792
		werr(0, "Sorry, no notes information");
793
		break;
794
	}
795
} /* end of vGetNotesInfo */
796
 
797
/*
798
 *  vPrepareFootnoteText - prepare the footnote text
799
 */
800
void
801
vPrepareFootnoteText(FILE *pFile)
802
{ 
803
	footnote_local_type	*pCurr;
804
	size_t		tFootnote;
805
 
806
	fail(pFile == NULL);
807
	fail(pFootnoteText == NULL && tFootnoteTextLength != 0);
808
 
809
	if (pFootnoteText == NULL || tFootnoteTextLength == 0) {
810
		/* No information */
811
		return;
812
	}
813
 
814
	/* Fill text and useful-ness */
815
	for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) {
816
		pCurr = pFootnoteText + tFootnote;
817
		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
818
		if (pCurr->bUseful) {
819
			pCurr->tInfo.szText = szFootnoteDecryptor(pFile,
820
							pCurr->ulCharPosStart,
821
							pCurr->ulCharPosNext);
822
		} else {
823
			pCurr->tInfo.szText = NULL;
824
		}
825
	}
826
} /* end of vPrepareFootnoteText */
827
 
828
/*
829
 * szGetFootnootText - get the text of the spefified footnote
830
 */
831
const char *
832
szGetFootnootText(UINT uiFootnoteIndex)
833
{
834
	if ((size_t)uiFootnoteIndex >= tFootnoteTextLength) {
835
		return NULL;
836
	}
837
	return pFootnoteText[uiFootnoteIndex].tInfo.szText;
838
} /* end of szGetFootnootText */
839
 
840
/*
841
 * Get the notetype of the note at the given fileoffset
842
 */
843
notetype_enum
844
eGetNotetype(ULONG ulFileOffset)
845
{
846
	size_t	tIndex;
847
 
848
	TRACE_MSG("eGetNotetype");
849
 
850
	fail(aulFootnoteList == NULL && tFootnoteListLength != 0);
851
	fail(aulEndnoteList == NULL && tEndnoteListLength != 0);
852
 
853
	/* Go for the easy answers first */
854
	if (tFootnoteListLength == 0 && tEndnoteListLength == 0) {
855
		return notetype_is_unknown;
856
	}
857
	if (tEndnoteListLength == 0) {
858
		return notetype_is_footnote;
859
	}
860
	if (tFootnoteListLength == 0) {
861
		return notetype_is_endnote;
862
	}
863
	/* No easy answer, so we search */
864
	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
865
		if (aulFootnoteList[tIndex] == ulFileOffset) {
866
			return notetype_is_footnote;
867
		}
868
	}
869
	for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
870
		if (aulEndnoteList[tIndex] == ulFileOffset) {
871
			return notetype_is_endnote;
872
		}
873
	}
874
	/* Not found */
875
	return notetype_is_unknown;
876
} /* end of eGetNotetype */