summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--epan/proto.h2
-rw-r--r--epan/uat-int.h63
-rw-r--r--epan/uat.c4
-rw-r--r--epan/uat.h77
4 files changed, 96 insertions, 50 deletions
diff --git a/epan/proto.h b/epan/proto.h
index 30aaf71728..1afe1f6a75 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -2862,7 +2862,7 @@ proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *t
exists, just pass -1
@param bad_checksum_expert optional expert info for a bad checksum. If
none exists, just pass NULL
- @pinfo Packet info used for optional expert info. If unused, NULL can
+ @param pinfo Packet info used for optional expert info. If unused, NULL can
be passed
@param computed_checksum Checksum to verify against
@param encoding data encoding of checksum from tvb
diff --git a/epan/uat-int.h b/epan/uat-int.h
index 46a32bcf9a..43aa3c2721 100644
--- a/epan/uat-int.h
+++ b/epan/uat-int.h
@@ -55,8 +55,8 @@ struct epan_uat {
gboolean from_profile;
const char* help;
guint flags;
- void** user_ptr;
- guint* nrows_p;
+ void** user_ptr; /**< Pointer to a dissector variable where an array of valid records are stored. */
+ guint* nrows_p; /**< Pointer to a dissector variable where the number of valid records in user_ptr are written. */
uat_copy_cb_t copy_cb;
uat_update_cb_t update_cb;
uat_free_cb_t free_cb;
@@ -64,9 +64,9 @@ struct epan_uat {
uat_field_t* fields;
guint ncols;
- GArray* user_data;
- GArray* raw_data;
- GArray* valid_data;
+ GArray* user_data; /**< An array of valid records that will be exposed to the dissector. */
+ GArray* raw_data; /**< An array of records containing possibly invalid data. For internal use only. */
+ GArray* valid_data; /**< An array of booleans describing whether the records in 'raw_data' are valid or not. */
gboolean changed;
uat_rep_t* rep;
uat_rep_free_cb_t free_rep;
@@ -81,30 +81,69 @@ void uat_init(void);
void uat_reset(void);
+/**
+ * Clones the given record and stores it internally in the UAT. If it is
+ * considered a valid record, then it will also be cloned and stored in the
+ * externally visible list.
+ */
WS_DLL_PUBLIC
-void* uat_add_record(uat_t*, const void* orig_rec_ptr, gboolean valid_rec);
+void* uat_add_record(uat_t *uat, const void *orig_rec_ptr, gboolean valid_rec);
+/**
+ * Marks the internal record in the UAT as valid or invalid. The record must
+ * exist in the UAT.
+ */
WS_DLL_PUBLIC
-void uat_update_record(uat_t *uat, const void *data, gboolean valid_rec);
+void uat_update_record(uat_t *uat, const void *record, gboolean valid_rec);
+/**
+ * Changes the order of two internal UAT records.
+ */
WS_DLL_PUBLIC
-void uat_swap(uat_t*, guint idx_a, guint idx_b);
+void uat_swap(uat_t *uat, guint idx_a, guint idx_b);
+/**
+ * Removes the record with the given index from the internal record list.
+ */
WS_DLL_PUBLIC
-void uat_remove_record_idx(uat_t*, guint rec_idx);
+void uat_remove_record_idx(uat_t *uat, guint rec_idx);
-void uat_destroy(uat_t*);
+void uat_destroy(uat_t *uat);
+/**
+ * Removes and destroys all records from the UAT.
+ */
WS_DLL_PUBLIC
-void uat_clear(uat_t*);
+void uat_clear(uat_t *uat);
+/**
+ * Saves the records from an UAT to file.
+ * Returns TRUE on success and FALSE on failure, storing the reason in 'error'
+ * (which must be freed using g_free).
+ */
WS_DLL_PUBLIC
-gboolean uat_save(uat_t* , char** );
+gboolean uat_save(uat_t *uat, char **error);
+/**
+ * Loads the records for all registered UATs from file.
+ */
void uat_load_all(void);
+/**
+ * Exposes the array of valid records to the UAT consumer (dissectors), updating
+ * the contents of 'data_ptr' and 'num_items_ptr' (see 'uat_new').
+ */
#define UAT_UPDATE(uat) do { *((uat)->user_ptr) = (void*)((uat)->user_data->data); *((uat)->nrows_p) = (uat)->user_data->len; } while(0)
+/**
+ * Get a record from the array of all UAT entries, whether they are semantically
+ * valid or not. This memory must only be used internally in the UAT core and
+ * must not be exposed to dissectors.
+ */
#define UAT_INDEX_PTR(uat,idx) (uat->raw_data->data + (uat->record_size * (idx)))
+/**
+ * Get a record from the array of all valid entries. These records will be
+ * shared with UAT consumers (dissectors).
+ */
#define UAT_USER_INDEX_PTR(uat,idx) (uat->user_data->data + (uat->record_size * (idx)))
#ifdef __cplusplus
diff --git a/epan/uat.c b/epan/uat.c
index 07f994bc67..328920266d 100644
--- a/epan/uat.c
+++ b/epan/uat.c
@@ -163,13 +163,13 @@ void* uat_add_record(uat_t* uat, const void* data, gboolean valid_rec) {
}
/* Updates the validity of a record. */
-void uat_update_record(uat_t *uat, const void *data, gboolean valid_rec) {
+void uat_update_record(uat_t *uat, const void *record, gboolean valid_rec) {
guint pos;
gboolean *valid;
/* Locate internal UAT data pointer. */
for (pos = 0; pos < uat->raw_data->len; pos++) {
- if (UAT_INDEX_PTR(uat, pos) == data) {
+ if (UAT_INDEX_PTR(uat, pos) == record) {
break;
}
}
diff --git a/epan/uat.h b/epan/uat.h
index d98cc86937..7c659a050a 100644
--- a/epan/uat.h
+++ b/epan/uat.h
@@ -2,7 +2,7 @@
* uat.h
*
* User Accessible Tables
- * Maintain an array of user accessible data strucures
+ * Maintain an array of user accessible data structures
*
* (c) 2007, Luis E. Garcia Ontanon <luis@ontanon.org>
*
@@ -37,24 +37,31 @@ extern "C" {
#endif /* __cplusplus */
/*
- * uat mantains a dynamically allocated table accessible to the user
- * via a file and/or gui tables.
+ * UAT maintains a dynamically allocated table accessible to the user
+ * via a file and/or via GUI preference dialogs.
*
- * the file is located either in userdir(when first read or when writen) or
- * in datadir for defaults (read only , it will be always written to userdir).
+ * The file is read from and written in the personal configuration directory. If
+ * there is no such file, defaults will be loaded from the global data
+ * directory.
*
- * the behaviour of the table is controlled by a series of callbacks
- * the caller must provide.
+ * The behaviour of the table is controlled by a series of callbacks which
+ * the caller (e.g. a dissector) must provide.
*
- * BEWARE that the user can change an uat at (almost) any time,
- * That is pointers to records in an uat are valid only during the call
- * to the function that obtains them (do not store them).
+ * BEWARE that the user can change an UAT at (almost) any time (via the GUI).
+ * That is, pointers to records in an UAT are valid only during the call
+ * to the function that obtains them (do not store pointers to these records).
+ * The records contents are only guaranteed to be valid in the post_update_cb
+ * function. (Implementation detail: currently a race condition is possible
+ * where the UAT consumer (dissector code) tries to use the UAT while the GUI
+ * user frees a record resulting in use-after-free. This is not ideal and might
+ * be fixed later.)
*
- * UATs are meant for short tables of user data (passwords and such) there's
+ * UATs are meant for short tables of user data (passwords and such), there is
* no quick access, you must iterate through them each time to fetch the record
* you are looking for.
*
- * Only users via gui or editing the file can add/remove records your code cannot.
+ * Only users via GUI or editing the file can add/remove records, your
+ * (dissector) code cannot.
*/
/* obscure data type to handle an uat */
@@ -71,7 +78,7 @@ typedef struct epan_uat uat_t;
/*
* Post-Update CB
*
- * to be called after to the table has being edited
+ * To be called by the GUI code after to the table has being edited.
* Will be called once the user clicks the Apply or OK button
* optional
*/
@@ -82,38 +89,38 @@ typedef void (*uat_post_update_cb_t)(void);
* Callbacks dealing with records (these deal with entire records)
********/
-/*
+/**
* Copy CB
- * copy(dest,orig,len)
+ * copy(dest, source, len)
*
- * used to copy a record
- * optional, memcpy will be used if not given
+ * Used to duplicate the contents of one record to another.
+ * Optional, memcpy will be used if not given.
*/
-typedef void* (*uat_copy_cb_t)(void*, const void*, size_t);
+typedef void* (*uat_copy_cb_t)(void *dest, const void *source, size_t len);
-/*
+/**
* Free CB
* free(record)
*
- * destroy a record's child data
- * (do not free the container, it will be handled by uat)
- * it is optional, no child data will be freed if no present
+ * Destroy the contents of a record, possibly freeing some fields.
+ * Do not free the container itself, this memory is owned by the UAT core.
+ * Optional if the record contains no pointers that need to be freed.
*/
-typedef void (*uat_free_cb_t)(void*);
+typedef void (*uat_free_cb_t)(void *record);
-/*
+/**
* Update CB
* update(record,&error)
*
- * to be called after any record fields had been updated
- * optional, record will be updated always if not given
- * it will return TRUE if OK or else
- * it will return FALSE and set *error to inform the user on what's
- * wrong with the given input
- * The error string must be allocated with g_malloc() or
- * a routine that calls it.
+ * Validates the contents of the record contents, to be called after any record
+ * fields had been updated (either from file or after modifications in the GUI).
+ *
+ * Optional, the record will be considered valid if the callback is omitted.
+ * It must return TRUE if the contents are considered valid and FALSE otherwise
+ * in which case the failure reason is set in 'error'. The error string will be
+ * freed by g_free.
*/
-typedef gboolean (*uat_update_cb_t)(void *, char**);
+typedef gboolean (*uat_update_cb_t)(void *record, char **error);
/*******
@@ -133,7 +140,7 @@ typedef gboolean (*uat_update_cb_t)(void *, char**);
* a routine that calls it.
* optional, if not given any input is considered OK and the set cb will be called
*/
-typedef gboolean (*uat_fld_chk_cb_t)(void*, const char*, unsigned, const void*, const void*, char**);
+typedef gboolean (*uat_fld_chk_cb_t)(void *record, const char *ptr, unsigned len, const void *chk_data, const void *fld_data, char **error);
/*
* Set Field CB
@@ -142,7 +149,7 @@ typedef gboolean (*uat_fld_chk_cb_t)(void*, const char*, unsigned, const void*,
* given an input string (ptr, len) sets the value of a field in the record,
* it is mandatory
*/
-typedef void (*uat_fld_set_cb_t)(void*, const char*, unsigned, const void*, const void*);
+typedef void (*uat_fld_set_cb_t)(void *record, const char *ptr, unsigned len, const void *set_data, const void *fld_data);
/*
* Convert-to-string CB
@@ -151,7 +158,7 @@ typedef void (*uat_fld_set_cb_t)(void*, const char*, unsigned, const void*, cons
* given a record returns a string representation of the field
* mandatory
*/
-typedef void (*uat_fld_tostr_cb_t)(void*, char**, unsigned*, const void*, const void*);
+typedef void (*uat_fld_tostr_cb_t)(void *record, char **out_ptr, unsigned *out_len, const void *tostr_data, const void *fld_data);
/***********
* Text Mode