diff --git a/configure.ac b/configure.ac index e273db91..4df941e9 100644 --- a/configure.ac +++ b/configure.ac @@ -715,18 +715,39 @@ AS_IF([test "x$uuid_mode" = x1], [ ]) dnl -dnl Check for PCRE +dnl Check for PCRE2 / PCRE dnl +AC_ARG_ENABLE(pcre2, AC_HELP_STRING([--disable-pcre2], + [Disable PCRE2 style regular expressions])) AC_ARG_ENABLE(pcre, AC_HELP_STRING([--disable-pcre], [Disable PCRE style regular expressions])) -AS_IF([test "X$enable_pcre" != "Xno"],[ +AS_IF([test "X$enable_pcre2" != "Xno"],[ + enable_pcre2=no + PKG_CHECK_MODULES([PCRE2], libpcre2-8, [ + CFLAGS="$PCRE2_CFLAGS $CFLAGS" + LIBS="$PCRE2_LIBS $LIBS" + AC_DEFINE([HAVE_LIBPCRE2], [1], [Define if libpcre2 is available.]) + enable_pcre2=yes + ], [ + AC_CHECK_HEADER(pcre2.h, [ + AC_CHECK_LIB(pcre2-8, pcre2_compile_8, [ + LIBS="${LIBS} -lpcre2-8" + AC_DEFINE([HAVE_LIBPCRE2], 1, [Define if libpcre2 is available.]) + enable_pcre2=yes + ]) + ]) + ]) +]) + +AS_IF([test "X$enable_pcre" != "Xno" && test "X$enable_pcre2" != "Xyes"],[ PKG_CHECK_MODULES([PCRE], libpcre, [ CFLAGS="$PCRE_CFLAGS $CFLAGS" AC_CHECK_HEADER(pcre.h, [ LIBS="$PCRE_LIBS $LIBS" AC_DEFINE([HAVE_LIBPCRE], [1], [Define if libpcre is available.]) + enable_pcre=yes ]) ], [ AC_CHECK_HEADER(pcre.h, [ @@ -738,6 +759,8 @@ AS_IF([test "X$enable_pcre" != "Xno"],[ ]) ]) +AS_IF([test "X$enable_pcre2" = Xyes], [PCRE_INFO="yes, via libpcre2"], [test "X$enable_pcre" = Xyes], [PCRE_INFO="yes, via libpcre"], [PCRE_INFO=no]) + dnl dnl Check for libcares (resolver library) dnl @@ -817,6 +840,7 @@ AC_MSG_NOTICE([Summary of build options: SSL: $with_ssl Zlib: $with_zlib PSL: $with_libpsl + PCRE: $PCRE_INFO Digest: $ENABLE_DIGEST NTLM: $ENABLE_NTLM OPIE: $ENABLE_OPIE diff --git a/src/init.c b/src/init.c index bb82b329..2fac8ae9 100644 --- a/src/init.c +++ b/src/init.c @@ -47,9 +47,6 @@ as that of the covered work. */ #endif #include -#ifdef HAVE_LIBPCRE -# include -#endif #ifdef HAVE_PWD_H # include @@ -1636,7 +1633,7 @@ cmd_spec_regex_type (const char *com, const char *val, void *place_ignored _GL_U { static const struct decode_item choices[] = { { "posix", regex_type_posix }, -#ifdef HAVE_LIBPCRE +#if defined HAVE_LIBPCRE || defined HAVE_LIBPCRE2 { "pcre", regex_type_pcre }, #endif }; diff --git a/src/main.c b/src/main.c index e731f3aa..ff41c8d9 100644 --- a/src/main.c +++ b/src/main.c @@ -995,7 +995,7 @@ Recursive accept/reject:\n"), --accept-regex=REGEX regex matching accepted URLs\n"), N_("\ --reject-regex=REGEX regex matching rejected URLs\n"), -#ifdef HAVE_LIBPCRE +#if defined HAVE_LIBPCRE || defined HAVE_LIBPCRE2 N_("\ --regex-type=TYPE regex type (posix|pcre)\n"), #else @@ -1784,6 +1784,12 @@ for details.\n\n")); /* Compile the regular expressions. */ switch (opt.regex_type) { +#ifdef HAVE_LIBPCRE2 + case regex_type_pcre: + opt.regex_compile_fun = compile_pcre2_regex; + opt.regex_match_fun = match_pcre2_regex; + break; +#endif #ifdef HAVE_LIBPCRE case regex_type_pcre: opt.regex_compile_fun = compile_pcre_regex; diff --git a/src/options.h b/src/options.h index 19d93f14..c3c2a2cf 100644 --- a/src/options.h +++ b/src/options.h @@ -92,7 +92,7 @@ struct options void *acceptregex; /* Patterns to accept (a regex struct). */ void *rejectregex; /* Patterns to reject (a regex struct). */ enum { -#ifdef HAVE_LIBPCRE +#if defined HAVE_LIBPCRE || HAVE_LIBPCRE2 regex_type_pcre, #endif regex_type_posix diff --git a/src/utils.c b/src/utils.c index c6258083..2289a47d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -68,7 +68,10 @@ as that of the covered work. */ #include #include -#ifdef HAVE_LIBPCRE +#ifdef HAVE_LIBPCRE2 +# define PCRE2_CODE_UNIT_WIDTH 8 +# include +#elif defined HAVE_LIBPCRE # include #endif @@ -2429,6 +2432,23 @@ wget_base64_decode (const char *base64, void *dest, size_t size) return n; } +#ifdef HAVE_LIBPCRE2 +/* Compiles the PCRE2 regex. */ +void * +compile_pcre2_regex (const char *str) +{ + int errornumber; + PCRE2_SIZE erroroffset; + pcre2_code *regex = pcre2_compile((PCRE2_SPTR) str, PCRE2_ZERO_TERMINATED, 0, &errornumber, &erroroffset, NULL); + if (! regex) + { + fprintf (stderr, _("Invalid regular expression %s, PCRE2 error %d\n"), + quote (str), errornumber); + } + return regex; +} +#endif + #ifdef HAVE_LIBPCRE /* Compiles the PCRE regex. */ void * @@ -2441,7 +2461,6 @@ compile_pcre_regex (const char *str) { fprintf (stderr, _("Invalid regular expression %s, %s\n"), quote (str), errbuf); - return false; } return regex; } @@ -2473,6 +2492,34 @@ compile_posix_regex (const char *str) return regex; } +#ifdef HAVE_LIBPCRE2 +/* Matches a PCRE2 regex. */ +bool +match_pcre2_regex (const void *regex, const char *str) +{ + int rc; + pcre2_match_data *match_data; + + match_data = pcre2_match_data_create_from_pattern(regex, NULL); + + if (match_data) + { + rc = pcre2_match(regex, (PCRE2_SPTR) str, strlen(str), 0, 0, match_data, NULL); + pcre2_match_data_free(match_data); + } + else + rc = PCRE2_ERROR_NOMEMORY; + + if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) + { + logprintf (LOG_VERBOSE, _("Error while matching %s: %d\n"), + quote (str), rc); + } + + return rc >= 0; +} +#endif + #ifdef HAVE_LIBPCRE #define OVECCOUNT 30 /* Matches a PCRE regex. */ diff --git a/src/utils.h b/src/utils.h index d55da2a7..7c0e7675 100644 --- a/src/utils.h +++ b/src/utils.h @@ -150,6 +150,11 @@ void xsleep (double); size_t wget_base64_encode (const void *, size_t, char *); ssize_t wget_base64_decode (const char *, void *, size_t); +#ifdef HAVE_LIBPCRE2 +void *compile_pcre2_regex (const char *); +bool match_pcre2_regex (const void *, const char *); +#endif + #ifdef HAVE_LIBPCRE void *compile_pcre_regex (const char *); bool match_pcre_regex (const void *, const char *);