[syslog-ng] [PATCH (3.4)] json-format: Unbreak $(format-json)

Gergely Nagy algernon at balabit.hu
Sat Oct 13 19:05:14 CEST 2012


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 at 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




More information about the syslog-ng mailing list