[PATCH (3.4)] json-format: Unbreak $(format-json)
The $(format-json) template function was misbehaving under certain conditions, namely where we had a sub-object, a simple value, and another object starting right after: in this case, no comma was placed between the simple value and the name of the new sub-object. The fix changes how comma placement is done completely: it is no longer a mix of prefix_data & user_data magic, but all state is kept in the user data, with the _obj_start(), _obj_end() and _value() functions setting it as appropriate: - When starting a new object, if we need a comma, we'll put one, and turn the comma flag off (the first item within an object won't need a comma). - When ending an object, we never add a comma, but the next item will need the comma flag set. - When adding a value, if the comma flag is set, we add one, and in the end, set the flag ourselves, as the next one will need a comma too. This is much simpler than the previous hackery, and also results in correct JSON in every situation. Signed-off-by: Gergely Nagy <algernon@balabit.hu> --- modules/json/format-json.c | 27 +++++---------------------- modules/json/tests/test_json.c | 2 ++ 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/modules/json/format-json.c b/modules/json/format-json.c index 4f0f01c..e17bcb0 100644 --- a/modules/json/format-json.c +++ b/modules/json/format-json.c @@ -118,14 +118,8 @@ tf_json_obj_start(const gchar *name, gpointer user_data) { json_state_t *state = (json_state_t *)user_data; - gboolean need_comma = FALSE; - if (prefix_data) - need_comma = GPOINTER_TO_INT(*prefix_data); - else - need_comma = state->need_comma; - - if (need_comma) + if (state->need_comma) g_string_append_c(state->buffer, ','); if (name) @@ -133,13 +127,11 @@ tf_json_obj_start(const gchar *name, g_string_append_c(state->buffer, '"'); g_string_append_escaped(state->buffer, name); g_string_append(state->buffer, "\":{"); - state->need_comma = TRUE; } else g_string_append_c(state->buffer, '{'); - if (prefix_data) - *prefix_data=GINT_TO_POINTER(0); + state->need_comma = FALSE; return FALSE; } @@ -152,11 +144,10 @@ tf_json_obj_end(const gchar *name, { json_state_t *state = (json_state_t *)user_data; - if (prev_data) - *prev_data = GINT_TO_POINTER(1); - g_string_append_c(state->buffer, '}'); + state->need_comma = TRUE; + return FALSE; } @@ -164,18 +155,10 @@ static gboolean tf_json_value(const gchar *name, const gchar *prefix, const gchar *value, gpointer *prefix_data, gpointer user_data) { - gboolean need_comma = FALSE; json_state_t *state = (json_state_t *)user_data; - if (prefix_data) - need_comma = GPOINTER_TO_INT(*prefix_data); - else - need_comma = state->need_comma; - - if (need_comma) + if (state->need_comma) g_string_append_c(state->buffer, ','); - else if (prefix_data) - *prefix_data = GINT_TO_POINTER(1); g_string_append_c(state->buffer, '"'); g_string_append_escaped(state->buffer, name); diff --git a/modules/json/tests/test_json.c b/modules/json/tests/test_json.c index f188b7f..2a88c63 100644 --- a/modules/json/tests/test_json.c +++ b/modules/json/tests/test_json.c @@ -11,6 +11,8 @@ test_format_json(void) assert_template_format("$(format-json msg.text=$MSG msg.id=42 host=bzorp)", "{\"msg\":{\"text\":\"árvíztűrőtükörfúrógép\",\"id\":\"42\"},\"host\":\"bzorp\"}"); assert_template_format("$(format-json msg.text.str=$MSG msg.text.len=42 msg.id=42 host=bzorp)", "{\"msg\":{\"text\":{\"str\":\"árvíztűrőtükörfúrógép\",\"len\":\"42\"},\"id\":\"42\"},\"host\":\"bzorp\"}"); + assert_template_format("$(format-json kernel.SUBSYSTEM=pci kernel.DEVICE.type=pci kernel.DEVICE.name=0000:02:00.0 MSGID=801 MESSAGE=test)", + "{\"kernel\":{\"SUBSYSTEM\":\"pci\",\"DEVICE\":{\"type\":\"pci\",\"name\":\"0000:02:00.0\"}},\"MSGID\":\"801\",\"MESSAGE\":\"test\"}"); } int -- 1.7.10.4
participants (1)
-
Gergely Nagy