diff options
author | Emmanuel Touzery <etouzery@gmail.com> | 2021-05-15 13:35:01 +0000 |
---|---|---|
committer | AndersBroman <a.broman58@gmail.com> | 2021-05-15 13:35:01 +0000 |
commit | 467f13f16c480307aab777b5ca7808f9f45dabf6 (patch) | |
tree | 20705d813b3dd772878760fbb55015c8743254b5 /epan/print.c | |
parent | fb41f052bb3054edac5853595178e58adfdd4171 (diff) |
fix #17369 tshark json now handles mixed children
Diffstat (limited to 'epan/print.c')
-rw-r--r-- | epan/print.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/epan/print.c b/epan/print.c index 7af041f7e9..8a51f271c0 100644 --- a/epan/print.c +++ b/epan/print.c @@ -112,6 +112,7 @@ static void write_json_proto_node_value_list(GSList *node_values_head, write_json_data *data); static void write_json_proto_node_filtered(proto_node *node, write_json_data *data); static void write_json_proto_node_hex_dump(proto_node *node, write_json_data *data); +static void write_json_proto_node_dynamic(proto_node *node, write_json_data *data); static void write_json_proto_node_children(proto_node *node, write_json_data *data); static void write_json_proto_node_value(proto_node *node, write_json_data *data); static void write_json_proto_node_no_value(proto_node *node, write_json_data *data); @@ -765,6 +766,23 @@ write_json_proto_tree(output_fields_t* fields, } /** + * Returns a boolean telling us whether that node list contains any node which has children + */ +static gboolean +any_has_children(GSList *node_values_list) +{ + GSList *current_node = node_values_list; + while (current_node != NULL) { + proto_node *current_value = (proto_node *) current_node->data; + if (current_value->first_child != NULL) { + return TRUE; + } + current_node = current_node->next; + } + return FALSE; +} + +/** * Write a json object containing a list of key:value pairs where each key:value pair corresponds to a different json * key and its associated nodes in the proto_tree. * @param proto_node_list_head A 2-dimensional list containing a list of values for each different node json key. The @@ -792,11 +810,11 @@ write_json_proto_node_list(GSList *proto_node_list_head, write_json_data *pdata) field_info *fi = first_value->finfo; char *value_string_repr = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, fi->hfinfo->display); + gboolean has_children = any_has_children(node_values_list); // We assume all values of a json key have roughly the same layout. Thus we can use the first value to derive // attributes of all the values. gboolean has_value = value_string_repr != NULL; - gboolean has_children = first_value->first_child != NULL; gboolean is_pseudo_text_field = fi->hfinfo->id == 0; wmem_free(NULL, value_string_repr); // fvalue_to_string_repr returns allocated buffer @@ -831,7 +849,9 @@ write_json_proto_node_list(GSList *proto_node_list_head, write_json_data *pdata) pdata->filter = NULL; } - write_json_proto_node(node_values_list, suffix, write_json_proto_node_children, pdata); + // has_children is TRUE if any of the nodes have children. So we're not 100% sure whether this + // particular node has children or not => use the 'dynamic' version of 'write_json_proto_node' + write_json_proto_node(node_values_list, suffix, write_json_proto_node_dynamic, pdata); // Put protocol filter back if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) { @@ -967,6 +987,20 @@ write_json_proto_node_hex_dump(proto_node *node, write_json_data *pdata) } /** + * Writes the value of a node, which may be a simple node with no value and no children, + * or a node with children -- this will be determined dynamically + */ +static void +write_json_proto_node_dynamic(proto_node *node, write_json_data *data) +{ + if (node->first_child == NULL) { + write_json_proto_node_no_value(node, data); + } else { + write_json_proto_node_children(node, data); + } +} + +/** * Writes the children of a node. Calls write_json_proto_node_list internally which recursively writes children of nodes * to the output. */ |