diff --git a/cfile.h b/cfile.h index 8ca3e23335..976f1dfa18 100644 --- a/cfile.h +++ b/cfile.h @@ -104,7 +104,7 @@ typedef struct _capture_file { guint32 search_pos; /* Byte position of last byte found in a hex search */ guint32 search_len; /* Length of bytes matching the search */ gboolean case_type; /* TRUE if case-insensitive text search */ - GRegex *regex; /* Set if regular expression search */ + ws_regex_t *regex; /* Set if regular expression search */ search_charset_t scs_type; /* Character set for text search */ search_direction dir; /* Direction in which to do searches */ gboolean search_in_progress; /* TRUE if user just clicked OK in the Find dialog or hit N/B */ diff --git a/file.c b/file.c index a49428ef6c..26163b907e 100644 --- a/file.c +++ b/file.c @@ -3146,7 +3146,7 @@ match_subtree_text(proto_node *node, gpointer data) } if (cf->regex) { - if (g_regex_match(cf->regex, label_ptr, (GRegexMatchFlags) 0, NULL)) { + if (ws_regex_matches(cf->regex, label_ptr)) { mdata->frame_matched = TRUE; mdata->finfo = fi; return; @@ -3223,7 +3223,7 @@ match_summary_line(capture_file *cf, frame_data *fdata, 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)) { + if (ws_regex_matches(cf->regex, info_column)) { result = MR_MATCHED; break; } @@ -3747,7 +3747,7 @@ match_regex(capture_file *cf, frame_data *fdata, wtap_rec *rec, Buffer *buf, void *criterion _U_) { match_result result = MR_NOTMATCHED; - GMatchInfo *match_info = NULL; + size_t result_pos[2] = {0, 0}; /* Load the frame's data. */ if (!cf_read_record(cf, fdata, rec, buf)) { @@ -3755,13 +3755,13 @@ match_regex(capture_file *cf, frame_data *fdata, return MR_ERROR; } - if (g_regex_match_full(cf->regex, (const gchar *)ws_buffer_start_ptr(buf), fdata->cap_len, - 0, (GRegexMatchFlags) 0, &match_info, NULL)) - { - gint start_pos = 0, end_pos = 0; - g_match_info_fetch_pos (match_info, 0, &start_pos, &end_pos); - cf->search_pos = end_pos - 1; - cf->search_len = end_pos - start_pos; + if (ws_regex_matches_pos(cf->regex, + (const gchar *)ws_buffer_start_ptr(buf), + fdata->cap_len, + result_pos)) { + //TODO: Fix cast. + cf->search_pos = (guint32)(result_pos[1] - 1); /* last byte = end position - 1 */ + cf->search_len = (guint32)(result_pos[1] - result_pos[0]); result = MR_MATCHED; } return result; diff --git a/packaging/debian/libwsutil0.symbols b/packaging/debian/libwsutil0.symbols index ece511aff5..cfa193a66c 100644 --- a/packaging/debian/libwsutil0.symbols +++ b/packaging/debian/libwsutil0.symbols @@ -439,6 +439,7 @@ libwsutil.so.0 libwsutil0 #MINVER# ws_regex_free@Base 3.7.0 ws_regex_matches@Base 3.7.0 ws_regex_matches_length@Base 3.7.0 + ws_regex_matches_pos@Base 3.7.2 ws_regex_pattern@Base 3.7.0 ws_socket_ptoa@Base 3.1.1 ws_strcasestr@Base 3.7.0 diff --git a/ui/qt/search_frame.cpp b/ui/qt/search_frame.cpp index 16c349f134..95a5b8e87c 100644 --- a/ui/qt/search_frame.cpp +++ b/ui/qt/search_frame.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "main_application.h" #include @@ -63,7 +64,7 @@ SearchFrame::SearchFrame(QWidget *parent) : SearchFrame::~SearchFrame() { if (regex_) { - g_regex_unref(regex_); + ws_regex_free(regex_); } delete sf_ui_; } @@ -140,13 +141,13 @@ void SearchFrame::keyPressEvent(QKeyEvent *event) bool SearchFrame::regexCompile() { - int flags = (G_REGEX_OPTIMIZE); + unsigned flags = 0; if (!sf_ui_->caseCheckBox->isChecked()) { - flags |= G_REGEX_CASELESS; + flags |= WS_REGEX_CASELESS; } if (regex_) { - g_regex_unref(regex_); + ws_regex_free(regex_); } if (sf_ui_->searchLineEdit->text().isEmpty()) { @@ -154,12 +155,12 @@ bool SearchFrame::regexCompile() return false; } - GError *error = nullptr; - regex_ = g_regex_new(sf_ui_->searchLineEdit->text().toUtf8().constData(), - (GRegexCompileFlags)flags, (GRegexMatchFlags) 0, &error); - if (error) { - regex_error_ = error->message; - g_error_free(error); + char *errmsg = nullptr; + regex_ = ws_regex_compile_ex(sf_ui_->searchLineEdit->text().toUtf8().constData(), -1, + &errmsg, flags); + + if (errmsg != nullptr) { + regex_error_ = errmsg; } return regex_ ? true : false; diff --git a/ui/qt/search_frame.h b/ui/qt/search_frame.h index c517fc79c4..7ea0946a2c 100644 --- a/ui/qt/search_frame.h +++ b/ui/qt/search_frame.h @@ -47,7 +47,7 @@ private: Ui::SearchFrame *sf_ui_; capture_file *cap_file_; - GRegex *regex_; + ws_regex_t *regex_; QString regex_error_; private slots: diff --git a/wsutil/regex.c b/wsutil/regex.c index 18ce71d8be..71b17824e3 100644 --- a/wsutil/regex.c +++ b/wsutil/regex.c @@ -103,14 +103,16 @@ ws_regex_compile(const char *patt, char **errmsg) static bool -match_pcre2(pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length) +match_pcre2(pcre2_code *code, const char *subject, ssize_t subj_length, + pcre2_match_data *match_data) { - pcre2_match_data *match_data; + PCRE2_SIZE length; int rc; - /* We don't use the matched substring but pcre2_match requires - * at least one pair of offsets. */ - match_data = pcre2_match_data_create(1, NULL); + if (subj_length < 0) + length = PCRE2_ZERO_TERMINATED; + else + length = (PCRE2_SIZE)subj_length; rc = pcre2_match(code, subject, @@ -120,8 +122,6 @@ match_pcre2(pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length) match_data, NULL); - pcre2_match_data_free(match_data); - if (rc < 0) { /* No match */ if (rc != PCRE2_ERROR_NOMATCH) { @@ -142,21 +142,49 @@ match_pcre2(pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length) bool ws_regex_matches(const ws_regex_t *re, const char *subj) { - ws_return_val_if_null(re, FALSE); - ws_return_val_if_null(subj, FALSE); - - return match_pcre2(re->code, (PCRE2_SPTR)subj, PCRE2_ZERO_TERMINATED); + return ws_regex_matches_length(re, subj, -1); } bool ws_regex_matches_length(const ws_regex_t *re, - const char *subj, size_t subj_length) + const char *subj, ssize_t subj_length) { + bool matched; + pcre2_match_data *match_data; + ws_return_val_if_null(re, FALSE); ws_return_val_if_null(subj, FALSE); - return match_pcre2(re->code, (PCRE2_SPTR)subj, (PCRE2_SIZE)subj_length); + /* We don't use the matched substring but pcre2_match requires + * at least one pair of offsets. */ + match_data = pcre2_match_data_create(1, NULL); + matched = match_pcre2(re->code, subj, subj_length, match_data); + pcre2_match_data_free(match_data); + return matched; +} + + +bool +ws_regex_matches_pos(const ws_regex_t *re, + const char *subj, ssize_t subj_length, + size_t pos_vect[2]) +{ + bool matched; + pcre2_match_data *match_data; + + ws_return_val_if_null(re, FALSE); + ws_return_val_if_null(subj, FALSE); + + match_data = pcre2_match_data_create(1, NULL); + matched = match_pcre2(re->code, subj, subj_length, match_data); + if (matched && pos_vect) { + PCRE2_SIZE *ovect = pcre2_get_ovector_pointer(match_data); + pos_vect[0] = ovect[0]; + pos_vect[1] = ovect[1]; + } + pcre2_match_data_free(match_data); + return matched; } diff --git a/wsutil/regex.h b/wsutil/regex.h index b3bd78fc66..0484eab383 100644 --- a/wsutil/regex.h +++ b/wsutil/regex.h @@ -37,7 +37,18 @@ ws_regex_matches(const ws_regex_t *re, const char *subj); /** Matches a subject string length in 8 bit code units. */ WS_DLL_PUBLIC bool ws_regex_matches_length(const ws_regex_t *re, - const char *subj, size_t subj_length); + const char *subj, ssize_t subj_length); + +/** Returns start and end position of the matched substring. + * + * pos_vect[0] is first codepoint in the matched substring. + * pos_vect[1] is the next to last codepoint in the matched substring. + * pos_vect[1] - pos_vect[0] is the matched substring length. + */ +WS_DLL_PUBLIC bool +ws_regex_matches_pos(const ws_regex_t *re, + const char *subj, ssize_t subj_length, + size_t pos_vect[2]); WS_DLL_PUBLIC void ws_regex_free(ws_regex_t *re);