From e26d407d5d5a77e167797faa69aae2429c380325 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 5 Dec 2013 12:27:03 +0100 Subject: [PATCH] value-pairs: Handle SDATA enterprise IDs correctly RFC5424 SDATA IDs are of the form "[win@18372.4 foo=bar]", which translates to "sdata.win@18372.4.foo=bar" internally. In this case, we should not split the "4" into a separate object, but treat it as part of the sdata ID. To do this, the name splitting was enhanced, and instead of splitting by every dot, it will look for @ too, and only split a token off after that, if a dot is followed by a non-number. A test case to verify the behaviour is also included. Signed-off-by: Tibor Benke Signed-off-by: Gergely Nagy --- lib/value-pairs.c | 51 +++++++++++++++++++++++++++++++++- modules/json/tests/test_json.c | 2 ++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/lib/value-pairs.c b/lib/value-pairs.c index 55997433a6b141..e889de2624204f 100644 --- a/lib/value-pairs.c +++ b/lib/value-pairs.c @@ -484,6 +484,55 @@ vp_walker_stack_push (vp_walk_stack_t **stack, return nt; } +static void +vp_walker_name_value_split_add_name_token(GPtrArray *array, const gchar *name, + int *current_name_start_idx, + int *index) +{ + gchar *token; + + token = g_strndup(name + *current_name_start_idx, *index - *current_name_start_idx); + *current_name_start_idx = ++(*index); + g_ptr_array_add(array, (gpointer) token); +} + +static gchar ** +vp_walker_name_value_split(const gchar *name) +{ + int i; + int current_name_start_idx = 0; + GPtrArray *array = g_ptr_array_new(); + gchar **tokens; + size_t name_len = strlen(name); + + for (i = 0; i < name_len; i++) + { + if (name[i] == '@') + { + i++; + while (g_ascii_isdigit(name[i]) || (name[i] == '.' && g_ascii_isdigit(name[i + 1]))) + i++; + } + if (name[i] == '.') + vp_walker_name_value_split_add_name_token(array, name, ¤t_name_start_idx, &i); + } + if (current_name_start_idx <= i - 1) + vp_walker_name_value_split_add_name_token(array, name, ¤t_name_start_idx, &i); + + if (array->len == 0) + return NULL; + + tokens = (gchar **) g_malloc ((array->len + 1) * sizeof(gchar *)); + + for (i = 0; i < array->len; i++) + tokens[i] = g_ptr_array_index(array, i); + tokens[array->len] = NULL; + + g_ptr_array_free(array, FALSE); + + return tokens; +} + static gchar * vp_walker_name_split(vp_walk_stack_t **stack, vp_walk_state_t *state, const gchar *name) @@ -491,7 +540,7 @@ vp_walker_name_split(vp_walk_stack_t **stack, vp_walk_state_t *state, gchar **tokens, *key = NULL; guint token_cnt, i, start; - tokens = g_strsplit(name, ".", 0); + tokens = vp_walker_name_value_split(name); token_cnt = g_strv_length(tokens); start = g_trash_stack_height((GTrashStack **)stack); diff --git a/modules/json/tests/test_json.c b/modules/json/tests/test_json.c index 1d27e980caa91c..fa2ce87cd6c87d 100644 --- a/modules/json/tests/test_json.c +++ b/modules/json/tests/test_json.c @@ -16,6 +16,8 @@ test_format_json(void) "{\"kernel\":{\"SUBSYSTEM\":\"pci\",\"DEVICE\":{\"type\":\"pci\",\"name\":\"0000:02:00.0\"}},\"MSGID\":\"801\",\"MESSAGE\":\"test\"}"); assert_template_format("$(format-json .foo=bar)", "{\"_foo\":\"bar\"}"); assert_template_format("$(format-json --scope rfc3164,rfc3164)", "{\"PROGRAM\":\"syslog-ng\",\"PRIORITY\":\"err\",\"PID\":\"23323\",\"MESSAGE\":\"árvíztűrőtükörfúrógép\",\"HOST\":\"bzorp\",\"FACILITY\":\"local3\",\"DATE\":\"Feb 11 18:58:35\"}"); + assert_template_format("$(format-json sdata.win@18372.4.fruit=\"pear\" sdata.win@18372.4.taste=\"good\")", + "{\"sdata\":{\"win@18372.4\":{\"taste\":\"good\",\"fruit\":\"pear\"}}}"); } void