forked from osmocom/wireshark
Convert capture file regex search to PCRE2.
Replace the use of the obsolete GRegex with PCRE2. Fixes a crash reported in issue #17500.
This commit is contained in:
parent
2cc887e80d
commit
e7f439bc2f
2
cfile.h
2
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 <control>N/B */
|
||||
|
|
20
file.c
20
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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <epan/strutil.h>
|
||||
|
||||
#include <wsutil/utf8_entities.h>
|
||||
#include <wsutil/regex.h>
|
||||
|
||||
#include "main_application.h"
|
||||
#include <QKeyEvent>
|
||||
|
@ -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;
|
||||
|
|
|
@ -47,7 +47,7 @@ private:
|
|||
|
||||
Ui::SearchFrame *sf_ui_;
|
||||
capture_file *cap_file_;
|
||||
GRegex *regex_;
|
||||
ws_regex_t *regex_;
|
||||
QString regex_error_;
|
||||
|
||||
private slots:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue