aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorJohn Thacker <johnthacker@gmail.com>2022-11-02 09:11:30 -0400
committerJohn Thacker <johnthacker@gmail.com>2022-11-02 19:46:11 +0000
commite449b560c02d363603224a7558758eb7da0c6a73 (patch)
tree11c5ac11bc7a8598d06c7dbbb9242eb8ec40fddd /ui
parentc6a0b9b64adcd5cbca616b0806045513523be08d (diff)
epan: Properly generate filter expressions for custom columns
Properly generate filter expressions for custom columns by using proto_construct_match_selected_string on each value and then joining them together later instead of trying to split the column expression value. This ensures that escaping is done properly for display filter strings, that commas internal to field values are not confused with commas between occurrences, that for multifield columns we can distinguish which field each value matches, etc. It's not entirely clear whether AND or OR logic is appropriate for multiple occurrences; currently OR is used. Bump glib requirement to 2.54 for g_ptr_array_find_with_equal_func (this doesn't drop support for any major distribution that already meets our other library requirements, like Qt.) Fix #18001.
Diffstat (limited to 'ui')
-rw-r--r--ui/qt/packet_list.cpp51
1 files changed, 11 insertions, 40 deletions
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index eb6602af5f..4deecfc9bc 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -1314,54 +1314,25 @@ QString PacketList::getFilterFromRowAndColumn(QModelIndex idx)
epan_dissect_run(&edt, cap_file_->cd_t, &rec,
frame_tvbuff_new_buffer(&cap_file_->provider, fdata, &buf),
fdata, &cap_file_->cinfo);
- epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
- if ((cap_file_->cinfo.columns[column].col_custom_fields_ids == NULL) ||
- (g_slist_length(cap_file_->cinfo.columns[column].col_custom_fields_ids) == 1))
- {
- /* 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 (cap_file_->cinfo.columns[column].col_fmt == COL_CUSTOM) {
+ filter.append(gchar_free_to_qstring(col_custom_get_filter(&edt, &cap_file_->cinfo, column)));
+ } else {
+ /* We don't need to fill in the custom columns, as we get their
+ * filters above.
*/
+ col_fill_in(&edt.pi, TRUE, TRUE);
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) {
- /* Protocol only */
- filter.append(cap_file_->cinfo.col_expr.col_expr[column]);
- } else if (hfi && hfi->type == FT_STRING) {
- /* Custom string, add quotes */
- is_string_value = TRUE;
- }
- } else {
- header_field_info *hfi = proto_registrar_get_byname(cap_file_->cinfo.col_expr.col_expr[column]);
- if (hfi && hfi->type == FT_STRING) {
- /* Could be an address type such as usb.src which must be quoted. */
- is_string_value = TRUE;
- }
+ header_field_info *hfi = proto_registrar_get_byname(cap_file_->cinfo.col_expr.col_expr[column]);
+ if (hfi && hfi->type == FT_STRING) {
+ /* Could be an address type such as usb.src which must be quoted. */
+ is_string_value = TRUE;
}
if (filter.isEmpty()) {
- 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) {
+ 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]));