diff options
-rw-r--r-- | epan/proto.h | 2 | ||||
-rw-r--r-- | epan/uat-int.h | 63 | ||||
-rw-r--r-- | epan/uat.c | 4 | ||||
-rw-r--r-- | epan/uat.h | 77 |
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 |