Qt: Generate filter expressions for columns with multiple occurrences

Generate filter expressions for columns with multiple occurrences
by using the membership operator (which is semantically OR).
It's not clear if this approach makes more sense than AND;
there's use cases for both.

Don't do this for multifield custom columns, since we don't know
which values were found by which field. That takes changing
the column logic in several places.

Ping #18001
This commit is contained in:
John Thacker 2022-10-30 11:05:01 -04:00 committed by AndersBroman
parent 3aafecb7b9
commit 2ad4b5bb3c
1 changed files with 23 additions and 9 deletions

View File

@ -1316,19 +1316,18 @@ QString PacketList::getFilterFromRowAndColumn(QModelIndex idx)
fdata, &cap_file_->cinfo);
epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
if ((cap_file_->cinfo.columns[column].col_custom_occurrence) ||
(strchr (cap_file_->cinfo.col_expr.col_expr_val[column], ',') == NULL))
if ((cap_file_->cinfo.columns[column].col_custom_fields_ids == NULL) ||
(g_slist_length(cap_file_->cinfo.columns[column].col_custom_fields_ids) == 1))
{
/* Only construct the filter when a single occurrence is displayed
* otherwise we might end up with a filter like "ip.proto==1,6".
*
* Or do we want to be able to filter on multiple occurrences so that
* the filter might be calculated as "ip.proto==1 && ip.proto==6"
* instead?
/* Don't construct a filter on multifield custom columns, because
* we don't have a good reference for which values were found by
* which field. Fixing that requires changing logic in several
* places in the code (perhaps making col_expr_t a linked list?)
*/
if (strlen(cap_file_->cinfo.col_expr.col_expr[column]) != 0 &&
strlen(cap_file_->cinfo.col_expr.col_expr_val[column]) != 0) {
gboolean is_string_value = FALSE;
gboolean is_multiple_values = (strchr (cap_file_->cinfo.col_expr.col_expr_val[column], ',') != NULL);
if (cap_file_->cinfo.columns[column].col_fmt == COL_CUSTOM) {
header_field_info *hfi = proto_registrar_get_byname(cap_file_->cinfo.columns[column].col_custom_fields);
if (hfi && hfi->parent == -1) {
@ -1347,7 +1346,22 @@ QString PacketList::getFilterFromRowAndColumn(QModelIndex idx)
}
if (filter.isEmpty()) {
if (is_string_value) {
if (is_multiple_values) {
/* Use the membership operator and find packets that have
* at least one matching value. Not clear if this (which
* is equivalent to OR) makes more sense than AND matching
* logic, but it's easy to construct.
*/
if (is_string_value) {
filter.append(QString("%1 in {\"%2\"}")
.arg(cap_file_->cinfo.col_expr.col_expr[column])
.arg(cap_file_->cinfo.col_expr.col_expr_val[column]).split(",").join("\",\""));
} else {
filter.append(QString("%1 in {%2}")
.arg(cap_file_->cinfo.col_expr.col_expr[column])
.arg(cap_file_->cinfo.col_expr.col_expr_val[column]));
}
} else if (is_string_value) {
filter.append(QString("%1 == \"%2\"")
.arg(cap_file_->cinfo.col_expr.col_expr[column])
.arg(cap_file_->cinfo.col_expr.col_expr_val[column]));