UAT: Allow missing fields.

Add uat_set_default_values, which lets us provide default values for
fields that might be missing from the end of a UAT line. Set a default
value for the I/O Graph dialog's Y Axis Factor. Fixes the backward
compatibility issue described in #17623
This commit is contained in:
Gerald Combs 2021-11-06 17:14:20 -07:00
parent 846b17ee9a
commit e5eb17d414
6 changed files with 65 additions and 8 deletions

View File

@ -1937,6 +1937,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
uat_new@Base 1.9.1
uat_remove_record_idx@Base 1.9.1
uat_save@Base 1.9.1
uat_set_default_values@Base 3.6.0
uat_swap@Base 1.9.1
uat_update_record@Base 1.99.3
udp_dissect_pdus@Base 1.99.3

View File

@ -52,6 +52,7 @@ struct epan_uat {
uat_reset_cb_t reset_cb;
uat_field_t* fields;
const char** default_values;
guint ncols;
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. */

View File

@ -85,6 +85,7 @@ uat_t* uat_new(const char* name,
uat->post_update_cb = post_update_cb;
uat->reset_cb = reset_cb;
uat->fields = flds_array;
uat->default_values = NULL;
uat->user_data = g_array_new(FALSE,FALSE,(guint)uat->record_size);
uat->raw_data = g_array_new(FALSE,FALSE,(guint)uat->record_size);
uat->valid_data = g_array_new(FALSE,FALSE,sizeof(gboolean));
@ -265,6 +266,11 @@ uat_t* uat_get_table_by_name(const char* name) {
return NULL;
}
void uat_set_default_values(uat_t *uat_in, const char *default_values[])
{
uat_in->default_values = default_values;
}
char *uat_fld_tostr(void *rec, uat_field_t *f) {
guint len;
char *ptr;

View File

@ -258,7 +258,7 @@ typedef struct _uat_field_t {
#define UAT_AFFECTS_DISSECTION 0x00000001 /* affects packet dissection */
#define UAT_AFFECTS_FIELDS 0x00000002 /* affects what named fields exist */
/** Create a new uat
/** Create a new UAT.
*
* @param name The name of the table
* @param size The size of the structure
@ -293,12 +293,12 @@ uat_t* uat_new(const char* name,
uat_reset_cb_t reset_cb,
uat_field_t* flds_array);
/** Cleanup all Uats
/** Cleanup all UATs.
*
*/
void uat_cleanup(void);
/** Populate a uat using its file.
/** Populate a UAT using its file.
*
* @param uat_in Pointer to a uat. Must not be NULL.
* @param filename Filename to load, NULL to fetch from current profile.
@ -309,7 +309,7 @@ void uat_cleanup(void);
WS_DLL_PUBLIC
gboolean uat_load(uat_t* uat_in, const gchar *filename, char** err);
/** Create or update a single uat entry using a string.
/** Create or update a single UAT entry using a string.
*
* @param uat_in Pointer to a uat. Must not be NULL.
* @param entry The string representation of the entry. Format must match
@ -320,7 +320,7 @@ gboolean uat_load(uat_t* uat_in, const gchar *filename, char** err);
*/
gboolean uat_load_str(uat_t* uat_in, char* entry, char** err);
/** Given a uat name or filename, find its pointer.
/** Given a UAT name or filename, find its pointer.
*
* @param name The name or filename of the uat
*
@ -331,6 +331,22 @@ uat_t *uat_find(gchar *name);
WS_DLL_PUBLIC
uat_t* uat_get_table_by_name(const char* name);
/**
* Provide default field values for a UAT.
*
* This can be used to provide forward compatibility when fields are added
* to a UAT.
*
* @param uat_in Pointer to a uat. Must not be NULL.
* @param default_values An array of strings with default values. Must
* be the same length as flds_array. Individual elements can be NULL,
* and can be used to distinguish between mandatory and optional fields,
* e.g. { NULL, NULL, NULL, "default value (optional)" }
* @todo Use this to provide default values for empty tables.
*/
WS_DLL_PUBLIC
void uat_set_default_values(uat_t *uat_in, const char *default_values[]);
/*
* Some common uat_fld_chk_cbs
*/

View File

@ -246,7 +246,7 @@ comment #[^\n]*\n
BEGIN NEXT_FIELD;
}
<START_OF_LINE,NEXT_FIELD>{newline} {
<START_OF_LINE,NEXT_FIELD>{newline} {
yyextra->ptrx = g_strdup("");
yyextra->len = 0;
@ -298,8 +298,34 @@ comment #[^\n]*\n
}
<SEPARATOR>{newline} {
DUMP("separator->newline");
/*
* We've run out of fields. Check to see if we have any default
* values that we can fill in. The field for the current column
* will be filled in below in <END_OF_RECORD>{newline}.
*/
guint save_colnum = yyextra->colnum;
yyextra->colnum++;
while (yyextra->colnum < yyextra->uat->ncols) {
const char *default_value = yyextra->uat->default_values[yyextra->colnum];
if (!default_value) {
break;
}
yyextra->uat->fields[yyextra->colnum].cb.set(yyextra->record, default_value, (guint) strlen(default_value), yyextra->uat->fields[yyextra->colnum].cbdata.chk, yyextra->uat->fields[yyextra->colnum].fld_data);
ws_log(WS_LOG_DOMAIN, LOG_LEVEL_INFO, "%s:%d: Set %s to %s.",
yyextra->uat->filename, yyextra->linenum, yyextra->uat->fields[yyextra->colnum].name, default_value);
yyextra->colnum++;
}
if (yyextra->colnum < yyextra->uat->ncols) {
ERROR(("expecting field %s", yyextra->uat->fields[yyextra->colnum].name));
}
yyextra->colnum = save_colnum;
yyextra->linenum++;
ERROR(("expecting field %s in previous line",yyextra->uat->fields[yyextra->colnum].name));
BEGIN END_OF_RECORD;
yyless(0);
}
<SEPARATOR>. {
@ -348,7 +374,7 @@ comment #[^\n]*\n
}
<END_OF_RECORD>. {
ERROR(("unexpected char while looking for end of line"));
ERROR(("unexpected char %s while looking for end of line", yytext));
}
<ERRORED>{newline} { yyextra->linenum++; BEGIN START_OF_LINE; }

View File

@ -130,6 +130,11 @@ static io_graph_settings_t *iog_settings_ = NULL;
static guint num_io_graphs_ = 0;
static uat_t *iog_uat_ = NULL;
// y_axis_factor was added in 3.6. Provide backward compatibility.
static const char *iog_uat_defaults_[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "1"
};
extern "C" {
//Allow the enable/disable field to be a checkbox, but for backwards compatibility,
@ -1202,6 +1207,8 @@ void IOGraphDialog::loadProfileGraphs()
NULL,
io_graph_fields);
uat_set_default_values(iog_uat_, iog_uat_defaults_);
char* err = NULL;
if (!uat_load(iog_uat_, NULL, &err)) {
report_failure("Error while loading %s: %s. Default graph values will be used", iog_uat_->name, err);