Coverage Report

Created: 2025-07-11 06:42

/src/libhtp/htp/htp_list.c
Line
Count
Source (jump to first uncovered line)
1
/***************************************************************************
2
 * Copyright (c) 2009-2010 Open Information Security Foundation
3
 * Copyright (c) 2010-2013 Qualys, Inc.
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are
8
 * met:
9
 *
10
 * - Redistributions of source code must retain the above copyright
11
 *   notice, this list of conditions and the following disclaimer.
12
13
 * - Redistributions in binary form must reproduce the above copyright
14
 *   notice, this list of conditions and the following disclaimer in the
15
 *   documentation and/or other materials provided with the distribution.
16
17
 * - Neither the name of the Qualys, Inc. nor the names of its
18
 *   contributors may be used to endorse or promote products derived from
19
 *   this software without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
 ***************************************************************************/
33
34
/**
35
 * @file
36
 * @author Ivan Ristic <ivanr@webkreator.com>
37
 */
38
39
#include "htp_config_auto.h"
40
41
#include "htp_private.h"
42
43
// Array-backed list
44
45
438k
htp_status_t htp_list_array_init(htp_list_t *l, size_t size) {
46
    // Allocate the initial batch of elements.
47
438k
    l->elements = malloc(size * sizeof (void *));
48
438k
    if (l->elements == NULL) {
49
0
        return HTP_ERROR;
50
0
    }
51
52
    // Initialize the structure.
53
438k
    l->first = 0;
54
438k
    l->last = 0;
55
438k
    l->current_size = 0;
56
438k
    l->max_size = size;
57
58
438k
    return HTP_OK;
59
438k
}
60
61
158k
htp_list_t *htp_list_array_create(size_t size) {
62
    // It makes no sense to create a zero-size list.
63
158k
    if (size == 0) return NULL;
64
65
    // Allocate the list structure.
66
158k
    htp_list_array_t *l = calloc(1, sizeof (htp_list_array_t));
67
158k
    if (l == NULL) return NULL;
68
69
158k
    if (htp_list_array_init(l, size) == HTP_ERROR) {
70
0
        free(l);
71
0
        return NULL;
72
0
    }
73
74
158k
    return (htp_list_t *) l;
75
158k
}
76
77
300k
void htp_list_array_clear(htp_list_array_t *l) {
78
300k
    if (l == NULL) return;
79
80
    // Continue using already allocated memory; just reset the fields.
81
300k
    l->first = 0;
82
300k
    l->last = 0;
83
300k
    l->current_size = 0;
84
300k
}
85
86
158k
void htp_list_array_destroy(htp_list_array_t *l) {
87
158k
    if (l == NULL) return;
88
89
158k
    free(l->elements);
90
158k
    free(l);
91
158k
}
92
93
279k
void htp_list_array_release(htp_list_array_t *l) {
94
279k
    if (l == NULL) return;
95
96
279k
    free(l->elements);
97
279k
}
98
99
18.2M
void *htp_list_array_get(const htp_list_array_t *l, size_t idx) {
100
18.2M
    if (l == NULL) return NULL;    
101
18.2M
    if (idx >= l->current_size) return NULL;
102
    
103
18.2M
    if (l->first + idx < l->max_size) {
104
18.2M
        return (void *) l->elements[l->first + idx];
105
18.2M
    } else {        
106
0
        return (void *) l->elements[idx - (l->max_size - l->first)];
107
0
    }
108
18.2M
}
109
110
0
void *htp_list_array_pop(htp_list_array_t *l) {
111
0
    if (l == NULL) return NULL;
112
113
0
    const void *r = NULL;
114
115
0
    if (l->current_size == 0) {
116
0
        return NULL;
117
0
    }
118
119
0
    size_t pos = l->first + l->current_size - 1;
120
0
    if (pos > l->max_size - 1) pos -= l->max_size;
121
122
0
    r = l->elements[pos];
123
0
    l->last = pos;
124
125
0
    l->current_size--;
126
127
0
    return (void *) r;
128
0
}
129
130
3.63M
htp_status_t htp_list_array_push(htp_list_array_t *l, void *e) {
131
3.63M
    if (l == NULL) return HTP_ERROR;
132
133
    // Check whether we're full
134
3.63M
    if (l->current_size >= l->max_size) {
135
11.3k
        size_t new_size = l->max_size * 2;
136
11.3k
        void *newblock = NULL;
137
138
11.3k
        if (l->first == 0) {
139
            // The simple case of expansion is when the first
140
            // element in the list resides in the first slot. In
141
            // that case we just add some new space to the end,
142
            // adjust the max_size and that's that.
143
11.3k
            newblock = realloc(l->elements, new_size * sizeof (void *));
144
11.3k
            if (newblock == NULL) return HTP_ERROR;
145
11.3k
        } else {
146
            // When the first element is not in the first
147
            // memory slot, we need to rearrange the order
148
            // of the elements in order to expand the storage area.
149
            /* coverity[suspicious_sizeof] */
150
0
            newblock = malloc((size_t) (new_size * sizeof (void *)));
151
0
            if (newblock == NULL) return HTP_ERROR;
152
153
            // Copy the beginning of the list to the beginning of the new memory block
154
            /* coverity[suspicious_sizeof] */
155
0
            memcpy(newblock,
156
0
                    (void *) ((char *) l->elements + l->first * sizeof (void *)),
157
0
                    (size_t) ((l->max_size - l->first) * sizeof (void *)));
158
159
            // Append the second part of the list to the end
160
0
            memcpy((void *) ((char *) newblock + (l->max_size - l->first) * sizeof (void *)),
161
0
                    (void *) l->elements,
162
0
                    (size_t) (l->first * sizeof (void *)));
163
164
0
            free(l->elements);
165
0
        }
166
167
11.3k
        l->first = 0;
168
11.3k
        l->last = l->current_size;
169
11.3k
        l->max_size = new_size;
170
11.3k
        l->elements = newblock;
171
11.3k
    }
172
173
3.63M
    l->elements[l->last] = e;
174
3.63M
    l->current_size++;
175
176
3.63M
    l->last++;
177
3.63M
    if (l->last == l->max_size) {
178
11.8k
        l->last = 0;
179
11.8k
    }
180
181
3.63M
    return HTP_OK;
182
3.63M
}
183
184
93.1k
htp_status_t htp_list_array_replace(htp_list_array_t *l, size_t idx, void *e) {
185
93.1k
    if (l == NULL) return HTP_ERROR;
186
187
93.1k
    if (idx + 1 > l->current_size) return HTP_DECLINED;
188
189
93.1k
    l->elements[(l->first + idx) % l->max_size] = e;
190
191
93.1k
    return HTP_OK;
192
93.1k
}
193
194
7.95M
size_t htp_list_array_size(const htp_list_array_t *l) {
195
7.95M
    if (l == NULL) return HTP_ERROR;
196
197
7.95M
    return l->current_size;
198
7.95M
}
199
200
0
void *htp_list_array_shift(htp_list_array_t *l) {
201
0
    if (l == NULL) return NULL;
202
203
0
    void *r = NULL;
204
205
0
    if (l->current_size == 0) {
206
0
        return NULL;
207
0
    }
208
209
0
    r = l->elements[l->first];
210
0
    l->first++;
211
0
    if (l->first == l->max_size) {
212
0
        l->first = 0;
213
0
    }
214
215
0
    l->current_size--;
216
217
0
    return r;
218
0
}
219
220
#if 0
221
// Linked list
222
223
htp_list_linked_t *htp_list_linked_create(void) {
224
    htp_list_linked_t *l = calloc(1, sizeof (htp_list_linked_t));
225
    if (l == NULL) return NULL;
226
227
    return l;
228
}
229
230
void htp_list_linked_destroy(htp_list_linked_t *l) {
231
    if (l == NULL) return;
232
233
    // Free the list structures
234
    htp_list_linked_element_t *temp = l->first;
235
    htp_list_linked_element_t *prev = NULL;
236
    while (temp != NULL) {
237
        free(temp->data);
238
        prev = temp;
239
        temp = temp->next;
240
        free(prev);
241
    }
242
243
    // Free the list itself
244
    free(l);
245
}
246
247
int htp_list_linked_empty(const htp_list_linked_t *l) {
248
    if (!l->first) {
249
        return 1;
250
    } else {
251
        return 0;
252
    }
253
}
254
255
void *htp_list_linked_pop(htp_list_linked_t *l) {
256
    void *r = NULL;
257
258
    if (!l->first) {
259
        return NULL;
260
    }
261
262
    // Find the last element
263
    htp_list_linked_element_t *qprev = NULL;
264
    htp_list_linked_element_t *qe = l->first;
265
    while (qe->next != NULL) {
266
        qprev = qe;
267
        qe = qe->next;
268
    }
269
270
    r = qe->data;
271
    free(qe);
272
273
    if (qprev != NULL) {
274
        qprev->next = NULL;
275
        l->last = qprev;
276
    } else {
277
        l->first = NULL;
278
        l->last = NULL;
279
    }
280
281
    return r;
282
}
283
284
int htp_list_linked_push(htp_list_linked_t *l, void *e) {
285
    htp_list_linked_element_t *le = calloc(1, sizeof (htp_list_linked_element_t));
286
    if (le == NULL) return -1;
287
288
    // Remember the element
289
    le->data = e;
290
291
    // If the queue is empty, make this element first
292
    if (!l->first) {
293
        l->first = le;
294
    }
295
296
    if (l->last) {
297
        l->last->next = le;
298
    }
299
300
    l->last = le;
301
302
    return 1;
303
}
304
305
void *htp_list_linked_shift(htp_list_linked_t *l) {
306
    void *r = NULL;
307
308
    if (!l->first) {
309
        return NULL;
310
    }
311
312
    htp_list_linked_element_t *le = l->first;
313
    l->first = le->next;
314
    r = le->data;
315
316
    if (!l->first) {
317
        l->last = NULL;
318
    }
319
320
    free(le);
321
322
    return r;
323
}
324
#endif
325
326
#if 0
327
328
int main(int argc, char **argv) {
329
    htp_list_t *q = htp_list_array_create(4);
330
331
    htp_list_push(q, "1");
332
    htp_list_push(q, "2");
333
    htp_list_push(q, "3");
334
    htp_list_push(q, "4");
335
336
    htp_list_shift(q);
337
    htp_list_push(q, "5");
338
    htp_list_push(q, "6");
339
340
    char *s = NULL;
341
    while ((s = (char *) htp_list_pop(q)) != NULL) {
342
        printf("Got: %s\n", s);
343
    }
344
345
    printf("---\n");
346
347
    htp_list_push(q, "1");
348
    htp_list_push(q, "2");
349
    htp_list_push(q, "3");
350
    htp_list_push(q, "4");
351
352
    while ((s = (char *) htp_list_shift(q)) != NULL) {
353
        printf("Got: %s\n", s);
354
    }
355
356
    free(q);
357
358
    return 0;
359
}
360
#endif