initial support for PCRE2

This commit is contained in:
cathugger 2018-01-20 19:55:45 +00:00
parent bc76dc4331
commit e32e8e06f6
3 changed files with 158 additions and 17 deletions

View file

@ -141,7 +141,7 @@ case "$enable_intfilter" in
native) native)
intfiltertype="size_t" intfiltertype="size_t"
;; ;;
no) no|"")
intfiltertype="" intfiltertype=""
;; ;;
*) *)
@ -235,6 +235,43 @@ then
MYDEFS="$MYDEFS -DSTATISTICS" MYDEFS="$MYDEFS -DSTATISTICS"
fi fi
AC_ARG_WITH([pcre2],[AC_HELP_STRING([--with-pcre2],[pcre2-config executable @<:@default=pcre2@:>@])],[],[with_pcre2="pcre2-config"])
AC_ARG_ENABLE([regex],[AC_HELP_STRING([--enable-regex],[whether to enable regex engine. currently possible values are "pcre2" and "yes" which defaults to "pcre2" @<:@default=no@:>@])],[],[enable_regex=no])
case "$enable_regex" in
no|"")
;;
yes|pcre2)
AC_MSG_CHECKING([pcre2])
V=""
if test "$with_pcre2" != "yes"
then
V=`"$with_pcre2" --version 2>/dev/null`
fi
if test -n "$V"
then
AC_MSG_RESULT([$V])
MYDEFS="$MYDEFS -DPCRE2FILTER"
CF=`"$with_pcre2" --cflags`
if test -n "$CF"
then
CFLAGS="$CFLAGS $CF"
fi
LF=`"$with_pcre2" --libs8`
if test -n "$LF"
then
LDFLAGS="$LDFLAGS $LF"
fi
else
AC_MSG_RESULT([not found])
AC_ERROR([pcre2-config cannot be executed])
fi
;;
*)
AC_MSG_WARN([unrecognised regex engine type: $enable_regex])
;;
esac
AC_SUBST(CSTD,["$cstd"]) AC_SUBST(CSTD,["$cstd"])
AC_SUBST(ED25519IMPL,["$ed25519impl"]) AC_SUBST(ED25519IMPL,["$ed25519impl"])
AC_SUBST(MYDEFS,["$MYDEFS"]) AC_SUBST(MYDEFS,["$MYDEFS"])

129
filters.h
View file

@ -4,6 +4,11 @@
# define BINFILTER # define BINFILTER
#endif #endif
#ifdef PCRE2FILTER
# undef BINFILTER
# undef INTFILTER
#endif
#ifdef INTFILTER #ifdef INTFILTER
# ifdef BINSEARCH # ifdef BINSEARCH
# ifndef BESORT # ifndef BESORT
@ -51,9 +56,22 @@ struct intfilter {
VEC_STRUCT(ifiltervec,struct intfilter) filters; VEC_STRUCT(ifiltervec,struct intfilter) filters;
# ifdef OMITMASK # ifdef OMITMASK
IFT ifiltermask; IFT ifiltermask;
# endif // BINSEARCH # endif
#endif // INTFILTER #endif // INTFILTER
#ifdef PCRE2FILTER
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
struct pcre2filter {
char *str;
pcre2_code *re;
} ;
VEC_STRUCT(pfiltervec,struct pcre2filter) filters;
#endif // PCRE2FILTER
static void filters_init() static void filters_init()
{ {
VEC_INIT(filters); VEC_INIT(filters);
@ -291,16 +309,24 @@ static void filter_sort(void)
#endif // BINFILTER #endif // BINFILTER
#ifdef PCRE2FILTER
static size_t filter_len(size_t i)
{
return 0;
}
#endif // PCRE2FILTER
static void filters_add(const char *filter) static void filters_add(const char *filter)
{ {
#ifdef NEEDBINFILTER
struct binfilter bf; struct binfilter bf;
size_t ret; size_t ret;
#ifdef INTFILTER # ifdef INTFILTER
union intconv { union intconv {
IFT i; IFT i;
u8 b[sizeof(IFT)]; u8 b[sizeof(IFT)];
} fc,mc; } fc,mc;
#endif # endif
// skip regex start symbol. we do not support regex tho // skip regex start symbol. we do not support regex tho
if (*filter == '^') if (*filter == '^')
@ -319,11 +345,11 @@ static void filters_add(const char *filter)
ret = BASE32_FROM_LEN(ret); ret = BASE32_FROM_LEN(ret);
if (!ret) if (!ret)
return; return;
#ifdef INTFILTER # ifdef INTFILTER
size_t maxsz = sizeof(IFT); size_t maxsz = sizeof(IFT);
#else # else
size_t maxsz = sizeof(bf.f); size_t maxsz = sizeof(bf.f);
#endif # endif
if (ret > maxsz) { if (ret > maxsz) {
fprintf(stderr,"filter \"%s\" is too long\n",filter); fprintf(stderr,"filter \"%s\" is too long\n",filter);
fprintf(stderr," "); fprintf(stderr," ");
@ -336,7 +362,7 @@ static void filters_add(const char *filter)
base32_from(bf.f,&bf.mask,filter); base32_from(bf.f,&bf.mask,filter);
bf.len = ret - 1; bf.len = ret - 1;
#ifdef INTFILTER # ifdef INTFILTER
mc.i = 0; mc.i = 0;
for (size_t i = 0;i < bf.len;++i) for (size_t i = 0;i < bf.len;++i)
mc.b[i] = 0xFF; mc.b[i] = 0xFF;
@ -345,29 +371,58 @@ static void filters_add(const char *filter)
fc.i &= mc.i; fc.i &= mc.i;
struct intfilter ifltr = { struct intfilter ifltr = {
.f = fc.i, .f = fc.i,
# ifndef OMITMASK # ifndef OMITMASK
.m = mc.i, .m = mc.i,
# endif # endif
}; };
# ifdef OMITMASK # ifdef OMITMASK
ifilter_addflatten(&ifltr,mc.i); ifilter_addflatten(&ifltr,mc.i);
# else // OMITMASK # else // OMITMASK
VEC_ADD(filters,ifltr); VEC_ADD(filters,ifltr);
# endif // OMITMASK # endif // OMITMASK
#endif // INTFILTER # endif // INTFILTER
#ifdef BINFILTER # ifdef BINFILTER
VEC_ADD(filters,bf); VEC_ADD(filters,bf);
#endif // BINFILTER # endif // BINFILTER
#endif // NEEDBINFILTER
#ifdef PCRE2FILTER
int errornum;
PCRE2_SIZE erroroffset;
pcre2_code *re;
re = pcre2_compile((PCRE2_SPTR8)filter,PCRE2_ZERO_TERMINATED,0,&errornum,&erroroffset,0);
if (!re) {
PCRE2_UCHAR buffer[1024];
pcre2_get_error_message(errornum,buffer,sizeof(buffer));
fprintf(stderr,"PCRE2 compilation failed at offset %zu: %s\n",
(size_t)erroroffset,buffer);
return;
}
// attempt to JIT. ignore error
(void)pcre2_jit_compile(re,PCRE2_JIT_COMPLETE);
struct pcre2filter f;
memset(&f,0,sizeof(f));
f.re = re;
size_t fl = strlen(filter) + 1;
f.str = malloc(fl);
if (!f.str)
abort();
memcpy(f.str,filter,fl);
VEC_ADD(filters,f);
#endif // PCRE2FILTER
} }
#ifdef NEEDBINFILTER
static void filters_dedup() static void filters_dedup()
{ {
//TODO //TODO
} }
#endif // NEEDBINFILTER
static void filters_prepare() static void filters_prepare()
{ {
#ifndef PCRE2FILTER
if (!quietflag) if (!quietflag)
fprintf(stderr,"sorting filters..."); fprintf(stderr,"sorting filters...");
filter_sort(); filter_sort();
@ -378,10 +433,17 @@ static void filters_prepare()
} }
if (!quietflag) if (!quietflag)
fprintf(stderr," done.\n"); fprintf(stderr," done.\n");
#endif
} }
static void filters_clean() static void filters_clean()
{ {
#ifdef PCRE2FILTER
for (size_t i = 0;i < VEC_LENGTH(filters);++i) {
pcre2_code_free(VEC_BUF(filters,i).re);
free(VEC_BUF(filters,i).str);
}
#endif
VEC_FREE(filters); VEC_FREE(filters);
} }
@ -450,6 +512,9 @@ do { \
# endif // BINSEARCH # endif // BINSEARCH
#define PREFILTER
#define POSTFILTER
#endif // INTFILTER #endif // INTFILTER
@ -509,9 +574,36 @@ do { \
# endif // BINSEARCH # endif // BINSEARCH
#define PREFILTER
#define POSTFILTER
#endif // BINFILTER #endif // BINFILTER
#ifdef PCRE2FILTER
#define PREFILTER \
char pkconvbuf[BASE32_TO_LEN(PUBLIC_LEN) + 1]; \
pcre2_match_data *pcre2md = pcre2_match_data_create(128,0);
#define POSTFILTER \
pcre2_match_data_free(pcre2md);
#define DOFILTER(it,pk,code) \
do { \
base32_to(pkconvbuf,pk,PUBLIC_LEN); \
size_t __l = VEC_LENGTH(filters); \
for (it = 0;it < __l;++it) { \
int rc = pcre2_match(VEC_BUF(filters,it).re,(PCRE2_SPTR8)pkconvbuf,BASE32_TO_LEN(PUBLIC_LEN),0,0,pcre2md,0); \
if (unlikely(rc >= 0)) { \
code; \
break; \
} \
} \
} while (0)
#endif // PCRE2FILTER
static void loadfilterfile(const char *fname) static void loadfilterfile(const char *fname)
{ {
@ -539,8 +631,10 @@ static void filters_print()
fprintf(stderr,"filters:\n"); fprintf(stderr,"filters:\n");
for (i = 0;i < l;++i) { for (i = 0;i < l;++i) {
#ifdef NEEDBINFILTER
char buf0[256],buf1[256]; char buf0[256],buf1[256];
u8 bufx[128]; u8 bufx[128];
#endif
if (i >= 20) { if (i >= 20) {
size_t notshown = l - i; size_t notshown = l - i;
@ -568,6 +662,7 @@ static void filters_print()
u8 mask = VEC_BUF(filters,i).mask; u8 mask = VEC_BUF(filters,i).mask;
u8 *ifraw = VEC_BUF(filters,i).f; u8 *ifraw = VEC_BUF(filters,i).f;
#endif // BINFILTER #endif // BINFILTER
#ifdef NEEDBINFILTER
base32_to(buf0,ifraw,len); base32_to(buf0,ifraw,len);
memcpy(bufx,ifraw,len); memcpy(bufx,ifraw,len);
bufx[len - 1] |= ~mask; bufx[len - 1] |= ~mask;
@ -577,6 +672,10 @@ static void filters_print()
++a, ++b; ++a, ++b;
*a = 0; *a = 0;
fprintf(stderr,"\t%s\n",buf0); fprintf(stderr,"\t%s\n",buf0);
#endif // NEEDBINFILTER
#ifdef PCRE2FILTER
fprintf(stderr,"\t%s\n",VEC_BUF(filters,i).str);
#endif // PCRE2FILTER
} }
fprintf(stderr,"in total, %zu %s\n",l,l == 1 ? "filter" : "filters"); fprintf(stderr,"in total, %zu %s\n",l,l == 1 ? "filter" : "filters");
} }

7
main.c
View file

@ -33,7 +33,8 @@ static char *workdir = 0;
static size_t workdirlen = 0; static size_t workdirlen = 0;
static int quietflag = 0; static int quietflag = 0;
static int wantdedup = 0; //static int wantdedup = 0;
#define wantdedup 0
#define SECRET_LEN 64 #define SECRET_LEN 64
#define PUBLIC_LEN 32 #define PUBLIC_LEN 32
@ -199,6 +200,7 @@ static void *dowork(void *task)
#ifdef STATISTICS #ifdef STATISTICS
struct statstruct *st = (struct statstruct *)task; struct statstruct *st = (struct statstruct *)task;
#endif #endif
PREFILTER
memcpy(secret,skprefix,skprefixlen); memcpy(secret,skprefix,skprefixlen);
wpk[PUBLIC_LEN] = 0; wpk[PUBLIC_LEN] = 0;
@ -267,6 +269,7 @@ next:
end: end:
free(sname); free(sname);
POSTFILTER
return 0; return 0;
} }
@ -304,6 +307,7 @@ static void *dofastwork(void *task)
#ifdef STATISTICS #ifdef STATISTICS
struct statstruct *st = (struct statstruct *)task; struct statstruct *st = (struct statstruct *)task;
#endif #endif
PREFILTER
memcpy(secret, skprefix, skprefixlen); memcpy(secret, skprefix, skprefixlen);
wpk[PUBLIC_LEN] = 0; wpk[PUBLIC_LEN] = 0;
@ -381,6 +385,7 @@ initseed:
end: end:
free(sname); free(sname);
POSTFILTER
return 0; return 0;
} }