diff --git a/src/pdag.c b/src/pdag.c index 44a3847b..3bb06cec 100644 --- a/src/pdag.c +++ b/src/pdag.c @@ -1318,6 +1318,34 @@ addUnparsedField(const char *str, const size_t strLen, const size_t offs, struct } +/** + * Add key:value pair to json tree + * If the key contains !, it will be added as nested + * Ex : a!b=abcd will be "a":{"b":"abcd"} + */ +static void +add_json_nested_key_value_pair(struct json_object *json, + char *name, + struct json_object *value) +{ + char *first = NULL; + // If the key contains an exclamation char + if( (first=strchr(name, '!')) != NULL ) { + // Prevent allocation + copy str + *first = '\0'; + struct json_object *subtree; + subtree = json_object_new_object(); + add_json_nested_key_value_pair(subtree, first+1, value); + json_object_object_add(json, name, subtree); + // Re-set the modified char above + *first = '!'; + } else { + json_object_object_add_ex(json, name, value, + JSON_C_OBJECT_ADD_KEY_IS_NEW|JSON_C_OBJECT_KEY_IS_CONSTANT); + } +} + + /* Do some fixup to the json that we cannot do on a lower layer */ static int fixJSON(struct ln_pdag *dag, @@ -1381,9 +1409,11 @@ fixJSON(struct ln_pdag *dag, json_object_put(*value); json_object_object_add_ex(json, prs->name, valDotDot, JSON_C_OBJECT_ADD_KEY_IS_NEW|JSON_C_OBJECT_KEY_IS_CONSTANT); + } else if(dag->ctx->version == 3) { + add_json_nested_key_value_pair(json, (char *)prs->name, *value); } else { json_object_object_add_ex(json, prs->name, *value, - JSON_C_OBJECT_ADD_KEY_IS_NEW|JSON_C_OBJECT_KEY_IS_CONSTANT); + JSON_C_OBJECT_ADD_KEY_IS_NEW|JSON_C_OBJECT_KEY_IS_CONSTANT); } } r = 0; diff --git a/src/samp.c b/src/samp.c index d5d42c3d..1d5c1c07 100644 --- a/src/samp.c +++ b/src/samp.c @@ -1062,6 +1062,8 @@ checkVersion(FILE *const fp) return -1; if(!strcmp(buf, "version=2\n")) { return 2; + } else if(!strcmp(buf, "version=3\n")) { + return 3; } else { return 1; } @@ -1154,7 +1156,7 @@ ln_sampLoad(ln_ctx ctx, const char *file) } /* now we are in our native code */ - ++ctx->conf_ln_nbr; /* "version=2" is line 1! */ + ++ctx->conf_ln_nbr; /* "version=2" or "version=3" is line 1! */ while(!isEof) { CHKR(ln_sampRead(ctx, repo, NULL, &isEof)); } @@ -1178,7 +1180,7 @@ ln_sampLoadFromString(ln_ctx ctx, const char *string) goto done; ln_dbgprintf(ctx, "loading v2 rulebase from string '%s'", string); - ctx->version = 2; + ctx->version = 3; while(!isEof) { CHKR(ln_sampRead(ctx, NULL, &string, &isEof)); } diff --git a/tests/field_v3_nested.sh b/tests/field_v3_nested.sh new file mode 100755 index 00000000..0dcafc1e --- /dev/null +++ b/tests/field_v3_nested.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# added 2023-09-25 by KGuillemot +# This file is part of the liblognorm project, released under ASL 2.0 +. $srcdir/exec.sh +no_solaris10 + +test_def $0 "v3 name-value-list parser" + +add_rule 'version=3' +add_rule 'rule=:<%syslog!priority:number%>%received!time:date-rfc3164% %host!name:word% %log!data:name-value-list%' + +execute '<15>Feb 10 08:30:07 hostname a=b c=d y=z' +assert_output_json_eq '{ "log": { "data": { "a": "b", "c": "d", "y": "z" } }, "host": { "name": "hostname" }, "received": { "time": "Feb 10 08:30:07" }, "syslog": { "priority": "15" } }' + +cleanup_tmp_files +