MAX_MCS_INDEX is a valid array index.
[metze/wireshark/wip.git] / epan / expert.c
index d82937293d307f93b83bbb3ae9349c0dcff6c63c..c9f7c96e9ded03740c89f90350092f81309d31de 100644 (file)
@@ -68,6 +68,9 @@ static gpa_expertinfo_t gpa_expertinfo;
 /* Hash table of abbreviations and IDs */
 static GHashTable *gpa_name_map = NULL;
 
+/* Deregistered expert infos */
+static GPtrArray *deregistered_expertinfos = NULL;
+
 const value_string expert_group_vals[] = {
        { PI_CHECKSUM,          "Checksum" },
        { PI_SEQUENCE,          "Sequence" },
@@ -80,6 +83,8 @@ const value_string expert_group_vals[] = {
        { PI_PROTOCOL,          "Protocol" },
        { PI_SECURITY,          "Security" },
        { PI_COMMENTS_GROUP,    "Comment" },
+       { PI_DECRYPTION,        "Decryption" },
+       { PI_ASSUMPTION,        "Assumption" },
        { 0, NULL }
 };
 
@@ -121,13 +126,15 @@ static GArray *uat_saved_fields = NULL;
 UAT_CSTRING_CB_DEF(uat_expert_entries, field, expert_level_entry_t)
 UAT_VS_DEF(uat_expert_entries, severity, expert_level_entry_t, guint32, PI_ERROR, "Error")
 
-static void uat_expert_update_cb(void *r, const char **err)
+static gboolean uat_expert_update_cb(void *r, char **err)
 {
        expert_level_entry_t *rec = (expert_level_entry_t *)r;
 
        if (expert_registrar_get_byname(rec->field) == NULL) {
                *err = g_strdup_printf("Expert Info field doesn't exist");
+               return FALSE;
        }
+       return TRUE;
 }
 
 static void *uat_expert_copy_cb(void *n, const void *o, size_t siz _U_)
@@ -184,6 +191,7 @@ static void uat_expert_post_update_cb(void)
        if((guint)eiindex >= gpa_expertinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG"))   \
                g_error("Unregistered expert info! index=%d", eiindex);                          \
        DISSECTOR_ASSERT_HINT((guint)eiindex < gpa_expertinfo.len, "Unregistered expert info!"); \
+       DISSECTOR_ASSERT_HINT(gpa_expertinfo.ei[eiindex] != NULL, "Unregistered expert info!"); \
        expinfo = gpa_expertinfo.ei[eiindex];
 
 void
@@ -262,6 +270,7 @@ expert_init(void)
        gpa_expertinfo.ei            = NULL;
        gpa_name_map                 = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
        uat_saved_fields             = g_array_new(FALSE, FALSE, sizeof(expert_field_info*));
+       deregistered_expertinfos     = g_ptr_array_new();
 }
 
 void
@@ -290,6 +299,11 @@ expert_cleanup(void)
                g_array_free(uat_saved_fields, TRUE);
                uat_saved_fields = NULL;
        }
+
+       if (deregistered_expertinfos) {
+               g_ptr_array_free(deregistered_expertinfos, FALSE);
+               deregistered_expertinfos = NULL;
+       }
 }
 
 
@@ -320,6 +334,37 @@ expert_module_t *expert_register_protocol(int id)
        return module;
 }
 
+void
+expert_deregister_expertinfo (const char *abbrev)
+{
+       expert_field_info *expinfo = (expert_field_info*)g_hash_table_lookup(gpa_name_map, abbrev);
+       if (expinfo) {
+               g_ptr_array_add(deregistered_expertinfos, gpa_expertinfo.ei[expinfo->id]);
+               g_hash_table_steal(gpa_name_map, abbrev);
+       }
+}
+
+void
+expert_deregister_protocol (expert_module_t *module)
+{
+       wmem_free(wmem_epan_scope(), module);
+}
+
+static void
+free_deregistered_expertinfo (gpointer data, gpointer user_data _U_)
+{
+       expert_field_info *expinfo = (expert_field_info *) data;
+       gpa_expertinfo.ei[expinfo->id] = NULL; /* Invalidate this id */
+}
+
+void
+expert_free_deregistered_expertinfos (void)
+{
+       g_ptr_array_foreach(deregistered_expertinfos, free_deregistered_expertinfo, NULL);
+       g_ptr_array_free(deregistered_expertinfos, TRUE);
+       deregistered_expertinfos = g_ptr_array_new();
+}
+
 static int
 expert_register_field_init(expert_field_info *expinfo, expert_module_t *module)
 {
@@ -368,8 +413,8 @@ expert_register_field_array(expert_module_t *module, ei_register_info *exp, cons
                 */
                if (ptr->ids->ei != -1 && ptr->ids->ei != 0) {
                        fprintf(stderr,
-                               "Duplicate field detected in call to expert_register_field_array: '%s' is already registered\n",
-                               ptr->eiinfo.summary);
+                               "Duplicate field detected in call to expert_register_field_array: '%s' is already registered, name=%s\n",
+                               ptr->eiinfo.summary, ptr->eiinfo.name);
                        return;
                }
 
@@ -402,6 +447,20 @@ expert_registrar_get_byname(const char *field_name)
        return hfinfo;
 }
 
+/**
+ * Get summary text of an expert_info field.
+ * This is intended for use in expert_add_info_format or proto_tree_add_expert_format
+ * to get the "base" string to then append additional information
+ */
+const gchar* expert_get_summary(expert_field *eiindex)
+{
+       expert_field_info *eiinfo;
+
+       /* Look up the item */
+       EXPERT_REGISTRAR_GET_NTH(eiindex->ei, eiinfo);
+
+    return eiinfo->summary;
+}
 
 /** clear flags according to the mask and set new flag values */
 #define FI_REPLACE_FLAGS(fi, mask, flags_in) { \
@@ -461,7 +520,7 @@ expert_set_info_vformat(packet_info *pinfo, proto_item *pi, int group, int sever
        }
 
        /* if this packet isn't loaded because of a read filter, don't output anything */
-       if (pinfo == NULL || PINFO_FD_NUM(pinfo) == 0) {
+       if (pinfo == NULL || pinfo->num == 0) {
                return;
        }
 
@@ -514,9 +573,10 @@ expert_set_info_vformat(packet_info *pinfo, proto_item *pi, int group, int sever
 
        ei = wmem_new(wmem_packet_scope(), expert_info_t);
 
-       ei->packet_num  = PINFO_FD_NUM(pinfo);
+       ei->packet_num  = pinfo->num;
        ei->group       = group;
        ei->severity    = severity;
+       ei->hf_index    = hf_index;
        ei->protocol    = pinfo->current_proto;
        ei->summary     = wmem_strdup(wmem_packet_scope(), formatted);
 
@@ -580,7 +640,7 @@ proto_tree_add_expert_internal(proto_tree *tree, packet_info *pinfo, expert_fiel
        /* Look up the item */
        EXPERT_REGISTRAR_GET_NTH(expindex->ei, eiinfo);
 
-       ti = proto_tree_add_text(tree, tvb, start, length, "%s", eiinfo->summary);
+       ti = proto_tree_add_text_internal(tree, tvb, start, length, "%s", eiinfo->summary);
        va_start(unused, length);
        expert_set_info_vformat(pinfo, ti, eiinfo->group, eiinfo->severity, *eiinfo->hf_info.p_id, FALSE, eiinfo->summary, unused);
        va_end(unused);
@@ -606,7 +666,7 @@ proto_tree_add_expert_format(proto_tree *tree, packet_info *pinfo, expert_field
        EXPERT_REGISTRAR_GET_NTH(expindex->ei, eiinfo);
 
        va_start(ap, format);
-       ti = proto_tree_add_text_valist(tree, tvb, start, length, format, ap);
+       ti = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
        va_end(ap);
 
        va_start(ap, format);