* Replace OpenBSD regex library with PCRE2. PCRE2 has way better performance than the OpenBSD library (something around 20 times faster). The following flags are enabled for every pattern: - PCRE2_UTF - PCRE2_MATCH_INVALID_UTF - PCRE2_NO_UTF_CHECK All the others are optional. Changes made: - Adds PCRE2 as subproject. - Changes the API away from POSIX to PCRE2. - Edits many regex patterns because: - ' ' is skipped in patterns, if the EXTENDED flag is set for matching. '\s' must be set now. - '.' doesn't match newlines by default. - Changes the API so matches and their groups are bundled into PVectors. - Moves the regex component to rz_util. * Fix cross build - add copy of PCRE2 dependecy Meson currently doesn't support subprojects to be native and non-native at the same time. See: https://github.com/mesonbuild/meson/issues/10947 Unfortunately, sdb depends on rz_util which in turn depends on PCRE2. Excluding PCRE2 from the native build makes linking of rz_util not possible anymore. Adding it, will make Meson complain that the dependencies cannot be mixed. Hence, we compile a copy of PCRE2 for the native build if required.
58 lines
1.3 KiB
C
58 lines
1.3 KiB
C
// SPDX-FileCopyrightText: 2008-2020 pancake <pancake@nopcode.org>
|
|
// SPDX-FileCopyrightText: 2008-2020 LemonBoy <thatlemon@gmail.com>
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
#include "rz_search.h"
|
|
#include <rz_vector.h>
|
|
#include <rz_util/rz_regex.h>
|
|
|
|
/**
|
|
* \return -1 on failure.
|
|
*/
|
|
RZ_API int rz_search_regexp_update(RzSearch *s, ut64 from, const ut8 *buf, int len) {
|
|
RzSearchKeyword *kw;
|
|
RzListIter *iter;
|
|
RzPVector *matches = NULL;
|
|
RzRegex *compiled = NULL;
|
|
const int old_nhits = s->nhits;
|
|
int ret = 0;
|
|
|
|
rz_list_foreach (s->kws, iter, kw) {
|
|
int cflags = RZ_REGEX_EXTENDED;
|
|
|
|
if (kw->icase) {
|
|
cflags |= RZ_REGEX_CASELESS;
|
|
}
|
|
|
|
compiled = rz_regex_new((char *)kw->bin_keyword, cflags, 0);
|
|
if (!compiled) {
|
|
eprintf("Cannot compile '%s' regexp\n", kw->bin_keyword);
|
|
return -1;
|
|
}
|
|
|
|
matches = rz_regex_match_all_not_grouped(compiled, (char *)buf, len, from, RZ_REGEX_DEFAULT);
|
|
void **it;
|
|
rz_pvector_foreach (matches, it) {
|
|
RzRegexMatch *m = *it;
|
|
int t = rz_search_hit_new(s, kw, m->start);
|
|
if (t == 0) {
|
|
ret = -1;
|
|
rz_pvector_free(matches);
|
|
goto beach;
|
|
}
|
|
// Max hits reached
|
|
if (t > 1) {
|
|
rz_pvector_free(matches);
|
|
goto beach;
|
|
}
|
|
}
|
|
rz_pvector_free(matches);
|
|
}
|
|
|
|
beach:
|
|
rz_regex_free(compiled);
|
|
if (!ret) {
|
|
ret = s->nhits - old_nhits;
|
|
}
|
|
return ret;
|
|
}
|