1 #include "foxtoken.h"
2 #include "foxobjtab.h"
3 #include "foxreport.h"
4 
5 #define OBJ_TABLE_NUM_ENTRIES 4111 //Prime number
6 
7 static ObjTableEntry *table[OBJ_TABLE_NUM_ENTRIES];
8 
9 /*
10  * Table Definition and Declaration
11  */
12 typedef struct _PDFObjectTable {
13 	uint32_t numEntries;
14 	uint32_t tableSize;
15 	ObjTableEntry **table;
16 } PDFObjectTable;
17 
18 static PDFObjectTable ObjTable;
19 
20 /*
21  * Constructor
22  *
23  * Initialized Object Table
24  */
initObjTable()25 __attribute__ ((constructor)) void initObjTable () {
26     int i;
27 	for (i = 0; i < OBJ_TABLE_NUM_ENTRIES; i++) {
28 		table[i] = NULL;
29 	}
30 
31 	ObjTable.table = table;
32 	ObjTable.numEntries = 0;
33 	ObjTable.tableSize = OBJ_TABLE_NUM_ENTRIES;
34 }
35 
36 /*
37  * Find slot for object
38  */
hashObj(ObjTableEntry * entry)39 static uint32_t hashObj (ObjTableEntry *entry) {
40 	return (entry->refnum % OBJ_TABLE_NUM_ENTRIES);
41 }
42 
43 /*
44  *
45  * Initializes new object table entry
46  *
47  */
getNewObjTabEntry()48 ObjTableEntry *getNewObjTabEntry() {
49 	ObjTableEntry *entry;
50 
51 	if ((entry = calloc(1, sizeof(ObjTableEntry))) == NULL) {
52 		foxLog(FATAL, "%s: Could not allocate memory.\n", __func__);
53 		return NULL;
54 	}
55 
56 	return entry;
57 }
58 
59 /*
60  *
61  * Adds an entry to the table by ref, then rev
62  *
63  */
addPDFObjEntry(ObjTableEntry * entry)64 int addPDFObjEntry (ObjTableEntry *entry) {
65 
66     uint32_t index;
67 	ObjTableEntry *temp;
68 
69 	index = hashObj(entry);
70 
71 	if (table[index] == NULL) {
72 		table[index] = entry;
73 	}
74 	else {
75         temp = table[index];
76 
77 	    if (temp->refnum == entry->refnum && temp->revnum == entry->revnum) {
78 		    foxLog(NONFATAL, "%s: Entry already exists with that ref/rev.\n", __func__);
79 		    return 0;
80 	    }
81 
82 		while (temp->next != NULL) {
83             temp = temp->next;
84 
85             if (temp->refnum == entry->refnum && temp->revnum == entry->revnum) {
86                 foxLog(NONFATAL, "%s: Entry already exists with that ref/rev.\n", __func__);
87                 return 0;
88             }
89 		}
90 
91         temp->next = entry;
92 	}
93 
94     return 1;
95 
96 }
97 
98 /*
99  * Retrieve entry by ref and rev
100  *
101  */
getPDFObjEntry(uint32_t refnum,uint32_t revnum)102 ObjTableEntry *getPDFObjEntry (uint32_t refnum, uint32_t revnum) {
103     ObjTableEntry *entry;
104 
105 	entry = table[refnum];
106 
107 	while (entry != NULL) {
108 		if (entry->refnum == refnum && entry->revnum == revnum)
109 			return entry;
110 
111 		entry = entry->next;
112 	}
113 
114 	return NULL;
115 }
116 
117 /*
118  * Cycle through table and pass by the next
119  * unresolved object on the table.
120  *
121  */
getNextUnresolved()122 ObjTableEntry *getNextUnresolved() {
123 	static unsigned int index = 0, ready = 1;
124 	static ObjTableEntry *temp, *entry;
125 
126     for (;index < ObjTable.tableSize; index++) {
127 		if (ready)
128 		    temp = ObjTable.table[index];
129 		while (temp != NULL) {
130 			if (temp->fullyResolved == 0) {
131 				ready = 0;
132 				entry = temp;
133 				temp = temp->next;
134 				return entry;
135 			}
136 			temp = temp->next;
137 		}
138 		index++;
139 		ready = 1;
140 	}
141 
142 	return NULL;
143 }
144 
145 /*
146  * This is for DEBUG purposes
147  *
148  * Do one final check to see if we missed any indirect
149  * references.
150  *
151  */
countUnresolved()152 __attribute__ ((destructor)) void countUnresolved() {
153 
154 	ObjTableEntry *temp, *entry;
155 #ifdef PDF_FOX_SHOW_DEBUG
156 	unsigned int index;
157 	uint32_t count = 0;
158 
159 	for (index = 0; index < ObjTable.tableSize; index++) {
160 		temp = ObjTable.table[index];
161 		while (temp != NULL) {
162 			if (temp->fullyResolved == 0) {
163 			    count++;
164 			}
165 			temp = temp->next;
166 		}
167 		index++;
168 	}
169 
170 	foxLog(PDF_DEBUG, "Remaining unresolved references = %d\n.", count);
171 #endif
172     uint32_t i;
173 
174 	for (i = 0; i < ObjTable.tableSize; i++) {
175 		temp = ObjTable.table[i];
176 		while (temp != NULL) {
177 			entry = temp->next;
178 			free(temp);
179 			temp = entry;
180 		}
181 		i++;
182 	}
183 
184 }
185