Mercurial > code
comparison array.c @ 29:19c0d2e11406
Security fixes for array
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 22 Sep 2011 21:07:51 +0200 |
parents | 904a373aa120 |
children | e2c3a0a549d2 |
comparison
equal
deleted
inserted
replaced
28:904a373aa120 | 29:19c0d2e11406 |
---|---|
102 | 102 |
103 return 0; | 103 return 0; |
104 } | 104 } |
105 | 105 |
106 /* | 106 /* |
107 * Remove the array's head and return the object or NULL if | 107 * Remove the array's head. |
108 * the array is empty. | 108 */ |
109 */ | 109 |
110 | 110 void |
111 void * | |
112 array_pop(struct array *arr) | 111 array_pop(struct array *arr) |
113 { | 112 { |
114 void *data; | 113 if (arr->length > 0) { |
115 | 114 memmove((char *) arr->data, (char *) arr->data + SIZE(1), |
116 if (arr->length == 0) | 115 SIZE(--arr->length)); |
117 return NULL; | 116 memset((char *) arr->data + SIZE(arr->length), 0, arr->unit); |
118 | 117 } |
119 data = arr->data; | 118 } |
120 memmove((char *) arr->data, (char *) arr->data + SIZE(1), | 119 |
121 SIZE(arr->length)); | 120 /* |
122 memset((char *) arr->data + SIZE(--arr->length), 0, arr->unit); | 121 * Remove the array's tail. |
123 | 122 */ |
124 return data; | 123 |
125 } | 124 void |
126 | |
127 /* | |
128 * Remove the array's queue and return the object or NULL | |
129 * if the array is empty. | |
130 */ | |
131 | |
132 void * | |
133 array_unqueue(struct array *arr) | 125 array_unqueue(struct array *arr) |
134 { | 126 { |
135 void *data; | 127 if (arr->length > 0) |
136 | 128 memset((char *) arr->data + SIZE(--arr->length), 0, arr->unit); |
137 if (arr->length == 0) | 129 } |
138 return NULL; | 130 |
139 | 131 /* |
140 data = (char *) arr->data + SIZE(--arr->length); | 132 * Remove the data at the specified index. Bounds are checked. |
141 memset((char *) arr->data + SIZE(arr->length), 0, arr->unit); | 133 */ |
142 | 134 |
143 return data; | 135 void |
144 } | |
145 | |
146 /* | |
147 * Remove the entry at the specified index and return it. If the index is out of | |
148 * bounds or the list is empty the functions returns NULL. | |
149 */ | |
150 | |
151 void * | |
152 array_remove(struct array *arr, int index) | 136 array_remove(struct array *arr, int index) |
153 { | 137 { |
154 void *data; | 138 if (arr->length > 0 && index >= 0 && index < arr->length) { |
155 | 139 memmove((char *) arr->data + SIZE(index), |
156 if (arr->length == 0 || index < 0 || index > arr->length - 1) | 140 (char *) arr->data + SIZE(index + 1), |
157 return NULL; | 141 SIZE(arr->length - index - 1)); |
158 | 142 memset((char *) arr->data + SIZE(--arr->length), 0, arr->unit); |
159 data = (char *) arr->data + SIZE(index); | 143 } |
160 memmove((char *) arr->data + SIZE(index), | |
161 (char *) arr->data + SIZE(index + 1), SIZE(arr->length - index)); | |
162 memset((char *) arr->data + SIZE(--arr->length), 0, arr->unit); | |
163 | |
164 return data; | |
165 } | 144 } |
166 | 145 |
167 /* | 146 /* |
168 * Swap the two elements referenced by index `i1' and `i2'. This function needs | 147 * Swap the two elements referenced by index `i1' and `i2'. This function needs |
169 * to allocate data to swap elements thus if the functions fails it returns -1 | 148 * to allocate data to swap elements thus if the functions fails it returns -1 |
172 | 151 |
173 int | 152 int |
174 array_swap(struct array *arr, int i1, int i2) | 153 array_swap(struct array *arr, int i1, int i2) |
175 { | 154 { |
176 /* Out of bounds */ | 155 /* Out of bounds */ |
177 if (i1 > arr->length - 1|| i1 < 0 || i2 > arr->length - 1 || i2 < 0) | 156 if (i1 >= arr->length || i1 < 0 || i2 >= arr->length || i2 < 0) |
178 return -1; | 157 return -1; |
179 | 158 |
180 /* | 159 /* |
181 * Only allocate at this time, the user may do not want to use this | 160 * Only allocate at this time, the user may do not want to use this |
182 * function. | 161 * function. |
197 * Apply the function `fn' on each object and give the optional `udata' | 176 * Apply the function `fn' on each object and give the optional `udata' |
198 * argument to the function too. | 177 * argument to the function too. |
199 */ | 178 */ |
200 | 179 |
201 void | 180 void |
202 array_map(struct array *arr, void (*fn)(void *, void *), void *udata) | 181 array_map(const struct array *arr, void (*fn)(void *, void *), void *udata) |
203 { | 182 { |
204 int i; | 183 int i; |
205 | 184 |
206 for (i = 0; i < arr->length; ++i) | 185 for (i = 0; i < arr->length; ++i) |
207 fn((char *) arr->data + SIZE(i), udata); | 186 fn((char *) arr->data + SIZE(i), udata); |
213 * indicate the data position. If the data was not found the function returns | 192 * indicate the data position. If the data was not found the function returns |
214 * NULL. | 193 * NULL. |
215 */ | 194 */ |
216 | 195 |
217 void * | 196 void * |
218 array_find(struct array *arr, int (*fn)(void *, void *), int *idx, void *udata) | 197 array_find(const struct array *arr, int (*fn)(void *, void *), int *ix, void *u) |
219 { | 198 { |
220 int st, i; | 199 int st, i; |
221 void *data; | 200 void *data; |
222 | 201 |
223 for (i = st = 0; i < arr->length && st != 1; ++i) | 202 for (i = st = 0; i < arr->length && st != 1; ++i) |
224 st = fn((char *) arr->data + SIZE(i), udata); | 203 st = fn((char *) arr->data + SIZE(i), u); |
225 | 204 |
226 if (st) { | 205 if (st) { |
227 data = (char *) arr->data + SIZE(--i); | 206 data = (char *) arr->data + SIZE(--i); |
228 if (idx) | 207 if (ix) |
229 *idx = i; | 208 *ix = i; |
230 } else | 209 } else |
231 data = NULL; | 210 data = NULL; |
232 | 211 |
233 return data; | 212 return data; |
234 } | 213 } |
279 SIZE(arr->bsize))) == NULL) | 258 SIZE(arr->bsize))) == NULL) |
280 return -1; | 259 return -1; |
281 | 260 |
282 arr->size += SIZE(arr->bsize); | 261 arr->size += SIZE(arr->bsize); |
283 } else | 262 } else |
284 return (arr->size / arr->unit <= (size_t) arr->length) ? -1 : 0; | 263 return -1; |
285 | 264 |
286 return 0; | 265 return 0; |
287 } | 266 } |