1 /*
2  * depot.c
3  * Copyright (C) 1998-2002 A.J. van Os; Released under GPL
4  *
5  * Description:
6  * Functions to compute the depot offset
7  */
8 
9 #include "antiword.h"
10 
11 #define SIZE_RATIO	(BIG_BLOCK_SIZE/SMALL_BLOCK_SIZE)
12 
13 static ULONG	*aulSmallBlockList = NULL;
14 static size_t	tSmallBlockListLen = 0;
15 
16 
17 /*
18  * vDestroySmallBlockList - destroy the small block list
19  */
20 void
vDestroySmallBlockList(void)21 vDestroySmallBlockList(void)
22 {
23 	DBG_MSG("vDestroySmallBlockList");
24 
25 	aulSmallBlockList = xfree(aulSmallBlockList);
26 	tSmallBlockListLen = 0;
27 } /* end of vDestroySmalBlockList */
28 
29 /*
30  * vCreateSmallBlockList - create the small block list
31  *
32  * returns: TRUE when successful, otherwise FALSE
33  */
34 BOOL
bCreateSmallBlockList(ULONG ulStartblock,const ULONG * aulBBD,size_t tBBDLen)35 bCreateSmallBlockList(ULONG ulStartblock, const ULONG *aulBBD, size_t tBBDLen)
36 {
37 	ULONG	ulTmp;
38 	size_t	tSize;
39 	int	iIndex;
40 
41 	fail(aulSmallBlockList != NULL);
42 	fail(tSmallBlockListLen != 0);
43 	fail(ulStartblock > MAX_BLOCKNUMBER && ulStartblock != END_OF_CHAIN);
44 	fail(aulBBD == NULL);
45 	fail(tBBDLen == 0);
46 
47 	/* Find the length of the small block list */
48 	for (tSmallBlockListLen = 0, ulTmp = ulStartblock;
49 	     tSmallBlockListLen < tBBDLen && ulTmp != END_OF_CHAIN;
50 	     tSmallBlockListLen++, ulTmp = aulBBD[ulTmp]) {
51 		if (ulTmp >= (ULONG)tBBDLen) {
52 			DBG_DEC(ulTmp);
53 			DBG_DEC(tBBDLen);
54 			werr(1, "The Big Block Depot is damaged");
55 		}
56 	}
57 	DBG_DEC(tSmallBlockListLen);
58 
59 	if (tSmallBlockListLen == 0) {
60 		/* There is no small block list */
61 		fail(ulStartblock != END_OF_CHAIN);
62 		aulSmallBlockList = NULL;
63 		return TRUE;
64 	}
65 
66 	/* Create the small block list */
67 	tSize = tSmallBlockListLen * sizeof(ULONG);
68 	aulSmallBlockList = xmalloc(tSize);
69 	for (iIndex = 0, ulTmp = ulStartblock;
70 	     iIndex < (int)tBBDLen && ulTmp != END_OF_CHAIN;
71 	     iIndex++, ulTmp = aulBBD[ulTmp]) {
72 		if (ulTmp >= (ULONG)tBBDLen) {
73 			DBG_DEC(ulTmp);
74 			DBG_DEC(tBBDLen);
75 			werr(1, "The Big Block Depot is damaged");
76 		}
77 		aulSmallBlockList[iIndex] = ulTmp;
78 		NO_DBG_DEC(aulSmallBlockList[iIndex]);
79 	}
80 	return TRUE;
81 } /* end of bCreateSmallBlockList */
82 
83 /*
84  * ulDepotOffset - get the depot offset the block list
85  */
86 ULONG
ulDepotOffset(ULONG ulIndex,size_t tBlockSize)87 ulDepotOffset(ULONG ulIndex, size_t tBlockSize)
88 {
89 	ULONG	ulTmp;
90 	size_t	tTmp;
91 
92 	fail(ulIndex >= ULONG_MAX / BIG_BLOCK_SIZE);
93 
94 	switch (tBlockSize) {
95 	case BIG_BLOCK_SIZE:
96 		return (ulIndex + 1) * BIG_BLOCK_SIZE;
97 	case SMALL_BLOCK_SIZE:
98 		tTmp = (size_t)(ulIndex / SIZE_RATIO);
99 		ulTmp = ulIndex % SIZE_RATIO;
100 		if (aulSmallBlockList == NULL ||
101 		    tTmp >= tSmallBlockListLen) {
102 			DBG_HEX(aulSmallBlockList);
103 			DBG_DEC(tSmallBlockListLen);
104 			DBG_DEC(tTmp);
105 			return 0;
106 		}
107 		return ((aulSmallBlockList[tTmp] + 1) * SIZE_RATIO +
108 				ulTmp) * SMALL_BLOCK_SIZE;
109 	default:
110 		DBG_DEC(tBlockSize);
111 		DBG_FIXME();
112 		return 0;
113 	}
114 } /* end of ulDepotOffset */
115