Coverage Report

Created: 2025-11-24 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/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
74.5k
static htp_status_t _htp_table_add(htp_table_t *table, const bstr *key, const void *element) {
44
    // Add key.
45
74.5k
    if (htp_list_add(&table->list, (void *)key) != HTP_OK) return HTP_ERROR;
46
47
    // Add element.
48
74.5k
    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
74.5k
    return HTP_OK;
54
74.5k
}
55
56
74.5k
htp_status_t htp_table_add(htp_table_t *table, const bstr *key, const void *element) {
57
74.5k
    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
74.5k
    if (table->alloc_type == HTP_TABLE_KEYS_ALLOC_UKNOWN) {
62
40.7k
        table->alloc_type = HTP_TABLE_KEYS_COPIED;
63
40.7k
    } else {
64
33.7k
        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
33.7k
    }
73
74
74.5k
    bstr *dupkey = bstr_dup(key);
75
74.5k
    if (dupkey == NULL) return HTP_ERROR;
76
77
74.5k
    if (_htp_table_add(table, dupkey, element) != HTP_OK) {
78
0
        bstr_free(dupkey);
79
0
        return HTP_ERROR;
80
0
    }
81
82
74.5k
    return HTP_OK;
83
74.5k
}
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
391k
void htp_table_clear(htp_table_t *table) {
128
391k
    if (table == NULL) return;
129
130
    // Free the table keys, but only if we're managing them.
131
391k
    if ((table->alloc_type == HTP_TABLE_KEYS_COPIED)||(table->alloc_type == HTP_TABLE_KEYS_ADOPTED)) {
132
172k
        bstr *key = NULL;
133
247k
        for (size_t i = 0, n = htp_list_size(&table->list); i < n; i += 2) {
134
74.5k
            key = htp_list_get(&table->list, i);
135
74.5k
            bstr_free(key);
136
74.5k
        }
137
172k
    }
138
139
391k
    htp_list_clear(&table->list);
140
391k
}
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
258k
htp_table_t *htp_table_create(size_t size) {
151
258k
    if (size == 0) return NULL;
152
153
258k
    htp_table_t *table = calloc(1, sizeof (htp_table_t));
154
258k
    if (table == NULL) return NULL;
155
156
258k
    table->alloc_type = HTP_TABLE_KEYS_ALLOC_UKNOWN;
157
158
    // Use a list behind the scenes.
159
258k
    if (htp_list_init(&table->list, size * 2) == HTP_ERROR) {
160
0
        free(table);
161
0
        return NULL;
162
0
    }
163
164
258k
    return table;
165
258k
}
166
167
258k
void htp_table_destroy(htp_table_t *table) {
168
258k
    if (table == NULL) return;
169
170
258k
    htp_table_clear(table);
171
172
258k
    htp_list_array_release(&table->list);
173
174
258k
    free(table);
175
258k
}
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
345k
void *htp_table_get(const htp_table_t *table, const bstr *key) {
188
345k
    if ((table == NULL)||(key == NULL)) return NULL;
189
190
    // Iterate through the list, comparing
191
    // keys with the parameter, return data if found.    
192
630k
    for (size_t i = 0, n = htp_list_size(&table->list); i < n; i += 2) {
193
555k
        bstr *key_candidate = htp_list_get(&table->list, i);
194
555k
        if (bstr_cmp_nocase(key_candidate, key) == 0) {
195
271k
            void *element = htp_list_get(&table->list, i + 1);
196
271k
            return element;
197
271k
        }
198
555k
    }
199
200
74.5k
    return NULL;
201
345k
}
202
203
656k
void *htp_table_get_c(const htp_table_t *table, const char *ckey) {
204
656k
    if ((table == NULL)||(ckey == NULL)) return NULL;
205
206
    // Iterate through the list, comparing
207
    // keys with the parameter, return data if found.    
208
890k
    for (size_t i = 0, n = htp_list_size(&table->list); i < n; i += 2) {
209
262k
        bstr *key_candidate = htp_list_get(&table->list, i);
210
262k
        if (bstr_cmp_c_nocasenorzero(key_candidate, ckey) == 0) {
211
28.0k
            void *element = htp_list_get(&table->list, i + 1);
212
28.0k
            return element;
213
28.0k
        }
214
262k
    }
215
216
628k
    return NULL;
217
656k
}
218
219
74.5k
void *htp_table_get_index(const htp_table_t *table, size_t idx, bstr **key) {
220
74.5k
    if (table == NULL) return NULL;
221
    
222
74.5k
    if (idx >= htp_list_size(&table->list)) return NULL;
223
224
74.5k
    if (key != NULL) {
225
0
        *key = htp_list_get(&table->list, idx * 2);
226
0
    }
227
228
74.5k
    return htp_list_get(&table->list, (idx * 2) + 1);
229
74.5k
}
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
466k
size_t htp_table_size(const htp_table_t *table) {
248
466k
    if (table == NULL) return 0;
249
466k
    return htp_list_size(&table->list) / 2;
250
466k
}