1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | #ifdef HAVE_CONFIG_H1 |
34 | #include <config.h> |
35 | #endif |
36 | #include <X11/fonts/fontmisc.h> |
37 | #include "stubs.h" |
38 | |
39 | typedef struct _AtomList { |
40 | char *name; |
41 | int len; |
42 | int hash; |
43 | Atom atom; |
44 | } AtomListRec, *AtomListPtr; |
45 | |
46 | static AtomListPtr *hashTable; |
47 | |
48 | static int hashSize, hashUsed; |
49 | static int hashMask; |
50 | static int rehash; |
51 | |
52 | static AtomListPtr *reverseMap; |
53 | static int reverseMapSize; |
54 | static Atom lastAtom; |
55 | |
56 | static int |
57 | Hash(const char *string, int len) |
58 | { |
59 | int h; |
60 | |
61 | h = 0; |
62 | while (len--) |
63 | h = (h << 3) ^ *string++; |
64 | if (h < 0) |
65 | return -h; |
66 | return h; |
67 | } |
68 | |
69 | static int |
70 | ResizeHashTable (void) |
71 | { |
72 | int newHashSize; |
73 | int newHashMask; |
74 | AtomListPtr *newHashTable; |
75 | int i; |
76 | int h; |
77 | int newRehash; |
78 | int r; |
79 | |
80 | if (hashSize == 0) |
81 | newHashSize = 1024; |
82 | else |
83 | newHashSize = hashSize * 2; |
84 | newHashTable = calloc (newHashSize, sizeof (AtomListPtr)); |
85 | if (!newHashTable) { |
86 | fprintf(stderr__stderrp, "ResizeHashTable(): Error: Couldn't allocate" |
87 | " newHashTable (%ld)\n", |
88 | newHashSize * (unsigned long)sizeof (AtomListPtr)); |
89 | return FALSE0; |
90 | } |
91 | newHashMask = newHashSize - 1; |
92 | newRehash = (newHashMask - 2); |
93 | for (i = 0; i < hashSize; i++) |
94 | { |
95 | if (hashTable[i]) |
96 | { |
97 | h = (hashTable[i]->hash) & newHashMask; |
98 | if (newHashTable[h]) |
99 | { |
100 | r = hashTable[i]->hash % newRehash | 1; |
101 | do { |
102 | h += r; |
103 | if (h >= newHashSize) |
104 | h -= newHashSize; |
105 | } while (newHashTable[h]); |
106 | } |
107 | newHashTable[h] = hashTable[i]; |
108 | } |
109 | } |
110 | free (hashTable); |
111 | hashTable = newHashTable; |
112 | hashSize = newHashSize; |
113 | hashMask = newHashMask; |
114 | rehash = newRehash; |
115 | return TRUE1; |
116 | } |
117 | |
118 | static int |
119 | ResizeReverseMap (void) |
120 | { |
121 | AtomListPtr *newMap; |
122 | int newMapSize; |
123 | |
124 | if (reverseMapSize == 0) |
125 | newMapSize = 1000; |
126 | else |
127 | newMapSize = reverseMapSize * 2; |
128 | newMap = realloc (reverseMap, newMapSize * sizeof (AtomListPtr)); |
129 | if (newMap == NULL((void *)0)) { |
130 | fprintf(stderr__stderrp, "ResizeReverseMap(): Error: Couldn't reallocate" |
131 | " reverseMap (%ld)\n", |
132 | newMapSize * (unsigned long)sizeof(AtomListPtr)); |
133 | return FALSE0; |
134 | } |
135 | reverseMap = newMap; |
136 | reverseMapSize = newMapSize; |
137 | return TRUE1; |
138 | } |
139 | |
140 | static int |
141 | NameEqual (const char *a, const char *b, int l) |
142 | { |
143 | while (l--) |
144 | if (*a++ != *b++) |
145 | return FALSE0; |
146 | return TRUE1; |
147 | } |
148 | |
149 | #ifdef __SUNPRO_C |
150 | #pragma weak MakeAtom |
151 | #endif |
152 | |
153 | weak Atom |
154 | MakeAtom(const char *string, unsigned len, int makeit) |
155 | { |
156 | AtomListPtr a; |
157 | int hash; |
158 | int h = 0; |
159 | int r; |
160 | |
161 | OVERRIDE_SYMBOL(MakeAtom, string, len, makeit); |
162 | |
163 | hash = Hash (string, len); |
| 1 | Value assigned to 'hashTable' | |
|
164 | if (hashTable) |
| 2 | | Assuming 'hashTable' is null | |
|
| |
165 | { |
166 | h = hash & hashMask; |
167 | if (hashTable[h]) |
168 | { |
169 | if (hashTable[h]->hash == hash && hashTable[h]->len == len && |
170 | NameEqual (hashTable[h]->name, string, len)) |
171 | { |
172 | return hashTable[h]->atom; |
173 | } |
174 | r = (hash % rehash) | 1; |
175 | for (;;) |
176 | { |
177 | h += r; |
178 | if (h >= hashSize) |
179 | h -= hashSize; |
180 | if (!hashTable[h]) |
181 | break; |
182 | if (hashTable[h]->hash == hash && hashTable[h]->len == len && |
183 | NameEqual (hashTable[h]->name, string, len)) |
184 | { |
185 | return hashTable[h]->atom; |
186 | } |
187 | } |
188 | } |
189 | } |
190 | if (!makeit) |
| 4 | | Assuming 'makeit' is not equal to 0 | |
|
| |
191 | return None0l; |
192 | a = malloc (sizeof (AtomListRec) + len + 1); |
193 | if (a == NULL((void *)0)) { |
| 6 | | Assuming 'a' is not equal to null | |
|
| |
194 | fprintf(stderr__stderrp, "MakeAtom(): Error: Couldn't allocate AtomListRec" |
195 | " (%ld)\n", (unsigned long)sizeof (AtomListRec) + len + 1); |
196 | return None0l; |
197 | } |
198 | a->name = (char *) (a + 1); |
199 | a->len = len; |
200 | strncpy (a->name, string, len)__builtin___strncpy_chk (a->name, string, len, __builtin_object_size (a->name, 2 > 1 ? 1 : 0)); |
201 | a->name[len] = '\0'; |
202 | a->atom = ++lastAtom; |
203 | a->hash = hash; |
204 | if (hashUsed >= hashSize / 2) |
| |
205 | { |
206 | ResizeHashTable (); |
207 | h = hash & hashMask; |
208 | if (hashTable[h]) |
209 | { |
210 | r = (hash % rehash) | 1; |
211 | do { |
212 | h += r; |
213 | if (h >= hashSize) |
214 | h -= hashSize; |
215 | } while (hashTable[h]); |
216 | } |
217 | } |
218 | hashTable[h] = a; |
| 9 | | Array access (from variable 'hashTable') results in a null pointer dereference |
|
219 | hashUsed++; |
220 | if (reverseMapSize <= a->atom) { |
221 | if (!ResizeReverseMap()) |
222 | return None0l; |
223 | } |
224 | reverseMap[a->atom] = a; |
225 | return a->atom; |
226 | } |
227 | |
228 | #ifdef __SUNPRO_C |
229 | #pragma weak ValidAtom |
230 | #endif |
231 | |
232 | weak int |
233 | ValidAtom(Atom atom) |
234 | { |
235 | OVERRIDE_SYMBOL(ValidAtom, atom); |
236 | return (atom != None0l) && (atom <= lastAtom); |
237 | } |
238 | |
239 | #ifdef __SUNPRO_C |
240 | #pragma weak NameForAtom |
241 | #endif |
242 | |
243 | weak char * |
244 | NameForAtom(Atom atom) |
245 | { |
246 | OVERRIDE_SYMBOL(NameForAtom, atom); |
247 | if (atom != None0l && atom <= lastAtom) |
248 | return reverseMap[atom]->name; |
249 | return NULL((void *)0); |
250 | } |