/src/fluent-bit/src/record_accessor/flb_ra_parser.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* Fluent Bit |
4 | | * ========== |
5 | | * Copyright (C) 2015-2024 The Fluent Bit Authors |
6 | | * |
7 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
8 | | * you may not use this file except in compliance with the License. |
9 | | * You may obtain a copy of the License at |
10 | | * |
11 | | * http://www.apache.org/licenses/LICENSE-2.0 |
12 | | * |
13 | | * Unless required by applicable law or agreed to in writing, software |
14 | | * distributed under the License is distributed on an "AS IS" BASIS, |
15 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | | * See the License for the specific language governing permissions and |
17 | | * limitations under the License. |
18 | | */ |
19 | | |
20 | | #include <fluent-bit/flb_info.h> |
21 | | #include <fluent-bit/flb_slist.h> |
22 | | #include <fluent-bit/flb_mem.h> |
23 | | #include <fluent-bit/flb_sds.h> |
24 | | #include <fluent-bit/flb_log.h> |
25 | | #include <fluent-bit/record_accessor/flb_ra_parser.h> |
26 | | |
27 | | #include "ra_parser.h" |
28 | | #include "ra_lex.h" |
29 | | |
30 | | int flb_ra_parser_subkey_count(struct flb_ra_parser *rp) |
31 | 0 | { |
32 | 0 | if (rp == NULL || rp->key == NULL) { |
33 | 0 | return -1; |
34 | 0 | } |
35 | 0 | else if (rp->type != FLB_RA_PARSER_KEYMAP) { |
36 | 0 | return 0; |
37 | 0 | } |
38 | 0 | else if(rp->key->subkeys == NULL) { |
39 | 0 | return -1; |
40 | 0 | } |
41 | | |
42 | 0 | return mk_list_size(rp->key->subkeys); |
43 | 0 | } |
44 | | |
45 | | void flb_ra_parser_dump(struct flb_ra_parser *rp) |
46 | 334k | { |
47 | 334k | struct mk_list *head; |
48 | 334k | struct flb_ra_key *key; |
49 | 334k | struct flb_ra_subentry *entry; |
50 | | |
51 | 334k | key = rp->key; |
52 | 334k | if (rp->type == FLB_RA_PARSER_STRING) { |
53 | 166k | printf("type : STRING\n"); |
54 | 166k | printf("string : '%s'\n", key->name); |
55 | 166k | } |
56 | 334k | if (rp->type == FLB_RA_PARSER_REGEX_ID) { |
57 | 1.93k | printf("type : REGEX_ID\n"); |
58 | 1.93k | printf("integer : '%i'\n", rp->id); |
59 | 1.93k | } |
60 | 334k | if (rp->type == FLB_RA_PARSER_TAG) { |
61 | 302 | printf("type : TAG\n"); |
62 | 302 | } |
63 | 334k | if (rp->type == FLB_RA_PARSER_TAG_PART) { |
64 | 477 | printf("type : TAG[%i]\n", rp->id); |
65 | 477 | } |
66 | 334k | else if (rp->type == FLB_RA_PARSER_KEYMAP) { |
67 | 165k | printf("type : KEYMAP\n"); |
68 | 165k | if (rp->key) { |
69 | 164k | printf("key name : %s\n", key->name); |
70 | 164k | mk_list_foreach(head, key->subkeys) { |
71 | 41.9k | entry = mk_list_entry(head, struct flb_ra_subentry, _head); |
72 | 41.9k | if (entry->type == FLB_RA_PARSER_STRING) { |
73 | 5.36k | printf(" - subkey : %s\n", entry->str); |
74 | 5.36k | } |
75 | 36.5k | else if (entry->type == FLB_RA_PARSER_ARRAY_ID) { |
76 | 36.5k | printf(" - array id: %i\n", entry->array_id); |
77 | 36.5k | } |
78 | 41.9k | } |
79 | 164k | } |
80 | 165k | } |
81 | 334k | } |
82 | | |
83 | | static void ra_parser_subentry_destroy_all(struct mk_list *list) |
84 | 379k | { |
85 | 379k | struct mk_list *tmp; |
86 | 379k | struct mk_list *head; |
87 | 379k | struct flb_ra_subentry *entry; |
88 | | |
89 | 379k | mk_list_foreach_safe(head, tmp, list) { |
90 | 45.1k | entry = mk_list_entry(head, struct flb_ra_subentry, _head); |
91 | 45.1k | mk_list_del(&entry->_head); |
92 | 45.1k | if (entry->type == FLB_RA_PARSER_STRING) { |
93 | 6.54k | flb_sds_destroy(entry->str); |
94 | 6.54k | } |
95 | 45.1k | flb_free(entry); |
96 | 45.1k | } |
97 | 379k | } |
98 | | |
99 | | int flb_ra_parser_subentry_add_string(struct flb_ra_parser *rp, char *key) |
100 | 7.02k | { |
101 | 7.02k | struct flb_ra_subentry *entry; |
102 | | |
103 | 7.02k | entry = flb_malloc(sizeof(struct flb_ra_subentry)); |
104 | 7.02k | if (!entry) { |
105 | 215 | flb_errno(); |
106 | 215 | return -1; |
107 | 215 | } |
108 | | |
109 | 6.81k | entry->type = FLB_RA_PARSER_STRING; |
110 | 6.81k | entry->str = flb_sds_create(key); |
111 | 6.81k | if (!entry->str) { |
112 | 266 | flb_errno(); |
113 | 266 | flb_free(entry); |
114 | 266 | return -1; |
115 | 266 | } |
116 | 6.54k | mk_list_add(&entry->_head, rp->slist); |
117 | | |
118 | 6.54k | return 0; |
119 | 6.81k | } |
120 | | |
121 | | int flb_ra_parser_subentry_add_array_id(struct flb_ra_parser *rp, int id) |
122 | 38.8k | { |
123 | 38.8k | struct flb_ra_subentry *entry; |
124 | | |
125 | 38.8k | entry = flb_malloc(sizeof(struct flb_ra_subentry)); |
126 | 38.8k | if (!entry) { |
127 | 209 | flb_errno(); |
128 | 209 | return -1; |
129 | 209 | } |
130 | | |
131 | 38.6k | entry->type = FLB_RA_PARSER_ARRAY_ID; |
132 | 38.6k | entry->array_id = id; |
133 | 38.6k | mk_list_add(&entry->_head, rp->slist); |
134 | | |
135 | 38.6k | return 0; |
136 | 38.8k | } |
137 | | |
138 | | |
139 | | struct flb_ra_key *flb_ra_parser_key_add(struct flb_ra_parser *rp, char *key) |
140 | 186k | { |
141 | 186k | struct flb_ra_key *k; |
142 | | |
143 | 186k | k = flb_malloc(sizeof(struct flb_ra_key)); |
144 | 186k | if (!k) { |
145 | 231 | flb_errno(); |
146 | 231 | return NULL; |
147 | 231 | } |
148 | | |
149 | 185k | k->name = flb_sds_create(key); |
150 | 185k | if (!k->name) { |
151 | 834 | flb_errno(); |
152 | 834 | flb_free(k); |
153 | 834 | return NULL; |
154 | 834 | } |
155 | 184k | k->subkeys = NULL; |
156 | | |
157 | 184k | return k; |
158 | 185k | } |
159 | | |
160 | | struct flb_ra_array *flb_ra_parser_array_add(struct flb_ra_parser *rp, int index) |
161 | 0 | { |
162 | 0 | struct flb_ra_array *arr; |
163 | |
|
164 | 0 | if (index < 0) { |
165 | 0 | return NULL; |
166 | 0 | } |
167 | | |
168 | 0 | arr = flb_malloc(sizeof(struct flb_ra_array)); |
169 | 0 | if (!arr) { |
170 | 0 | flb_errno(); |
171 | 0 | return NULL; |
172 | 0 | } |
173 | | |
174 | 0 | arr->index = index; |
175 | 0 | arr->subkeys = NULL; |
176 | |
|
177 | 0 | return arr; |
178 | 0 | } |
179 | | |
180 | | struct flb_ra_key *flb_ra_parser_string_add(struct flb_ra_parser *rp, |
181 | | char *str, int len) |
182 | 0 | { |
183 | 0 | struct flb_ra_key *k; |
184 | |
|
185 | 0 | k = flb_malloc(sizeof(struct flb_ra_key)); |
186 | 0 | if (!k) { |
187 | 0 | flb_errno(); |
188 | 0 | return NULL; |
189 | 0 | } |
190 | | |
191 | 0 | k->name = flb_sds_create_len(str, len); |
192 | 0 | if (!k->name) { |
193 | 0 | flb_errno(); |
194 | 0 | flb_free(k); |
195 | 0 | return NULL; |
196 | 0 | } |
197 | 0 | k->subkeys = NULL; |
198 | |
|
199 | 0 | return k; |
200 | 0 | } |
201 | | |
202 | | static struct flb_ra_parser *flb_ra_parser_create() |
203 | 379k | { |
204 | 379k | struct flb_ra_parser *rp; |
205 | | |
206 | 379k | rp = flb_calloc(1, sizeof(struct flb_ra_parser)); |
207 | 379k | if (!rp) { |
208 | 2 | flb_errno(); |
209 | 2 | return NULL; |
210 | 2 | } |
211 | 379k | rp->type = -1; |
212 | 379k | rp->key = NULL; |
213 | 379k | rp->slist = flb_malloc(sizeof(struct mk_list)); |
214 | 379k | if (!rp->slist) { |
215 | 4 | flb_errno(); |
216 | 4 | flb_free(rp); |
217 | 4 | return NULL; |
218 | 4 | } |
219 | 379k | mk_list_init(rp->slist); |
220 | | |
221 | 379k | return rp; |
222 | 379k | } |
223 | | |
224 | | struct flb_ra_parser *flb_ra_parser_string_create(char *str, int len) |
225 | 188k | { |
226 | 188k | struct flb_ra_parser *rp; |
227 | | |
228 | 188k | rp = flb_ra_parser_create(); |
229 | 188k | if (!rp) { |
230 | 1 | flb_error("[record accessor] could not create string context"); |
231 | 1 | return NULL; |
232 | 1 | } |
233 | | |
234 | 188k | rp->type = FLB_RA_PARSER_STRING; |
235 | 188k | rp->key = flb_malloc(sizeof(struct flb_ra_key)); |
236 | 188k | if (!rp->key) { |
237 | 2 | flb_errno(); |
238 | 2 | flb_ra_parser_destroy(rp); |
239 | 2 | return NULL; |
240 | 2 | } |
241 | 188k | rp->key->subkeys = NULL; |
242 | 188k | rp->key->name = flb_sds_create_len(str, len); |
243 | 188k | if (!rp->key->name) { |
244 | 2 | flb_ra_parser_destroy(rp); |
245 | 2 | return NULL; |
246 | 2 | } |
247 | | |
248 | 188k | return rp; |
249 | 188k | } |
250 | | |
251 | | struct flb_ra_parser *flb_ra_parser_regex_id_create(int id) |
252 | 2.41k | { |
253 | 2.41k | struct flb_ra_parser *rp; |
254 | | |
255 | 2.41k | rp = flb_ra_parser_create(); |
256 | 2.41k | if (!rp) { |
257 | 1 | flb_error("[record accessor] could not create string context"); |
258 | 1 | return NULL; |
259 | 1 | } |
260 | | |
261 | 2.41k | rp->type = FLB_RA_PARSER_REGEX_ID; |
262 | 2.41k | rp->id = id; |
263 | 2.41k | return rp; |
264 | 2.41k | } |
265 | | |
266 | | struct flb_ra_parser *flb_ra_parser_tag_create() |
267 | 684 | { |
268 | 684 | struct flb_ra_parser *rp; |
269 | | |
270 | 684 | rp = flb_ra_parser_create(); |
271 | 684 | if (!rp) { |
272 | 1 | flb_error("[record accessor] could not create tag context"); |
273 | 1 | return NULL; |
274 | 1 | } |
275 | | |
276 | 683 | rp->type = FLB_RA_PARSER_TAG; |
277 | 683 | return rp; |
278 | 684 | } |
279 | | |
280 | | struct flb_ra_parser *flb_ra_parser_tag_part_create(int id) |
281 | 1.06k | { |
282 | 1.06k | struct flb_ra_parser *rp; |
283 | | |
284 | 1.06k | rp = flb_ra_parser_create(); |
285 | 1.06k | if (!rp) { |
286 | 2 | flb_error("[record accessor] could not create tag context"); |
287 | 2 | return NULL; |
288 | 2 | } |
289 | | |
290 | 1.06k | rp->type = FLB_RA_PARSER_TAG_PART; |
291 | 1.06k | rp->id = id; |
292 | | |
293 | 1.06k | return rp; |
294 | 1.06k | } |
295 | | |
296 | | struct flb_ra_parser *flb_ra_parser_meta_create(char *str, int len) |
297 | 186k | { |
298 | 186k | int ret; |
299 | 186k | yyscan_t scanner; |
300 | 186k | YY_BUFFER_STATE buf; |
301 | 186k | flb_sds_t s; |
302 | 186k | struct flb_ra_parser *rp; |
303 | 186k | struct flb_ra_key *key; |
304 | | |
305 | 186k | rp = flb_ra_parser_create(); |
306 | 186k | if (!rp) { |
307 | 1 | flb_error("[record accessor] could not create meta context"); |
308 | 1 | return NULL; |
309 | 1 | } |
310 | | |
311 | | /* Temporal buffer of string with fixed length */ |
312 | 186k | s = flb_sds_create_len(str, len); |
313 | 186k | if (!s) { |
314 | 2 | flb_errno(); |
315 | 2 | flb_ra_parser_destroy(rp); |
316 | 2 | return NULL; |
317 | 2 | } |
318 | | |
319 | | /* Flex/Bison work */ |
320 | 186k | flb_ra_lex_init(&scanner); |
321 | 186k | buf = flb_ra__scan_string(s, scanner); |
322 | | |
323 | 186k | ret = flb_ra_parse(rp, s, scanner); |
324 | | |
325 | | /* release resources */ |
326 | 186k | flb_sds_destroy(s); |
327 | 186k | flb_ra__delete_buffer(buf, scanner); |
328 | 186k | flb_ra_lex_destroy(scanner); |
329 | | |
330 | | /* Finish structure mapping */ |
331 | 186k | if (rp->type == FLB_RA_PARSER_KEYMAP) { |
332 | 186k | if (rp->key) { |
333 | 184k | key = rp->key; |
334 | 184k | key->subkeys = rp->slist; |
335 | 184k | rp->slist = NULL; |
336 | 184k | } |
337 | 186k | } |
338 | | |
339 | 186k | if (ret != 0) { |
340 | 233 | flb_ra_parser_destroy(rp); |
341 | 233 | return NULL; |
342 | 233 | } |
343 | | |
344 | 185k | return rp; |
345 | 186k | } |
346 | | |
347 | | void flb_ra_parser_destroy(struct flb_ra_parser *rp) |
348 | 379k | { |
349 | 379k | struct flb_ra_key *key; |
350 | | |
351 | 379k | key = rp->key; |
352 | 379k | if (key) { |
353 | 373k | flb_sds_destroy(key->name); |
354 | 373k | if (key->subkeys) { |
355 | 184k | ra_parser_subentry_destroy_all(key->subkeys); |
356 | 184k | flb_free(key->subkeys); |
357 | 184k | } |
358 | 373k | flb_free(rp->key); |
359 | 373k | } |
360 | 379k | if (rp->slist) { |
361 | 194k | ra_parser_subentry_destroy_all(rp->slist); |
362 | 194k | flb_free(rp->slist); |
363 | 194k | } |
364 | 379k | flb_free(rp); |
365 | 379k | } |