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 "libxfontint.h" |
37 | #include <X11/fonts/fontmisc.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 | if (hashTable[i]) { |
95 | h = (hashTable[i]->hash) & newHashMask; |
96 | if (newHashTable[h]) { |
97 | r = hashTable[i]->hash % newRehash | 1; |
98 | do { |
99 | h += r; |
100 | if (h >= newHashSize) |
101 | h -= newHashSize; |
102 | } while (newHashTable[h]); |
103 | } |
104 | newHashTable[h] = hashTable[i]; |
105 | } |
106 | } |
107 | free(hashTable); |
108 | hashTable = newHashTable; |
109 | hashSize = newHashSize; |
110 | hashMask = newHashMask; |
111 | rehash = newRehash; |
112 | return TRUE1; |
113 | } |
114 | |
115 | static int |
116 | ResizeReverseMap(void) |
117 | { |
118 | AtomListPtr *newMap; |
119 | int newMapSize; |
120 | |
121 | if (reverseMapSize == 0) |
122 | newMapSize = 1000; |
123 | else |
124 | newMapSize = reverseMapSize * 2; |
125 | newMap = realloc(reverseMap, newMapSize * sizeof(AtomListPtr)); |
126 | if (newMap == NULL((void *)0)) { |
127 | fprintf(stderr__stderrp, "ResizeReverseMap(): Error: Couldn't reallocate" |
128 | " reverseMap (%ld)\n", |
129 | newMapSize * (unsigned long) sizeof(AtomListPtr)); |
130 | return FALSE0; |
131 | } |
132 | reverseMap = newMap; |
133 | reverseMapSize = newMapSize; |
134 | return TRUE1; |
135 | } |
136 | |
137 | static int |
138 | NameEqual(const char *a, const char *b, int l) |
139 | { |
140 | while (l--) |
141 | if (*a++ != *b++) |
142 | return FALSE0; |
143 | return TRUE1; |
144 | } |
145 | |
146 | Atom |
147 | __libxfont_internal__MakeAtom(const char *string, unsigned len, int makeit) |
148 | { |
149 | AtomListPtr a; |
150 | int hash; |
151 | int h = 0; |
152 | int r; |
153 | |
154 | hash = Hash(string, len); |
155 | if (hashTable) { |
| 1 | Assuming 'hashTable' is null | |
|
| |
156 | h = hash & hashMask; |
157 | if (hashTable[h]) { |
158 | if (hashTable[h]->hash == hash && hashTable[h]->len == len && |
159 | NameEqual(hashTable[h]->name, string, len)) { |
160 | return hashTable[h]->atom; |
161 | } |
162 | r = (hash % rehash) | 1; |
163 | for (;;) { |
164 | h += r; |
165 | if (h >= hashSize) |
166 | h -= hashSize; |
167 | if (!hashTable[h]) |
168 | break; |
169 | if (hashTable[h]->hash == hash && hashTable[h]->len == len && |
170 | NameEqual(hashTable[h]->name, string, len)) { |
171 | return hashTable[h]->atom; |
172 | } |
173 | } |
174 | } |
175 | } |
176 | if (!makeit) |
| 3 | | Assuming 'makeit' is not equal to 0 | |
|
| |
177 | return None0L; |
178 | a = malloc(sizeof(AtomListRec) + len + 1); |
179 | if (a == NULL((void *)0)) { |
| 5 | | Assuming 'a' is not equal to null | |
|
| |
180 | fprintf(stderr__stderrp, "MakeAtom(): Error: Couldn't allocate AtomListRec" |
181 | " (%ld)\n", (unsigned long) sizeof(AtomListRec) + len + 1); |
182 | return None0L; |
183 | } |
184 | a->name = (char *) (a + 1); |
185 | a->len = len; |
186 | strncpy(a->name, string, len)__builtin___strncpy_chk (a->name, string, len, __builtin_object_size (a->name, 2 > 1 ? 1 : 0)); |
187 | a->name[len] = '\0'; |
188 | a->atom = ++lastAtom; |
189 | a->hash = hash; |
190 | if (hashUsed >= hashSize / 2) { |
| |
191 | ResizeHashTable(); |
192 | h = hash & hashMask; |
193 | if (hashTable[h]) { |
| 8 | | Array access (from variable 'hashTable') results in a null pointer dereference |
|
194 | r = (hash % rehash) | 1; |
195 | do { |
196 | h += r; |
197 | if (h >= hashSize) |
198 | h -= hashSize; |
199 | } while (hashTable[h]); |
200 | } |
201 | } |
202 | hashTable[h] = a; |
203 | hashUsed++; |
204 | if (reverseMapSize <= a->atom) { |
205 | if (!ResizeReverseMap()) |
206 | return None0L; |
207 | } |
208 | reverseMap[a->atom] = a; |
209 | return a->atom; |
210 | } |
211 | |
212 | int |
213 | __libxfont_internal__ValidAtom(Atom atom) |
214 | { |
215 | return (atom != None0L) && (atom <= lastAtom); |
216 | } |
217 | |
218 | const char * |
219 | __libxfont_internal__NameForAtom(Atom atom) |
220 | { |
221 | if (atom != None0L && atom <= lastAtom) |
222 | return reverseMap[atom]->name; |
223 | return NULL((void *)0); |
224 | } |