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); | 
