diff options
| -rw-r--r-- | maildrop/Makefile.am | 6 | ||||
| -rw-r--r-- | maildrop/configure.ac | 9 | ||||
| -rw-r--r-- | maildrop/search.C | 139 | ||||
| -rw-r--r-- | maildrop/search.h | 24 |
4 files changed, 92 insertions, 86 deletions
diff --git a/maildrop/Makefile.am b/maildrop/Makefile.am index 5f94c37..154cebe 100644 --- a/maildrop/Makefile.am +++ b/maildrop/Makefile.am @@ -3,7 +3,7 @@ # distribution information. -AM_CPPFLAGS=@AUTHINCLUDE@ +AM_CPPFLAGS := @AUTHINCLUDE@ `pcre2-config --cflags` DISTCLEANFILES=uidgid testmailbot.* CLEANFILES=maildrop.html maildrop.1 maildropfilter.7 maildropfilter.html @@ -46,8 +46,8 @@ maildrop_SOURCES=deliver.C deliverdotlock.C deliverdotlock.h \ maildrop_DEPENDENCIES = libmdcommon.la -maildrop_LDADD = libmdcommon.la @AUTHLDADD@ -lpcre -maildrop_LDFLAGS= +maildrop_LDADD = libmdcommon.la @AUTHLDADD@ +maildrop_LDFLAGS= `pcre2-config --libs8` reformail_SOURCES=reformail.C reformail_LDADD = libmdcommon.la diff --git a/maildrop/configure.ac b/maildrop/configure.ac index fca57fe..63acdfb 100644 --- a/maildrop/configure.ac +++ b/maildrop/configure.ac @@ -159,7 +159,7 @@ AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_HEADER_TIME AC_HEADER_DIRENT -AC_CHECK_HEADERS(fcntl.h memory.h sys/file.h sys/time.h sys/stat.h unistd.h strings.h locale.h pcre.h pcre/pcre.h) +AC_CHECK_HEADERS(fcntl.h memory.h sys/file.h sys/time.h sys/stat.h unistd.h strings.h locale.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_TYPE_MODE_T @@ -301,6 +301,13 @@ else AC_CHECK_PROG(QMAIL,qmail-inject,qmail-inject,) fi +AC_CHECK_PROG(PCRE2, pcre2-config, yes, no) + +if test "$PCRE2" = "no" +then + AC_MSG_ERROR([pcre2 library not found]) +fi + dnl Try to find sendmail. test "x$prefix" = xNONE && prefix=$ac_default_prefix diff --git a/maildrop/search.C b/maildrop/search.C index 9add6ee..32d4ce6 100644 --- a/maildrop/search.C +++ b/maildrop/search.C @@ -12,22 +12,17 @@ void Search::cleanup() { - if (pcre_regexp_extra) + if (match_data) { - pcre_free(pcre_regexp_extra); - pcre_regexp_extra=NULL; + pcre2_match_data_free(match_data); + match_data=NULL; } + if (pcre_regexp) { - pcre_free(pcre_regexp); + pcre2_code_free(pcre_regexp); pcre_regexp=NULL; } - - if (pcre_vectors) - { - free(pcre_vectors); - pcre_vectors=NULL; - } } int Search::init(const char *expr, const char *opts) @@ -51,69 +46,55 @@ int Search::init(const char *expr, const char *opts) if (strchr(opts, 'w')) match_body=1; } - const char *errptr; + int errcode; cleanup(); - int errindex; + PCRE2_SIZE errindex; - pcre_regexp=pcre_compile(expr, - PCRE_UTF8 | (strchr(opts, 'D') ? 0:PCRE_CASELESS), - &errptr, - &errindex, 0); + pcre_regexp=pcre2_compile((PCRE2_SPTR8)expr, + PCRE2_ZERO_TERMINATED, + PCRE2_UTF | (strchr(opts, 'D') ? 0:PCRE2_CASELESS), + &errcode, + &errindex, + NULL); if (!pcre_regexp) { Buffer b; + PCRE2_UCHAR buffer[256]; + pcre2_get_error_message(errcode, buffer, sizeof(buffer)); + b="Invalid regular expression, offset "; b.append((unsigned long)errindex); b += " of: "; b += expr; b += ": "; - b += errptr; + b += (char *)buffer; b += "\n"; b += '\0'; merr.write(b); return -1; } - pcre_regexp_extra=pcre_study(pcre_regexp, 0, &errptr); + match_data= pcre2_match_data_create_from_pattern( + pcre_regexp, NULL + ); - if (errptr) + if (!match_data) { Buffer b; - b="Error parsing regular expression: "; + b="Failed to create match data for: "; b += expr; - b += ": "; - b += errptr; b += "\n"; b += '\0'; merr.write(b); + cleanup(); return -1; } - search_expr=expr; - int cnt=0; - - pcre_fullinfo(pcre_regexp, pcre_regexp_extra, - PCRE_INFO_CAPTURECOUNT, &cnt); - - pcre_vector_count=(cnt+1)*3; - - pcre_vectors=(int *)malloc(pcre_vector_count*sizeof(int)); - - if (!pcre_vectors) - { - Buffer b; - - b=strerror(errno); - b += "\n"; - b += '\0'; - merr.write(b); - return -1; - } while (*opts) { @@ -166,30 +147,40 @@ int Search::find(const char *str, const char *expr, const char *opts, int startoffset=0; const char *orig_str=str; - int match_count=0; for (;;) { - match_count=pcre_exec(pcre_regexp, pcre_regexp_extra, - orig_str, strlen(orig_str), - startoffset, - 0, - pcre_vectors, - pcre_vector_count); - if (match_count <= 0) + int rc=pcre2_match(pcre_regexp, + (PCRE2_SPTR8)orig_str, + strlen(orig_str), + startoffset, + 0, + match_data, + NULL); + + if (rc < 0 ) break; - startoffset=pcre_vectors[1]; + + + PCRE2_SIZE *ovector=pcre2_get_ovector_pointer(match_data); + uint32_t ovector_count=pcre2_get_ovector_count(match_data); score += weight1; weight1 *= weight2; if (!scoring_match || foreachp) { - init_match_vars(orig_str, match_count, - pcre_vectors, foreachp); + init_match_vars(orig_str, ovector, ovector_count, + foreachp); if (!foreachp) break; } + + if (!ovector || ovector_count <= 0) + break; + + startoffset=ovector[1]; + } return (0); } @@ -263,27 +254,32 @@ int Search::search_cb(const char *ptr, size_t cnt) } const char *orig_str=current_line; - int match_count; - - match_count=pcre_exec(pcre_regexp, - pcre_regexp_extra, - orig_str, - strlen(orig_str), - 0, - 0, - pcre_vectors, - pcre_vector_count); - - if (match_count > 0) + + int rc=pcre2_match(pcre_regexp, + (PCRE2_SPTR8)orig_str, + strlen(orig_str), + 0, + 0, + match_data, + NULL); + + if (rc >= 0) { score += weight1; weight1 *= weight2; if (!scoring_match || foreachp_arg) { + PCRE2_SIZE *ovector= + pcre2_get_ovector_pointer( + match_data); + uint32_t ovector_count= + pcre2_get_ovector_count( + match_data); + init_match_vars(orig_str, - match_count, - pcre_vectors, + ovector, + ovector_count, foreachp_arg); if (!foreachp_arg) // Stop searching now @@ -311,11 +307,16 @@ int Search::search_cb(const char *ptr, size_t cnt) return (0); } -void Search::init_match_vars(const char *str, int nranges, int *offsets, +void Search::init_match_vars(const char *str, + PCRE2_SIZE *offsets, + uint32_t nranges, Buffer *foreachp) { Buffer varname; - int cnt; + uint32_t cnt; + + if (!offsets) + return; for (cnt=0; cnt<nranges; cnt++) { diff --git a/maildrop/search.h b/maildrop/search.h index 681c082..963ea8c 100644 --- a/maildrop/search.h +++ b/maildrop/search.h @@ -4,11 +4,9 @@ #include "buffer.h" -#if HAVE_PCRE_H -#include <pcre.h> -#else -#include <pcre/pcre.h> -#endif +#define PCRE2_CODE_UNIT_WIDTH 8 + +#include <pcre2.h> //////////////////////////////////////////////////////////////////////////// // @@ -42,10 +40,8 @@ class Message; class Search { - pcre *pcre_regexp; - pcre_extra *pcre_regexp_extra; - int *pcre_vectors; - size_t pcre_vector_count; + pcre2_code *pcre_regexp; + pcre2_match_data *match_data; Buffer current_line; Buffer next_line; @@ -62,8 +58,8 @@ public: double score; // For weighted scoring. Without scoring, this is // either 0, or 1. - Search() : pcre_regexp(NULL), pcre_regexp_extra(NULL), - pcre_vectors(NULL) {} + Search() : pcre_regexp(NULL), + match_data(NULL) {} ~Search() { cleanup(); } int find(Message &, MessageInfo &, const char *, const char *, Buffer *); @@ -71,8 +67,10 @@ public: private: int findinline(Message &, const char *, Buffer *); int findinsection(Message &, const char *, Buffer *); - void init_match_vars(const char *, int, int *, Buffer *); - + void init_match_vars(const char *, + PCRE2_SIZE *, + uint32_t, + Buffer *); Buffer search_expr; Buffer *foreachp_arg; static int search_cb(const char *ptr, size_t cnt, void *arg); |
