1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* Fluent Bit 4 * ========== 5 * Copyright (C) 2019-2021 The Fluent Bit Authors 6 * Copyright (C) 2015-2018 Treasure Data Inc. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 #include <fluent-bit/flb_info.h> 22 #include <fluent-bit/flb_log.h> 23 #include <fluent-bit/flb_sds.h> 24 #include <fluent-bit/flb_mem.h> 25 #include <fluent-bit/flb_regex.h> 26 #include <fluent-bit/flb_ra_key.h> 27 #include <fluent-bit/record_accessor/flb_ra_parser.h> 28 #include <msgpack.h> 29 #include <limits.h> 30 31 /* Map msgpack object into flb_ra_value representation */ 32 static int msgpack_object_to_ra_value(msgpack_object o, 33 struct flb_ra_value *result) 34 { 35 result->o = o; 36 37 /* Compose result with found value */ 38 if (o.type == MSGPACK_OBJECT_BOOLEAN) { 39 result->type = FLB_RA_BOOL; 40 result->val.boolean = o.via.boolean; 41 return 0; 42 } 43 else if (o.type == MSGPACK_OBJECT_POSITIVE_INTEGER || 44 o.type == MSGPACK_OBJECT_NEGATIVE_INTEGER) { 45 result->type = FLB_RA_INT; 46 result->val.i64 = o.via.i64; 47 return 0; 48 } 49 else if (o.type == MSGPACK_OBJECT_FLOAT32 || 50 o.type == MSGPACK_OBJECT_FLOAT) { 51 result->type = FLB_RA_FLOAT; 52 result->val.f64 = o.via.f64; 53 return 0; 54 } 55 else if (o.type == MSGPACK_OBJECT_STR) { 56 result->type = FLB_RA_STRING; 57 result->val.string = flb_sds_create_len((char *) o.via.str.ptr, 58 o.via.str.size); 59 return 0; 60 } 61 else if (o.type == MSGPACK_OBJECT_MAP) { 62 /* return boolean 'true', just denoting the existence of the key */ ms_sleep(unsigned int ms)63 result->type = FLB_RA_BOOL; 64 result->val.boolean = true; 65 return 0; 66 } 67 else if (o.type == MSGPACK_OBJECT_NIL) { 68 result->type = FLB_RA_NULL; 69 return 0; 70 } 71 str_dup(const char * s)72 return -1; 73 } 74 75 /* Return the entry position of key/val in the map */ 76 static int ra_key_val_id(flb_sds_t ckey, msgpack_object map) 77 { 78 int i; 79 int map_size; 80 msgpack_object key; 81 82 if (map.type != MSGPACK_OBJECT_MAP) { 83 return -1; strn_dup(const char * s,size_t n)84 } 85 86 map_size = map.via.map.size; 87 for (i = 0; i < map_size; i++) { 88 key = map.via.map.ptr[i].key; 89 90 if (key.type != MSGPACK_OBJECT_STR) { 91 continue; 92 } 93 94 /* Compare by length and by key name */ 95 if (flb_sds_cmp(ckey, key.via.str.ptr, key.via.str.size) != 0) { 96 continue; 97 } mem_alloc(size_t amount)98 99 return i; 100 } 101 102 return -1; 103 } 104 105 static int msgpack_object_strcmp(msgpack_object o, char *str, int len) 106 { 107 if (o.type != MSGPACK_OBJECT_STR) { 108 return -1; 109 } mem_calloc(size_t nmemb,size_t size)110 111 if (o.via.str.size != len) { 112 return -1; 113 } 114 115 return strncmp(o.via.str.ptr, str, len); 116 } 117 118 /* Lookup perfect match of sub-keys and map content */ 119 static int subkey_to_object(msgpack_object *map, struct mk_list *subkeys, 120 msgpack_object **out_key, msgpack_object **out_val) 121 { mem_realloc(void * orig,size_t amount)122 int i = 0; 123 int levels; 124 int matched = 0; 125 msgpack_object *found = NULL; 126 msgpack_object *key = NULL; 127 msgpack_object *val = NULL; 128 msgpack_object cur; 129 struct mk_list *head; 130 struct flb_ra_subentry *entry; 131 132 /* Expected number of map levels in the map */ 133 levels = mk_list_size(subkeys); 134 135 cur = *map; 136 137 mk_list_foreach(head, subkeys) { 138 /* expected entry */ 139 entry = mk_list_entry(head, struct flb_ra_subentry, _head); 140 dB(float amplitude)141 /* Array Handling */ 142 if (entry->type == FLB_RA_PARSER_ARRAY_ID) { 143 /* check the current msgpack object is an array */ 144 if (cur.type != MSGPACK_OBJECT_ARRAY) { 145 return -1; 146 } 147 148 /* Index limit and ensure no overflow */ 149 if (entry->array_id == INT_MAX || 150 cur.via.array.size < entry->array_id + 1) { 151 return -1; 152 } 153 154 cur = cur.via.array.ptr[entry->array_id]; 155 goto next; 156 } 157 158 if (cur.type != MSGPACK_OBJECT_MAP) { 159 break; dB2_power(float db)160 } 161 162 i = ra_key_val_id(entry->str, cur); 163 if (i == -1) { 164 found = NULL; 165 continue; 166 } 167 168 key = &cur.via.map.ptr[i].key; dB_s(int noisefloor,float amplitude,float correction_dBs)169 val = &cur.via.map.ptr[i].val; 170 171 /* A bit obvious, but it's better to validate data type */ 172 if (key->type != MSGPACK_OBJECT_STR) { 173 found = NULL; 174 continue; 175 } 176 177 found = key; 178 cur = cur.via.map.ptr[i].val; 179 dB2_amp_s(int noisefloor,int db,float correction_dBs)180 next: 181 matched++; 182 183 if (levels == matched) { 184 break; 185 } 186 } 187 188 /* No matches */ pdB_s(int noisefloor,float power,float correction_dBs)189 if (!found || (matched > 0 && levels != matched)) { 190 return -1; 191 } 192 193 *out_key = (msgpack_object *) key; 194 *out_val = (msgpack_object *) val; 195 196 return 0; 197 } 198 199 struct flb_ra_value *flb_ra_key_to_value(flb_sds_t ckey, dB2_power_s(int noisefloor,int db,float correction_dBs)200 msgpack_object map, 201 struct mk_list *subkeys) 202 { 203 int i; 204 int ret; 205 msgpack_object val; 206 msgpack_object *out_key; 207 msgpack_object *out_val; 208 struct flb_ra_value *result; 209 210 /* Get the key position in the map */ 211 i = ra_key_val_id(ckey, map); 212 if (i == -1) { 213 return NULL; 214 } 215 216 /* Reference entries */ 217 val = map.via.map.ptr[i].val; 218 219 /* Create the result context */ 220 result = flb_calloc(1, sizeof(struct flb_ra_value)); 221 if (!result) { 222 flb_errno(); 223 return NULL; 224 } 225 result->o = val; 226 227 if ((val.type == MSGPACK_OBJECT_MAP || val.type == MSGPACK_OBJECT_ARRAY) 228 && subkeys != NULL) { 229 230 ret = subkey_to_object(&val, subkeys, &out_key, &out_val); 231 if (ret == 0) { 232 ret = msgpack_object_to_ra_value(*out_val, result); 233 if (ret == -1) { 234 flb_free(result); 235 return NULL; 236 } 237 return result; 238 } 239 else { 240 flb_free(result); 241 return NULL; 242 } 243 } 244 else { 245 ret = msgpack_object_to_ra_value(val, result); 246 if (ret == -1) { 247 flb_error("[ra key] cannot process key value"); 248 flb_free(result); 249 return NULL; 250 } 251 } 252 253 return result; 254 } 255 256 int flb_ra_key_value_get(flb_sds_t ckey, msgpack_object map, 257 struct mk_list *subkeys, 258 msgpack_object **start_key, 259 msgpack_object **out_key, msgpack_object **out_val) 260 { 261 int i; 262 int ret; 263 msgpack_object val; 264 msgpack_object *o_key; 265 msgpack_object *o_val; 266 267 /* Get the key position in the map */ numtostr_signed(int digits,int n,char * buf)268 i = ra_key_val_id(ckey, map); 269 if (i == -1) { 270 return -1; 271 } 272 273 /* Reference entries */ 274 *start_key = &map.via.map.ptr[i].key; 275 val = map.via.map.ptr[i].val; 276 277 if ((val.type == MSGPACK_OBJECT_MAP || val.type == MSGPACK_OBJECT_ARRAY) 278 && subkeys != NULL) { 279 ret = subkey_to_object(&val, subkeys, &o_key, &o_val); 280 if (ret == 0) { 281 *out_key = o_key; 282 *out_val = o_val; 283 return 0; 284 } 285 } 286 else { 287 *out_key = &map.via.map.ptr[i].key; 288 *out_val = &map.via.map.ptr[i].val; 289 return 0; get_basename(const char * filename)290 } 291 292 return -1; 293 } 294 295 int flb_ra_key_strcmp(flb_sds_t ckey, msgpack_object map, 296 struct mk_list *subkeys, char *str, int len) 297 { 298 int i; 299 int ret; 300 msgpack_object val; 301 msgpack_object *out_key; 302 msgpack_object *out_val; 303 304 /* Get the key position in the map */ get_extension(const char * filename)305 i = ra_key_val_id(ckey, map); 306 if (i == -1) { 307 return -1; 308 } 309 310 /* Reference map value */ 311 val = map.via.map.ptr[i].val; 312 313 if ((val.type == MSGPACK_OBJECT_MAP || val.type == MSGPACK_OBJECT_ARRAY) 314 && subkeys != NULL) { 315 ret = subkey_to_object(&val, subkeys, &out_key, &out_val); 316 if (ret == 0) { 317 return msgpack_object_strcmp(*out_val, str, len); get_parent_directory(const char * dirname)318 } 319 else { 320 return -1; 321 } 322 } 323 324 return msgpack_object_strcmp(val, str, len); 325 } 326 327 int flb_ra_key_regex_match(flb_sds_t ckey, msgpack_object map, 328 struct mk_list *subkeys, struct flb_regex *regex, 329 struct flb_regex_search *result) 330 { 331 int i; 332 int ret; 333 msgpack_object val; 334 msgpack_object *out_key; 335 msgpack_object *out_val; 336 337 /* Get the key position in the map */ 338 i = ra_key_val_id(ckey, map); 339 if (i == -1) { 340 return -1; 341 } 342 ltrim_string(char * s)343 /* Reference map value */ 344 val = map.via.map.ptr[i].val; 345 346 if ((val.type == MSGPACK_OBJECT_MAP || val.type == MSGPACK_OBJECT_ARRAY) 347 && subkeys != NULL) { 348 ret = subkey_to_object(&val, subkeys, &out_key, &out_val); 349 if (ret == 0) { 350 if (out_val->type != MSGPACK_OBJECT_STR) { 351 return -1; 352 } rtrim_string(char * s)353 354 if (result) { 355 /* Regex + capture mode */ 356 return flb_regex_do(regex, 357 (char *) out_val->via.str.ptr, 358 out_val->via.str.size, 359 result); 360 } 361 else { 362 /* No capture */ 363 return flb_regex_match(regex, trim_string(char * s)364 (unsigned char *) out_val->via.str.ptr, 365 out_val->via.str.size); 366 } 367 } 368 return -1; 369 } 370 371 if (val.type != MSGPACK_OBJECT_STR) { 372 return -1; 373 } str_break(const char * s,char c,char ** first,char ** second)374 375 if (result) { 376 /* Regex + capture mode */ 377 return flb_regex_do(regex, (char *) val.via.str.ptr, val.via.str.size, 378 result); 379 } 380 else { 381 /* No capture */ 382 return flb_regex_match(regex, (unsigned char *) val.via.str.ptr, 383 val.via.str.size); 384 } 385 386 return -1; 387 } str_escape(const char * s,int space)388 389 void flb_ra_key_value_destroy(struct flb_ra_value *v) 390 { 391 if (v->type == FLB_RA_STRING) { 392 flb_sds_destroy(v->val.string); 393 } 394 flb_free(v); 395 } 396