/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 | } |