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 }