Coverage Report

Created: 2025-07-23 07:29

/src/suricata7/libhtp/htp/htp_table.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
355k
static htp_status_t _htp_table_add(htp_table_t *table, const bstr *key, const void *element) {
44
    // Add key.
45
355k
    if (htp_list_add(&table->list, (void *)key) != HTP_OK) return HTP_ERROR;
46
47
    // Add element.
48
355k
    if (htp_list_add(&table->list, (void *)element) != HTP_OK) {
49
0
        htp_list_pop(&table->list);
50
0
        return HTP_ERROR;
51
0
    }
52
53
355k
    return HTP_OK;
54
355k
}
55
56
355k
htp_status_t htp_table_add(htp_table_t *table, const bstr *key, const void *element) {
57
355k
    if ((table == NULL)||(key == NULL)) return HTP_ERROR;
58
    
59
    // Keep track of how keys are allocated, and
60
    // ensure that all invocations are consistent.
61
355k
    if (table->alloc_type == HTP_TABLE_KEYS_ALLOC_UKNOWN) {
62
142k
        table->alloc_type = HTP_TABLE_KEYS_COPIED;
63
213k
    } else {
64
213k
        if (table->alloc_type != HTP_TABLE_KEYS_COPIED) {
65
            #ifdef HTP_DEBUG
66
            fprintf(stderr, "# Inconsistent key management strategy. Actual %d. Attempted %d.\n",
67
                table->alloc_type, HTP_TABLE_KEYS_COPIED);
68
            #endif
69
            
70
0
            return HTP_ERROR;
71
0
        }
72
213k
    }
73
74
355k
    bstr *dupkey = bstr_dup(key);
75
355k
    if (dupkey == NULL) return HTP_ERROR;
76
77
355k
    if (_htp_table_add(table, dupkey, element) != HTP_OK) {
78
0
        bstr_free(dupkey);
79
0
        return HTP_ERROR;
80
0
    }
81
82
355k
    return HTP_OK;
83
355k
}
84
85
0
htp_status_t htp_table_addn(htp_table_t *table, const bstr *key, const void *element) {
86
0
    if ((table == NULL)||(key == NULL)) return HTP_ERROR;
87
    
88
    // Keep track of how keys are allocated, and
89
    // ensure that all invocations are consistent.
90
0
    if (table->alloc_type == HTP_TABLE_KEYS_ALLOC_UKNOWN) {
91
0
        table->alloc_type = HTP_TABLE_KEYS_ADOPTED;
92
0
    } else {
93
0
        if (table->alloc_type != HTP_TABLE_KEYS_ADOPTED) {
94
            #ifdef HTP_DEBUG
95
            fprintf(stderr, "# Inconsistent key management strategy. Actual %d. Attempted %d.\n",
96
                table->alloc_type, HTP_TABLE_KEYS_ADOPTED);
97
            #endif
98
99
0
            return HTP_ERROR;
100
0
        }
101
0
    }
102
103
0
    return _htp_table_add(table, key, element);
104
0
}
105
106
0
htp_status_t htp_table_addk(htp_table_t *table, const bstr *key, const void *element) {
107
0
    if ((table == NULL)||(key == NULL)) return HTP_ERROR;
108
    
109
    // Keep track of how keys are allocated, and
110
    // ensure that all invocations are consistent.
111
0
    if (table->alloc_type == HTP_TABLE_KEYS_ALLOC_UKNOWN) {
112
0
        table->alloc_type = HTP_TABLE_KEYS_REFERENCED;
113
0
    } else {
114
0
        if (table->alloc_type != HTP_TABLE_KEYS_REFERENCED) {
115
            #ifdef HTP_DEBUG
116
            fprintf(stderr, "# Inconsistent key management strategy. Actual %d. Attempted %d.\n",
117
                table->alloc_type, HTP_TABLE_KEYS_REFERENCED);
118
            #endif
119
120
0
            return HTP_ERROR;
121
0
        }
122
0
    }
123
124
0
    return _htp_table_add(table, key, element);
125
0
}
126
127
740k
void htp_table_clear(htp_table_t *table) {
128
740k
    if (table == NULL) return;
129
130
    // Free the table keys, but only if we're managing them.
131
740k
    if ((table->alloc_type == HTP_TABLE_KEYS_COPIED)||(table->alloc_type == HTP_TABLE_KEYS_ADOPTED)) {
132
144k
        bstr *key = NULL;
133
499k
        for (size_t i = 0, n = htp_list_size(&table->list); i < n; i += 2) {
134
355k
            key = htp_list_get(&table->list, i);
135
355k
            bstr_free(key);
136
355k
        }
137
144k
    }
138
139
740k
    htp_list_clear(&table->list);
140
740k
}
141
142
0
void htp_table_clear_ex(htp_table_t *table) {
143
0
    if (table == NULL) return;
144
145
    // This function does not free table keys.
146
147
0
    htp_list_clear(&table->list);
148
0
}
149
150
737k
htp_table_t *htp_table_create(size_t size) {
151
737k
    if (size == 0) return NULL;
152
153
737k
    htp_table_t *table = calloc(1, sizeof (htp_table_t));
154
737k
    if (table == NULL) return NULL;
155
156
737k
    table->alloc_type = HTP_TABLE_KEYS_ALLOC_UKNOWN;
157
158
    // Use a list behind the scenes.
159
737k
    if (htp_list_init(&table->list, size * 2) == HTP_ERROR) {
160
0
        free(table);
161
0
        return NULL;
162
0
    }
163
164
737k
    return table;
165
737k
}
166
167
737k
void htp_table_destroy(htp_table_t *table) {
168
737k
    if (table == NULL) return;
169
170
737k
    htp_table_clear(table);
171
172
737k
    htp_list_array_release(&table->list);
173
174
737k
    free(table);
175
737k
}
176
177
0
void htp_table_destroy_ex(htp_table_t *table) {
178
0
    if (table == NULL) return;
179
180
    // Change allocation strategy in order to
181
    // prevent the keys from being freed.
182
0
    table->alloc_type = HTP_TABLE_KEYS_REFERENCED;
183
184
0
    htp_table_destroy(table);
185
0
}
186
187
984k
void *htp_table_get(const htp_table_t *table, const bstr *key) {
188
984k
    if ((table == NULL)||(key == NULL)) return NULL;
189
190
    // Iterate through the list, comparing
191
    // keys with the parameter, return data if found.    
192
2.23M
    for (size_t i = 0, n = htp_list_size(&table->list); i < n; i += 2) {
193
1.88M
        bstr *key_candidate = htp_list_get(&table->list, i);
194
1.88M
        if (bstr_cmp_nocase(key_candidate, key) == 0) {
195
628k
            void *element = htp_list_get(&table->list, i + 1);
196
628k
            return element;
197
628k
        }
198
1.88M
    }
199
200
355k
    return NULL;
201
984k
}
202
203
3.42M
void *htp_table_get_c(const htp_table_t *table, const char *ckey) {
204
3.42M
    if ((table == NULL)||(ckey == NULL)) return NULL;
205
206
    // Iterate through the list, comparing
207
    // keys with the parameter, return data if found.    
208
7.09M
    for (size_t i = 0, n = htp_list_size(&table->list); i < n; i += 2) {
209
3.80M
        bstr *key_candidate = htp_list_get(&table->list, i);
210
3.80M
        if (bstr_cmp_c_nocasenorzero(key_candidate, ckey) == 0) {
211
129k
            void *element = htp_list_get(&table->list, i + 1);
212
129k
            return element;
213
129k
        }
214
3.80M
    }
215
216
3.29M
    return NULL;
217
3.42M
}
218
219
507k
void *htp_table_get_index(const htp_table_t *table, size_t idx, bstr **key) {
220
507k
    if (table == NULL) return NULL;
221
    
222
507k
    if (idx >= htp_list_size(&table->list)) return NULL;
223
224
507k
    if (key != NULL) {
225
0
        *key = htp_list_get(&table->list, idx * 2);
226
0
    }
227
228
507k
    return htp_list_get(&table->list, (idx * 2) + 1);
229
507k
}
230
231
0
void *htp_table_get_mem(const htp_table_t *table, const void *key, size_t key_len) {
232
0
    if ((table == NULL)||(key == NULL)) return NULL;
233
234
    // Iterate through the list, comparing
235
    // keys with the parameter, return data if found.
236
0
    for (size_t i = 0, n = htp_list_size(&table->list); i < n; i += 2) {
237
0
        bstr *key_candidate = htp_list_get(&table->list, i);
238
0
        if (bstr_cmp_mem_nocase(key_candidate, key, key_len) == 0) {
239
0
            void *element = htp_list_get(&table->list, i + 1);
240
0
            return element;
241
0
        }
242
0
    }
243
244
0
    return NULL;
245
0
}
246
247
1.24M
size_t htp_table_size(const htp_table_t *table) {
248
1.24M
    if (table == NULL) return 0;
249
1.24M
    return htp_list_size(&table->list) / 2;
250
1.24M
}