epan: Respect custom column resolved/unresolved status everywhere

Add a function to get the column text of the nth column, taking
into account whether the column is resolved or unresolved. Use
this function in the GUI, as well as in tshark, when writing
PSML, exporting dissection to PSML, etc., instead of accessing
col_data directly.

This removes the direct accesses of col_data from outside
column.c and column-utils.c

Fix #18168.
This commit is contained in:
John Thacker 2022-07-09 12:34:15 -04:00
parent 58b29b8f74
commit 8ac995578c
10 changed files with 75 additions and 57 deletions

View File

@ -806,6 +806,20 @@ get_column_tooltip(const gint col)
return g_string_free (column_tooltip, FALSE);
}
const gchar*
get_column_text(column_info *cinfo, const gint col)
{
ws_assert(cinfo);
ws_assert(col < cinfo->num_cols);
if (!get_column_resolved(col) && cinfo->col_expr.col_expr_val[col]) {
/* Use the unresolved value in col_expr_val */
return cinfo->col_expr.col_expr_val[col];
}
return cinfo->columns[col].col_data;
}
void
col_finalize(column_info *cinfo)
{

View File

@ -66,6 +66,19 @@ gint get_column_char_width(const gint format);
WS_DLL_PUBLIC
gchar *get_column_tooltip(const gint col);
/** Get the text of a column element. The string returned may
* depend on whether the resolved member variable is set.
* For internal Wireshark use, not to be called from dissectors.
* Dissectors use col_get_text() in column-utils.h
*
* @param cinfo the column information
* @param col the column index to use (not the format)
*
* @return the text string
*/
WS_DLL_PUBLIC
const gchar *get_column_text(column_info *cinfo, const gint col);
WS_DLL_PUBLIC
void
col_finalize(column_info *cinfo);

View File

@ -1176,7 +1176,7 @@ write_ek_summary(column_info *cinfo, write_json_data* pdata)
if (!get_column_visible(i))
continue;
json_dumper_set_member_name(pdata->dumper, g_ascii_strdown(cinfo->columns[i].col_title, -1));
json_dumper_value_string(pdata->dumper, cinfo->columns[i].col_data);
json_dumper_value_string(pdata->dumper, get_column_text(cinfo, i));
}
}
@ -1620,7 +1620,7 @@ write_psml_columns(epan_dissect_t *edt, FILE *fh, gboolean use_color)
if (!get_column_visible(i))
continue;
fprintf(fh, "<section>");
print_escaped_xml(fh, edt->pi.cinfo->columns[i].col_data);
print_escaped_xml(fh, get_column_text(edt->pi.cinfo, i));
fprintf(fh, "</section>\n");
}
@ -1686,9 +1686,9 @@ write_csv_columns(epan_dissect_t *edt, FILE *fh)
for (i = 0; i < edt->pi.cinfo->num_cols - 1; i++) {
if (!get_column_visible(i))
continue;
csv_write_str(edt->pi.cinfo->columns[i].col_data, ',', fh);
csv_write_str(get_column_text(edt->pi.cinfo, i), ',', fh);
}
csv_write_str(edt->pi.cinfo->columns[i].col_data, '\n', fh);
csv_write_str(get_column_text(edt->pi.cinfo,i), '\n', fh);
}
void
@ -2515,7 +2515,7 @@ static void write_specified_fields(fields_format format, output_fields_t *fields
g_free(col_name);
if (NULL != field_index) {
format_field_values(fields, field_index, g_strdup(cinfo->columns[col].col_data));
format_field_values(fields, field_index, g_strdup(get_column_text(cinfo, col)));
}
}
}

10
file.c
View File

@ -2345,6 +2345,7 @@ print_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec, Buffer *buf,
char bookmark_name[9+10+1]; /* "__frameNNNNNNNNNN__\0" */
char bookmark_title[6+10+1]; /* "Frame NNNNNNNNNN__\0" */
col_item_t* col_item;
const gchar* col_text;
/* Fill in the column information if we're printing the summary
information. */
@ -2394,8 +2395,9 @@ print_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec, Buffer *buf,
line_len = 0;
for (i = 0; i < args->num_visible_cols; i++) {
col_item = &cf->cinfo.columns[args->visible_cols[i]];
col_text = get_column_text(&cf->cinfo, args->visible_cols[i]);
/* Find the length of the string for this column. */
column_len = (int) strlen(col_item->col_data);
column_len = (int) strlen(col_text);
if (args->col_widths[i] > column_len)
column_len = args->col_widths[i];
@ -2411,9 +2413,9 @@ print_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec, Buffer *buf,
/* Right-justify the packet number column. */
if (col_item->col_fmt == COL_NUMBER)
snprintf(cp, column_len+1, "%*s", args->col_widths[i], col_item->col_data);
snprintf(cp, column_len+1, "%*s", args->col_widths[i], col_text);
else
snprintf(cp, column_len+1, "%-*s", args->col_widths[i], col_item->col_data);
snprintf(cp, column_len+1, "%-*s", args->col_widths[i], col_text);
cp += column_len;
if (i != args->num_visible_cols - 1)
*cp++ = ' ';
@ -3218,7 +3220,7 @@ match_summary_line(capture_file *cf, frame_data *fdata,
for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
if (cf->cinfo.columns[colx].fmt_matx[COL_INFO]) {
/* Found it. See if we match. */
info_column = edt.pi.cinfo->columns[colx].col_data;
info_column = get_column_text(edt.pi.cinfo, colx);
info_column_len = strlen(info_column);
if (cf->regex) {
if (g_regex_match(cf->regex, info_column, (GRegexMatchFlags) 0, NULL)) {

View File

@ -799,6 +799,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
get_column_format_from_str@Base 1.9.1
get_column_format_matches@Base 1.9.1
get_column_resolved@Base 1.9.1
get_column_text@Base 3.7.2
get_column_title@Base 1.9.1
get_column_tooltip@Base 2.0.1
get_column_visible@Base 1.9.1

View File

@ -1333,9 +1333,7 @@ sharkd_session_process_frames_cb(epan_dissect_t *edt, proto_tree *tree _U_,
sharkd_json_array_open("c");
for (int col = 0; col < cinfo->num_cols; ++col)
{
const col_item_t *col_item = &cinfo->columns[col];
sharkd_json_value_string(NULL, col_item->col_data);
sharkd_json_value_string(NULL, get_column_text(cinfo, col));
}
sharkd_json_array_close();
@ -3483,9 +3481,7 @@ sharkd_session_process_frame_cb(epan_dissect_t *edt, proto_tree *tree, struct ep
sharkd_json_array_open("col");
for (col = 0; col < cinfo->num_cols; ++col)
{
const col_item_t *col_item = &cinfo->columns[col];
sharkd_json_value_string(NULL, col_item->col_data);
sharkd_json_value_string(NULL, get_column_text(cinfo, col));
}
sharkd_json_array_close();
}

View File

@ -1720,13 +1720,14 @@ print_columns(capture_file *cf)
/* Skip columns not marked as visible. */
if (!get_column_visible(i))
continue;
const gchar* col_text = get_column_text(&cf->cinfo, i);
switch (col_item->col_fmt) {
case COL_NUMBER:
column_len = col_len = strlen(col_item->col_data);
column_len = col_len = strlen(col_text);
if (column_len < 3)
column_len = 3;
line_bufp = get_line_buf(buf_offset + column_len);
put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
break;
case COL_CLS_TIME:
@ -1737,11 +1738,11 @@ print_columns(capture_file *cf)
case COL_UTC_TIME:
case COL_UTC_YMD_TIME: /* XXX - wider */
case COL_UTC_YDOY_TIME: /* XXX - wider */
column_len = col_len = strlen(col_item->col_data);
column_len = col_len = strlen(col_text);
if (column_len < 10)
column_len = 10;
line_bufp = get_line_buf(buf_offset + column_len);
put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
break;
case COL_DEF_SRC:
@ -1753,11 +1754,11 @@ print_columns(capture_file *cf)
case COL_DEF_NET_SRC:
case COL_RES_NET_SRC:
case COL_UNRES_NET_SRC:
column_len = col_len = strlen(col_item->col_data);
column_len = col_len = strlen(col_text);
if (column_len < 12)
column_len = 12;
line_bufp = get_line_buf(buf_offset + column_len);
put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
break;
case COL_DEF_DST:
@ -1769,17 +1770,17 @@ print_columns(capture_file *cf)
case COL_DEF_NET_DST:
case COL_RES_NET_DST:
case COL_UNRES_NET_DST:
column_len = col_len = strlen(col_item->col_data);
column_len = col_len = strlen(col_text);
if (column_len < 12)
column_len = 12;
line_bufp = get_line_buf(buf_offset + column_len);
put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
put_string_spaces(line_bufp + buf_offset, col_text, col_len, column_len);
break;
default:
column_len = strlen(col_item->col_data);
column_len = strlen(col_text);
line_bufp = get_line_buf(buf_offset + column_len);
put_string(line_bufp + buf_offset, col_item->col_data, column_len);
put_string(line_bufp + buf_offset, col_text, column_len);
break;
}
buf_offset += column_len;

View File

@ -4215,13 +4215,14 @@ print_columns(capture_file *cf, const epan_dissect_t *edt)
/* Skip columns not marked as visible. */
if (!get_column_visible(i))
continue;
const gchar* col_text = get_column_text(&cf->cinfo, i);
switch (col_item->col_fmt) {
case COL_NUMBER:
column_len = col_len = strlen(col_item->col_data);
column_len = col_len = strlen(col_text);
if (column_len < 5)
column_len = 5;
line_bufp = get_line_buf(buf_offset + column_len);
put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
break;
case COL_CLS_TIME:
@ -4232,11 +4233,11 @@ print_columns(capture_file *cf, const epan_dissect_t *edt)
case COL_UTC_TIME:
case COL_UTC_YMD_TIME: /* XXX - wider */
case COL_UTC_YDOY_TIME: /* XXX - wider */
column_len = col_len = strlen(col_item->col_data);
column_len = col_len = strlen(col_text);
if (column_len < 10)
column_len = 10;
line_bufp = get_line_buf(buf_offset + column_len);
put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
break;
case COL_DEF_SRC:
@ -4248,11 +4249,11 @@ print_columns(capture_file *cf, const epan_dissect_t *edt)
case COL_DEF_NET_SRC:
case COL_RES_NET_SRC:
case COL_UNRES_NET_SRC:
column_len = col_len = strlen(col_item->col_data);
column_len = col_len = strlen(col_text);
if (column_len < 12)
column_len = 12;
line_bufp = get_line_buf(buf_offset + column_len);
put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
break;
case COL_DEF_DST:
@ -4264,17 +4265,17 @@ print_columns(capture_file *cf, const epan_dissect_t *edt)
case COL_DEF_NET_DST:
case COL_RES_NET_DST:
case COL_UNRES_NET_DST:
column_len = col_len = strlen(col_item->col_data);
column_len = col_len = strlen(col_text);
if (column_len < 12)
column_len = 12;
line_bufp = get_line_buf(buf_offset + column_len);
put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
put_string_spaces(line_bufp + buf_offset, col_text, col_len, column_len);
break;
default:
column_len = strlen(col_item->col_data);
column_len = strlen(col_text);
line_bufp = get_line_buf(buf_offset + column_len);
put_string(line_bufp + buf_offset, col_item->col_data, column_len);
put_string(line_bufp + buf_offset, col_text, column_len);
break;
}
buf_offset += column_len;

View File

@ -237,7 +237,7 @@ void PacketListRecord::cacheColumnStrings(column_info *cinfo)
/* Column based on frame_data or it already contains a value */
if (text_col < 0) {
col_fill_in_frame_data(fdata_, cinfo, column, FALSE);
col_text_ << QString(cinfo->columns[column].col_data);
col_text_ << QString(get_column_text(cinfo, column));
continue;
}
@ -249,12 +249,13 @@ void PacketListRecord::cacheColumnStrings(column_info *cinfo)
case COL_8021Q_VLAN_ID:
case COL_EXPERT:
case COL_FREQ_CHAN:
if (cinfo->columns[column].col_data && cinfo->columns[column].col_data != cinfo->columns[column].col_buf) {
const gchar *col_data = get_column_text(cinfo, column);
if (col_data && col_data != cinfo->columns[column].col_buf) {
/* This is a constant string, so we don't have to copy it */
// XXX - ui/gtk/packet_list_store.c uses G_MAXUSHORT. We don't do proper UTF8
// truncation in either case.
int col_text_len = MIN(qstrlen(cinfo->col_data[column]) + 1, COL_MAX_INFO_LEN);
col_text_ << QString(QByteArray::fromRawData(cinfo->columns[column].col_data, col_text_len));
int col_text_len = MIN(qstrlen(col_data) + 1, COL_MAX_INFO_LEN);
col_text_ << QString(QByteArray::fromRawData(col_data, col_text_len));
break;
}
/* !! FALL-THROUGH!! */
@ -278,29 +279,18 @@ void PacketListRecord::cacheColumnStrings(column_info *cinfo)
case COL_RES_NET_DST:
case COL_UNRES_NET_DST:
default:
if (!get_column_resolved(column) && cinfo->col_expr.col_expr_val[column]) {
/* Use the unresolved value in col_expr_val */
// XXX Use QContiguousCache?
col_text_ << QString(cinfo->col_expr.col_expr_val[column]);
} else {
col_text_ << QString(cinfo->columns[column].col_data);
}
// XXX Use QContiguousCache?
col_text_ << QString(get_column_text(cinfo, column));
break;
}
#else // MINIMIZE_STRING_COPYING
QString col_str;
if (!get_column_resolved(column) && cinfo->col_expr.col_expr_val[column]) {
/* Use the unresolved value in col_expr_val */
col_str = QString(cinfo->col_expr.col_expr_val[column]);
} else {
int text_col = cinfo_column_.value(column, -1);
if (text_col < 0) {
col_fill_in_frame_data(fdata_, cinfo, column, FALSE);
}
col_str = QString(cinfo->columns[column].col_data);
int text_col = cinfo_column_.value(column, -1);
if (text_col < 0) {
col_fill_in_frame_data(fdata_, cinfo, column, FALSE);
}
col_str = QString(get_column_text(cinfo, column));
col_text_ << col_str;
col_lines = static_cast<int>(col_str.count('\n'));
if (col_lines > lines_) {

View File

@ -83,7 +83,7 @@ PacketDialog::PacketDialog(QWidget &parent, CaptureFile &cf, frame_data *fdata)
// ElidedLabel doesn't support rich text / HTML
col_parts << QString("%1: %2")
.arg(get_column_title(i))
.arg(cap_file_.capFile()->cinfo.columns[i].col_data);
.arg(get_column_text(&cap_file_.capFile()->cinfo, i));
}
col_info_ = col_parts.join(" " UTF8_MIDDLE_DOT " ");