Coverage Report

Created: 2026-01-16 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/libhtp/htp/htp_table.c
Line
Count
Source
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
414k
static htp_status_t _htp_table_add(htp_table_t *table, const bstr *key, const void *element) {
44
    // Add key.
45
414k
    if (htp_list_add(&table->list, (void *)key) != HTP_OK) return HTP_ERROR;
46
47
    // Add element.
48
414k
    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
414k
    return HTP_OK;
54
414k
}
55
56
414k
htp_status_t htp_table_add(htp_table_t *table, const bstr *key, const void *element) {
57
414k
    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
414k
    if (table->alloc_type == HTP_TABLE_KEYS_ALLOC_UKNOWN) {
62
149k
        table->alloc_type = HTP_TABLE_KEYS_COPIED;
63
264k
    } else {
64
264k
        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
264k
    }
73
74
414k
    bstr *dupkey = bstr_dup(key);
75
414k
    if (dupkey == NULL) return HTP_ERROR;
76
77
414k
    if (_htp_table_add(table, dupkey, element) != HTP_OK) {
78
0
        bstr_free(dupkey);
79
0
        return HTP_ERROR;
80
0
    }
81
82
414k
    return HTP_OK;
83
414k
}
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
750k
void htp_table_clear(htp_table_t *table) {
128
750k
    if (table == NULL) return;
129
130
    // Free the table keys, but only if we're managing them.
131
750k
    if ((table->alloc_type == HTP_TABLE_KEYS_COPIED)||(table->alloc_type == HTP_TABLE_KEYS_ADOPTED)) {
132
150k
        bstr *key = NULL;
133
565k
        for (size_t i = 0, n = htp_list_size(&table->list); i < n; i += 2) {
134
414k
            key = htp_list_get(&table->list, i);
135
414k
            bstr_free(key);
136
414k
        }
137
150k
    }
138
139
750k
    htp_list_clear(&table->list);
140
750k
}
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
747k
htp_table_t *htp_table_create(size_t size) {
151
747k
    if (size == 0) return NULL;
152
153
747k
    htp_table_t *table = calloc(1, sizeof (htp_table_t));
154
747k
    if (table == NULL) return NULL;
155
156
747k
    table->alloc_type = HTP_TABLE_KEYS_ALLOC_UKNOWN;
157
158
    // Use a list behind the scenes.
159
747k
    if (htp_list_init(&table->list, size * 2) == HTP_ERROR) {
160
0
        free(table);
161
0
        return NULL;
162
0
    }
163
164
747k
    return table;
165
747k
}
166
167
747k
void htp_table_destroy(htp_table_t *table) {
168
747k
    if (table == NULL) return;
169
170
747k
    htp_table_clear(table);
171
172
747k
    htp_list_array_release(&table->list);
173
174
747k
    free(table);
175
747k
}
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
1.02M
void *htp_table_get(const htp_table_t *table, const bstr *key) {
188
1.02M
    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.61M
    for (size_t i = 0, n = htp_list_size(&table->list); i < n; i += 2) {
193
2.20M
        bstr *key_candidate = htp_list_get(&table->list, i);
194
2.20M
        if (bstr_cmp_nocase(key_candidate, key) == 0) {
195
608k
            void *element = htp_list_get(&table->list, i + 1);
196
608k
            return element;
197
608k
        }
198
2.20M
    }
199
200
414k
    return NULL;
201
1.02M
}
202
203
3.23M
void *htp_table_get_c(const htp_table_t *table, const char *ckey) {
204
3.23M
    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.55M
    for (size_t i = 0, n = htp_list_size(&table->list); i < n; i += 2) {
209
4.48M
        bstr *key_candidate = htp_list_get(&table->list, i);
210
4.48M
        if (bstr_cmp_c_nocasenorzero(key_candidate, ckey) == 0) {
211
160k
            void *element = htp_list_get(&table->list, i + 1);
212
160k
            return element;
213
160k
        }
214
4.48M
    }
215
216
3.07M
    return NULL;
217
3.23M
}
218
219
638k
void *htp_table_get_index(const htp_table_t *table, size_t idx, bstr **key) {
220
638k
    if (table == NULL) return NULL;
221
    
222
638k
    if (idx >= htp_list_size(&table->list)) return NULL;
223
224
638k
    if (key != NULL) {
225
0
        *key = htp_list_get(&table->list, idx * 2);
226
0
    }
227
228
638k
    return htp_list_get(&table->list, (idx * 2) + 1);
229
638k
}
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.32M
size_t htp_table_size(const htp_table_t *table) {
248
1.32M
    if (table == NULL) return 0;
249
1.32M
    return htp_list_size(&table->list) / 2;
250
1.32M
}