From: Nick Porter Date: Thu, 24 Jul 2025 17:35:31 +0000 (+0100) Subject: All supported platforms have libpcre2 available X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77d23dfb7d52ac8f7b61580e22875c9faeb3097c;p=thirdparty%2Ffreeradius-server.git All supported platforms have libpcre2 available So remove libpcre code --- diff --git a/configure b/configure index 082af199d1..ae8ec038be 100755 --- a/configure +++ b/configure @@ -15287,426 +15287,6 @@ printf "%s\n" "#define HAVE_REGEX_PCRE2 1" >>confdefs.h printf "%s\n" "#define HAVE_BINSAFE_REGEX 1" >>confdefs.h fi - fi - - if test "x$REGEX" != "xyes"; then - - -ac_safe=`echo "pcre.h" | sed 'y%./+-%__pm%'` - -if test "x" = "x"; then - sm_pkg=`echo "${ac_safe}" | sed 's/.h//;s/^lib//'` -else - sm_pkg="" -fi - -old_CPPFLAGS="$CPPFLAGS" -smart_include_dir="/usr/local/include /opt/include /usr/local/${sm_pkg}/include /opt/homebrew/include /opt/homebrew/opt/${sm_pkg}/include" - -_smart_try_dir= -_smart_include_dir= - -for _prefix in $smart_prefix ""; do -for _dir in $smart_try_dir; do - _smart_try_dir="${_smart_try_dir} ${_dir}/${_prefix}" -done - -for _dir in $smart_include_dir; do - _smart_include_dir="${_smart_include_dir} ${_dir}/${_prefix}" -done -done - -if test "x$_smart_try_dir" != "x"; then -for try in $_smart_try_dir; do - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pcre.h in $try" >&5 -printf %s "checking for pcre.h in $try... " >&6; } - CPPFLAGS="-isystem $try $old_CPPFLAGS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - -int -main (void) -{ - - int a = 1; - - - ; - return 0; -} - -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - - smart_include="-isystem $try" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - break - -else case e in #( - e) - smart_include= - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -done -CPPFLAGS="$old_CPPFLAGS" -fi - -if test "x$smart_include" = "x"; then -for _prefix in $smart_prefix; do - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${_prefix}/pcre.h" >&5 -printf %s "checking for ${_prefix}/pcre.h... " >&6; } - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - -int -main (void) -{ - - int a = 1; - - - ; - return 0; -} - -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - - smart_include="-isystem ${_prefix}/" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - break - -else case e in #( - e) - smart_include= - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -done -fi - -if test "x$smart_include" = "x"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pcre.h" >&5 -printf %s "checking for pcre.h... " >&6; } - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - -int -main (void) -{ - - int a = 1; - - - ; - return 0; -} - -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - - smart_include=" " - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - break - -else case e in #( - e) - smart_include= - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -if test "x$smart_include" = "x"; then -for try in $_smart_include_dir; do - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pcre.h in $try" >&5 -printf %s "checking for pcre.h in $try... " >&6; } - CPPFLAGS="-isystem $try $old_CPPFLAGS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - -int -main (void) -{ - - int a = 1; - - - ; - return 0; -} - -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - - smart_include="-isystem $try" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - break - -else case e in #( - e) - smart_include= - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -done -CPPFLAGS="$old_CPPFLAGS" -fi - -if test "x$smart_include" != "x"; then -eval "ac_cv_header_$ac_safe=yes" -CPPFLAGS="$smart_include $old_CPPFLAGS" -SMART_CPPFLAGS="$smart_include $SMART_CPPFLAGS" -fi - -smart_prefix= - - if test "x$ac_cv_header_pcre_h" = "xyes"; then - smart_try_dir=$pcre_lib_dir - - -sm_lib_safe=`echo "pcre" | sed 'y%./+-%__p_%'` -sm_func_safe=`echo "pcre_compile" | sed 'y%./+-%__p_%'` - -if test "x" = "x"; then - sm_pkg="${sm_lib_safe}" -else - sm_pkg="" -fi - -old_LIBS="$LIBS" -old_CPPFLAGS="$CPPFLAGS" -smart_lib= -smart_ldflags= -smart_lib_dir="/usr/local/lib /opt/lib /usr/local/${sm_pkg}/lib /opt/homebrew/lib /opt/homebrew/opt/${sm_pkg}/lib" - -if test "x$smart_try_dir" != "x"; then -for try in $smart_try_dir; do - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pcre_compile in -lpcre in $try" >&5 -printf %s "checking for pcre_compile in -lpcre in $try... " >&6; } - LIBS="-lpcre $old_LIBS" - CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -extern char pcre_compile(); -int -main (void) -{ -pcre_compile() - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - - smart_lib="-lpcre" - smart_ldflags="-L$try -Wl,-rpath,$try" - smart_ld_found="$try" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - break - -else case e in #( - e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -done -LIBS="$old_LIBS" -CPPFLAGS="$old_CPPFLAGS" -fi - -if test "x$smart_lib" = "x"; then -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pcre_compile in -lpcre" >&5 -printf %s "checking for pcre_compile in -lpcre... " >&6; } -LIBS="-lpcre $old_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -extern char pcre_compile(); -int -main (void) -{ -pcre_compile() - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - - smart_lib="-lpcre" - smart_ld_found="" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - -else case e in #( - e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS="$old_LIBS" -fi - -if test "x$smart_lib" = "x"; then -for try in $smart_lib_dir; do - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pcre_compile in -lpcre in $try" >&5 -printf %s "checking for pcre_compile in -lpcre in $try... " >&6; } - LIBS="-lpcre $old_LIBS" - CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -extern char pcre_compile(); -int -main (void) -{ -pcre_compile() - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - - smart_lib="-lpcre" - smart_ldflags="-L$try -Wl,-rpath,$try" - smart_ld_found="$try" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - break - -else case e in #( - e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -done -LIBS="$old_LIBS" -CPPFLAGS="$old_CPPFLAGS" -fi - -if test "x$smart_lib" != "x"; then -eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes" -LIBS="$smart_ldflags $smart_lib $old_LIBS" -SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS" -SMART_LD_FOUND="$smart_ld_found" -fi - - if test "x$ac_cv_lib_pcre_pcre_compile" = "xyes"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking libpcre library and header version consistency" >&5 -printf %s "checking libpcre library and header version consistency... " >&6; } - if test "$cross_compiling" = yes -then : - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cross-compiling (assuming yes)" >&5 -printf "%s\n" "cross-compiling (assuming yes)" >&6; } - - -else case e in #( - e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - #include - #include - #define XSTRINGIFY(x) #x - #define STRINGIFY(x) XSTRINGIFY(x) - -int -main (void) -{ - - char const *p = pcre_version(); - char *q; - unsigned long ver; - - printf("library: %s header: %u.%u %s... ", p, PCRE_MAJOR, PCRE_MINOR, STRINGIFY(PCRE_DATE)); - - ver = strtoul(p, &q, 10); - if (*q != '.') return 1; - if (ver != PCRE_MAJOR) return 65; - p = ++q; - - ver = strtoul(p, &q, 10); - if (ver != PCRE_MINOR) return 1; - - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - REGEX=yes - -printf "%s\n" "#define HAVE_REGEX_PCRE 1" >>confdefs.h - - -printf "%s\n" "#define HAVE_BINSAFE_REGEX 1" >>confdefs.h - - -else case e in #( - e) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} -as_fn_error $? "libpcre library version does not match header version -See 'config.log' for more details" "$LINENO" 5; } - ;; -esac -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext ;; -esac -fi - - fi - fi fi fi diff --git a/configure.ac b/configure.ac index 5b5b9f6a98..754d4c52f1 100644 --- a/configure.ac +++ b/configure.ac @@ -2249,7 +2249,7 @@ if test "x$WITH_REGEX" != "xno" && test "x$WITH_PCRE" != "xno"; then smart_try_dir=$pcre_include_dir dnl # - dnl # Prefer libpcre2 over libpcre + dnl # Check for libpcre2 dnl # FR_SMART_CHECK_INCLUDE(pcre2.h,[#define PCRE2_CODE_UNIT_WIDTH (8)]) if test "x$ac_cv_header_pcre2_h" = "xyes"; then @@ -2261,59 +2261,6 @@ if test "x$WITH_REGEX" != "xno" && test "x$WITH_PCRE" != "xno"; then AC_DEFINE(HAVE_BINSAFE_REGEX, 1, [Define if we have a binary safe regular expression library]) fi fi - - dnl # - dnl # Fallback to libpcre - dnl # - if test "x$REGEX" != "xyes"; then - FR_SMART_CHECK_INCLUDE(pcre.h) - if test "x$ac_cv_header_pcre_h" = "xyes"; then - smart_try_dir=$pcre_lib_dir - FR_SMART_CHECK_LIB(pcre, pcre_compile) - if test "x$ac_cv_lib_pcre_pcre_compile" = "xyes"; then - AC_MSG_CHECKING([libpcre library and header version consistency]) - AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[ - #include - #include - #include - #define XSTRINGIFY(x) #x - #define STRINGIFY(x) XSTRINGIFY(x) - ]], - [[ - char const *p = pcre_version(); - char *q; - unsigned long ver; - - printf("library: %s header: %u.%u %s... ", p, PCRE_MAJOR, PCRE_MINOR, STRINGIFY(PCRE_DATE)); - - ver = strtoul(p, &q, 10); - if (*q != '.') return 1; - if (ver != PCRE_MAJOR) return 65; - p = ++q; - - ver = strtoul(p, &q, 10); - if (ver != PCRE_MINOR) return 1; - ]] - )], - [ - AC_MSG_RESULT(yes) - REGEX=yes - AC_DEFINE(HAVE_REGEX_PCRE, [1], [define this if we have libpcre]) - AC_DEFINE(HAVE_BINSAFE_REGEX, 1, [Define if we have a binary safe regular expression library]) - ], - [ - AC_MSG_RESULT(no) - AC_MSG_FAILURE([libpcre library version does not match header version]) - ], - [ - AC_MSG_RESULT([cross-compiling (assuming yes)]) - ] - ) - fi - fi - fi fi dnl # diff --git a/src/include/autoconf.h.in b/src/include/autoconf.h.in index 808e76065c..f78c2ca3f2 100644 --- a/src/include/autoconf.h.in +++ b/src/include/autoconf.h.in @@ -362,9 +362,6 @@ /* Define if we have any regular expression library */ #undef HAVE_REGEX -/* define this if we have libpcre */ -#undef HAVE_REGEX_PCRE - /* define this if we have libpcre2 */ #undef HAVE_REGEX_PCRE2 diff --git a/src/lib/server/dependency.c b/src/lib/server/dependency.c index ccdf9a8215..f7d4a46a6e 100644 --- a/src/lib/server/dependency.c +++ b/src/lib/server/dependency.c @@ -192,14 +192,6 @@ void dependency_features_init(CONF_SECTION *cs) #endif ); - dependency_feature_add(cs, "regex-pcre", -#ifdef HAVE_REGEX_PCRE - true -#else - false -#endif - ); - dependency_feature_add(cs, "regex-pcre2", #ifdef HAVE_REGEX_PCRE2 true @@ -223,7 +215,7 @@ void dependency_features_init(CONF_SECTION *cs) #endif dependency_feature_add(cs, "regex-binsafe", -#if defined(HAVE_REGNEXEC) || defined(HAVE_REGEX_PCRE) || defined(HAVE_REGEX_PCRE2) +#if defined(HAVE_REGNEXEC) || defined(HAVE_REGEX_PCRE2) true #else false @@ -357,8 +349,6 @@ void dependency_version_numbers_init(CONF_SECTION *cs) # ifdef HAVE_REGEX_PCRE2 snprintf(buffer, sizeof(buffer), "%i.%i (%s) - retrieved at build time", PCRE2_MAJOR, PCRE2_MINOR, STRINGIFY(PCRE2_DATE)); dependency_version_number_add(cs, "pcre2", buffer); -# elif defined(HAVE_REGEX_PCRE) - dependency_version_number_add(cs, "pcre", pcre_version()); # endif #endif diff --git a/src/lib/server/regex.c b/src/lib/server/regex.c index 139649ce6f..47ee33a0c4 100644 --- a/src/lib/server/regex.c +++ b/src/lib/server/regex.c @@ -34,7 +34,7 @@ RCSID("$Id$") #define REQUEST_DATA_REGEX (0xadbeef00) typedef struct { -#if defined(HAVE_REGEX_PCRE) || defined(HAVE_REGEX_PCRE2) +#if defined(HAVE_REGEX_PCRE2) regex_t *preg; //!< Compiled pattern. #endif fr_regmatch_t *regmatch; //!< Match vectors. @@ -89,7 +89,7 @@ void regex_sub_to_request(request_t *request, regex_t **preg, fr_regmatch_t **re /* * Steal runtime pregs, leave precompiled ones */ -#if defined(HAVE_REGEX_PCRE) || defined(HAVE_REGEX_PCRE2) +#if defined(HAVE_REGEX_PCRE2) if (!(*preg)->precompiled) { new_rc->preg = talloc_steal(new_rc, *preg); *preg = NULL; @@ -227,121 +227,6 @@ int regex_request_to_sub_named(TALLOC_CTX *ctx, fr_value_box_t *out, request_t * return 0; } -# elif defined(HAVE_REGEX_PCRE) -/** Extract a subcapture value from the request - * - * @note This is the PCRE variant of the function. - * - * @param[in] ctx To allocate subcapture buffer in. - * @param[out] out Where to write the subcapture string. - * @param[in] request to extract. - * @param[in] num Subcapture index (0 for entire match). - * @return - * - 0 on success. - * - -1 on notfound. - */ -int regex_request_to_sub(TALLOC_CTX *ctx, fr_value_box_t *out, request_t *request, uint32_t num) -{ - fr_regcapture_t *rc; - char const *p; - int ret; - - rc = request_data_reference(request, request, REQUEST_DATA_REGEX); - if (!rc) { - RDEBUG4("No subcapture data found"); - return -1; - } - - ret = pcre_get_substring(rc->regmatch->subject, - (int *)rc->regmatch->match_data, (int)rc->regmatch->used, num, &p); - switch (ret) { - case PCRE_ERROR_NOMEMORY: - MEM(NULL); - break; - - /* - * Not finding a substring is fine - */ - case PCRE_ERROR_NOSUBSTRING: - RDEBUG4("%i/%zu Not found", num + 1, rc->regmatch->used); - return -1; - - default: - if (ret < 0) return -1; - - talloc_set_type(p, char); - talloc_steal(ctx, p); - - fr_value_box_init(out, FR_TYPE_STRING, NULL, false); - fr_value_box_bstrndup_shallow(out, NULL, p, talloc_array_length(p) - 1, false); - fr_value_box_mark_safe_for(out, rc->safe_for); - fr_value_box_set_secret(out, rc->secret); - - RDEBUG4("%i/%zu Found: %pV (%zu)", num + 1, rc->regmatch->used, out, out->vb_length); - break; - } - - return 0; -} - -/** Extract a named subcapture value from the request - * - * @note This is the PCRE variant of the function. - * - * @param[in] ctx To allocate subcapture buffer in. - * @param[out] out Where to write the subcapture string. - * @param[in] request to extract. - * @param[in] name of subcapture. - * @return - * - 0 on success. - * - -1 on notfound. - */ -int regex_request_to_sub_named(TALLOC_CTX *ctx, fr_value_box_t *out, request_t *request, char const *name) -{ - fr_regcapture_t *rc; - void *rd; - char const *p; - int ret; - - rd = request_data_reference(request, request, REQUEST_DATA_REGEX); - if (!rd) { - RDEBUG4("No subcapture data found"); - return -1; - } - - rc = talloc_get_type_abort(rd, fr_regcapture_t); - ret = pcre_get_named_substring(rc->preg->compiled, rc->regmatch->subject, - (int *)rc->regmatch->match_data, (int)rc->regmatch->used, name, &p); - switch (ret) { - case PCRE_ERROR_NOMEMORY: - MEM(NULL); - break; - - /* - * Not finding a substring is fine - */ - case PCRE_ERROR_NOSUBSTRING: - RDEBUG4("No named capture group \"%s\"", name); - return -1; - - default: - if (ret < 0) return -1; - - talloc_set_type(p, char); - talloc_steal(ctx, p); - - fr_value_box_init(out, FR_TYPE_STRING, NULL, false); - fr_value_box_bstrndup_shallow(out, NULL, p, talloc_array_length(p) - 1, false); - fr_value_box_mark_safe_for(out, rc->safe_for); - fr_value_box_set_secret(out, rc->secret); - - RDEBUG4("Found \"%s\": %pV (%zu)", name, out, out->vb_length); - - break; - } - - return 0; -} # else /** Extract a subcapture value from the request * diff --git a/src/lib/server/regex.h b/src/lib/server/regex.h index 3a79ae00b9..feb41552b4 100644 --- a/src/lib/server/regex.h +++ b/src/lib/server/regex.h @@ -47,7 +47,7 @@ int regex_request_to_sub(TALLOC_CTX *ctx, fr_value_box_t *out, request_t *reques /* * Named capture groups only supported by PCRE. */ -# if defined(HAVE_REGEX_PCRE2) || defined(HAVE_REGEX_PCRE) +# if defined(HAVE_REGEX_PCRE2) int regex_request_to_sub_named(TALLOC_CTX *ctx, fr_value_box_t *out, request_t *request, char const *name) CC_HINT(nonnull); # endif #endif diff --git a/src/lib/util/regex.c b/src/lib/util/regex.c index 89efb45346..ecec901040 100644 --- a/src/lib/util/regex.c +++ b/src/lib/util/regex.c @@ -28,7 +28,7 @@ RCSID("$Id$") #include #include -#if defined(HAVE_REGEX_PCRE) || (defined(HAVE_REGEX_PCRE2) && defined(PCRE2_CONFIG_JIT)) +#if defined(HAVE_REGEX_PCRE2) && defined(PCRE2_CONFIG_JIT) #ifndef FR_PCRE_JIT_STACK_MIN # define FR_PCRE_JIT_STACK_MIN (128 * 1024) #endif @@ -657,374 +657,7 @@ fr_regmatch_t *regex_match_data_alloc(TALLOC_CTX *ctx, uint32_t count) return regmatch; } -/* - *###################################### - *# FUNCTIONS FOR LIBPCRE # - *###################################### - */ -#elif defined(HAVE_REGEX_PCRE) -/* - * Wrapper functions for libpcre. Much more powerful, and guaranteed - * to be binary safe but require libpcre. - */ -#if (PCRE_MAJOR >= 8) && (PCRE_MINOR >= 32) && defined(PCRE_CONFIG_JIT) -# define HAVE_PCRE_JIT_EXEC 1 -#endif - -/** Thread local storage for PCRE - * - */ -typedef struct { - TALLOC_CTX *alloc_ctx; //!< Context used for any allocations. -#ifdef HAVE_PCRE_JIT_EXEC - pcre_jit_stack *jit_stack; -#endif -} fr_pcre_tls_t; - -static _Thread_local fr_pcre_tls_t *fr_pcre_tls; -static bool fr_pcre_study_flags; - -/* - * Replace the libpcre memory allocation and freeing functions - * with talloc wrappers. This allows us to use the subcapture copy - * functions and just reparent the memory allocated. - */ -static void *_pcre_talloc(size_t to_alloc) -{ - return talloc_array(fr_pcre_tls->alloc_ctx, uint8_t, to_alloc); -} - -static void _pcre_talloc_free(void *to_free) -{ - talloc_free(to_free); -} - -static int _pcre_globals_reset(UNUSED void *uctx) -{ - pcre_malloc = NULL; - pcre_free = NULL; - return 0; -} - -static int _pcre_globals_configure(UNUSED void *uctx) -{ -#ifdef PCRE_CONFIG_JIT - int *do_jit = 0; - - /* - * If the headers are from >= 8.20 - * check at runtime to see if this version - * of the libpcre library was compiled with - * JIT support. - */ - pcre_config(PCRE_CONFIG_JIT, &do_jit); - - if (do_jit) fr_pcre_study_flags |= PCRE_STUDY_JIT_COMPILE; -#endif - pcre_malloc = _pcre_talloc; /* pcre_malloc is a global provided by libpcre */ - pcre_free = _pcre_talloc_free; /* pcre_free is a global provided by libpcre */ - - return 0; -} - -/** Free thread local data - * - * @param[in] tls Thread local data to free. - */ -static int _pcre_tls_free(fr_pcre_tls_t *tls) -{ -#ifdef HAVE_PCRE_JIT_EXEC - if (tls->jit_stack) pcre_jit_stack_free(tls->jit_stack); -#endif - return 0; -} - -static int _pcre_tls_free_on_exit(void *arg) -{ - return talloc_free(arg); -} - -/** Performs thread local storage initialisation for libpcre - * - */ -static inline CC_HINT(always_inline) int pcre_tls_init(void) -{ - fr_pcre_tls_t *tls; - - if (fr_pcre_tls) return 0; - - tls = talloc_zero(NULL, fr_pcre_tls_t); - if (unlikely(!tls)) return -1; - talloc_set_destructor(tls, _pcre_tls_free); - - /* - * Need to set this first so that the alloc - * functions can access alloc_ctx. - */ - fr_atexit_thread_local(fr_pcre_tls, _pcre_tls_free_on_exit, tls); - -#ifdef HAVE_PCRE_JIT_EXEC - /* - * Starts at 128K, max is 512K per thread. - */ - tls->jit_stack = pcre_jit_stack_alloc(FR_PCRE_JIT_STACK_MIN, FR_PCRE_JIT_STACK_MAX); -#endif - - return 0; -} - -/** Free regex_t structure - * - * Calls libpcre specific free functions for the expression and study. - * - * @param preg to free. - */ -static int _regex_free(regex_t *preg) -{ - if (preg->compiled) pcre_free(preg->compiled); -#ifdef PCRE_CONFIG_JIT - if (preg->extra) pcre_free_study(preg->extra); -#else - if (preg->extra) pcre_free(preg->extra); -#endif - - return 0; -} - -/** Wrapper around pcre_compile - * - * Allows the rest of the code to do compilations using one function signature. - * - * @note Compiled expression must be freed with talloc_free. - * - * @param[out] out Where to write out a pointer to the structure containing - * the compiled expression. - * @param[in] pattern to compile. - * @param[in] len of pattern. - * @param[in] flags controlling matching. May be NULL. - * @param[in] subcaptures Whether to compile the regular expression to store subcapture - * data. - * @param[in] runtime If false run the pattern through the PCRE JIT to convert it - * to machine code. This trades startup time (longer) for - * runtime performance (better). - * @return - * - >= 1 on success. - * - <= 0 on error. Negative value is offset of parse error. - */ -ssize_t regex_compile(TALLOC_CTX *ctx, regex_t **out, char const *pattern, size_t len, - fr_regex_flags_t const *flags, bool subcaptures, bool runtime) -{ - char const *error; - int offset; - int cflags = 0; - int ret; - regex_t *preg; - - fr_atexit_global_once_ret(&ret, _pcre_globals_configure, _pcre_globals_reset, NULL); - if (unlikely(ret < 0)) return -1; - - - if (unlikely(pcre_tls_init() < 0)) return -1; - - /* - * Check inputs - */ - *out = NULL; - - if (len == 0) { - fr_strerror_const("Empty expression"); - return 0; - } - - /* - * Options - */ - if (flags) { - if (flags->global) { - fr_strerror_const("g - Global matching/substitution not supported with libpcre"); - return 0; - } - if (flags->ignore_case) cflags |= PCRE_CASELESS; - if (flags->multiline) cflags |= PCRE_MULTILINE; - if (flags->dot_all) cflags |= PCRE_DOTALL; - if (flags->unicode) cflags |= PCRE_UTF8; - if (flags->extended) cflags |= PCRE_EXTENDED; - } - - if (!subcaptures) cflags |= PCRE_NO_AUTO_CAPTURE; - - preg = talloc_zero(ctx, regex_t); - if (unlikely(preg == NULL)) { - fr_strerror_const("Out of memory"); - return 0; - } - talloc_set_destructor(preg, _regex_free); - - preg->compiled = pcre_compile(pattern, cflags, &error, &offset, NULL); - if (!preg->compiled) { - fr_strerror_printf("%s", error); - talloc_free(preg); - - return -(ssize_t)offset; - } - - if (!runtime) { - preg->precompiled = true; - preg->extra = pcre_study(preg->compiled, fr_pcre_study_flags, &error); - if (error) { - fr_strerror_printf("Pattern study failed: %s", error); - talloc_free(preg); - - return 0; - } - -#ifdef PCRE_INFO_JIT - /* - * Check to see if the JIT was successful. - * - * Not all platforms have JIT support, the pattern - * may not be jitable, or JIT support may have been - * disabled. - */ - if (fr_pcre_study_flags & PCRE_STUDY_JIT_COMPILE) { - int jitd = 0; - - pcre_fullinfo(preg->compiled, preg->extra, PCRE_INFO_JIT, &jitd); - if (jitd) preg->jitd = true; - } -#endif - } - - *out = preg; - - return len; -} - -static fr_table_num_ordered_t const regex_pcre_error_str[] = { - { L("PCRE_ERROR_NOMATCH"), PCRE_ERROR_NOMATCH }, - { L("PCRE_ERROR_NULL"), PCRE_ERROR_NULL }, - { L("PCRE_ERROR_BADOPTION"), PCRE_ERROR_BADOPTION }, - { L("PCRE_ERROR_BADMAGIC"), PCRE_ERROR_BADMAGIC }, - { L("PCRE_ERROR_UNKNOWN_OPCODE"), PCRE_ERROR_UNKNOWN_OPCODE }, - { L("PCRE_ERROR_NOMEMORY"), PCRE_ERROR_NOMEMORY }, - { L("PCRE_ERROR_NOSUBSTRING"), PCRE_ERROR_NOSUBSTRING }, - { L("PCRE_ERROR_MATCHLIMIT"), PCRE_ERROR_MATCHLIMIT }, - { L("PCRE_ERROR_CALLOUT"), PCRE_ERROR_CALLOUT }, - { L("PCRE_ERROR_BADUTF8"), PCRE_ERROR_BADUTF8 }, - { L("PCRE_ERROR_BADUTF8_OFFSET"), PCRE_ERROR_BADUTF8_OFFSET }, - { L("PCRE_ERROR_PARTIAL"), PCRE_ERROR_PARTIAL }, - { L("PCRE_ERROR_BADPARTIAL"), PCRE_ERROR_BADPARTIAL }, - { L("PCRE_ERROR_INTERNAL"), PCRE_ERROR_INTERNAL }, - { L("PCRE_ERROR_BADCOUNT"), PCRE_ERROR_BADCOUNT }, - { L("PCRE_ERROR_DFA_UITEM"), PCRE_ERROR_DFA_UITEM }, - { L("PCRE_ERROR_DFA_UCOND"), PCRE_ERROR_DFA_UCOND }, - { L("PCRE_ERROR_DFA_UMLIMIT"), PCRE_ERROR_DFA_UMLIMIT }, - { L("PCRE_ERROR_DFA_WSSIZE"), PCRE_ERROR_DFA_WSSIZE }, - { L("PCRE_ERROR_DFA_RECURSE"), PCRE_ERROR_DFA_RECURSE }, - { L("PCRE_ERROR_RECURSIONLIMIT"), PCRE_ERROR_RECURSIONLIMIT }, - { L("PCRE_ERROR_NULLWSLIMIT"), PCRE_ERROR_NULLWSLIMIT }, - { L("PCRE_ERROR_BADNEWLINE"), PCRE_ERROR_BADNEWLINE }, - { L("PCRE_ERROR_BADOFFSET"), PCRE_ERROR_BADOFFSET }, - { L("PCRE_ERROR_SHORTUTF8"), PCRE_ERROR_SHORTUTF8 }, - { L("PCRE_ERROR_RECURSELOOP"), PCRE_ERROR_RECURSELOOP }, - { L("PCRE_ERROR_JIT_STACKLIMIT"), PCRE_ERROR_JIT_STACKLIMIT }, - { L("PCRE_ERROR_BADMODE"), PCRE_ERROR_BADMODE }, - { L("PCRE_ERROR_BADENDIANNESS"), PCRE_ERROR_BADENDIANNESS }, - { L("PCRE_ERROR_DFA_BADRESTART"), PCRE_ERROR_DFA_BADRESTART }, - { L("PCRE_ERROR_JIT_BADOPTION"), PCRE_ERROR_JIT_BADOPTION }, - { L("PCRE_ERROR_BADLENGTH"), PCRE_ERROR_BADLENGTH }, -#ifdef PCRE_ERROR_UNSET - { L("PCRE_ERROR_UNSET"), PCRE_ERROR_UNSET }, -#endif -}; -static size_t regex_pcre_error_str_len = NUM_ELEMENTS(regex_pcre_error_str); - -/** Wrapper around pcre_exec - * - * @param[in] preg The compiled expression. - * @param[in] subject to match. - * @param[in] len Length of subject. - * @param[in] regmatch Match result structure. - * @return - * - -1 on failure. - * - 0 on no match. - * - 1 on match. - */ -int regex_exec(regex_t *preg, char const *subject, size_t len, fr_regmatch_t *regmatch) -{ - int ret; - size_t matches; - - if (unlikely(pcre_tls_init() < 0)) return -1; - - /* - * Disable capturing - */ - if (!regmatch) { - matches = 0; - } else { - matches = regmatch->allocd; - - /* - * Reset the match result structure - */ - memset(regmatch->match_data, 0, sizeof(regmatch->match_data[0]) * matches); - regmatch->used = 0; - } - -#ifdef HAVE_PCRE_JIT_EXEC - if (preg->jitd) { - ret = pcre_jit_exec(preg->compiled, preg->extra, subject, len, 0, 0, - regmatch ? (int *)regmatch->match_data : NULL, matches * 3, fr_pcre_tls->jit_stack); - } else -#endif - { - ret = pcre_exec(preg->compiled, preg->extra, subject, len, 0, 0, - regmatch ? (int *)regmatch->match_data : NULL, matches * 3); - } - if (ret < 0) { - if (ret == PCRE_ERROR_NOMATCH) return 0; - - fr_strerror_printf("regex evaluation failed with code (%i): %s", ret, - fr_table_str_by_value(regex_pcre_error_str, ret, "")); - return -1; - } - /* - * 0 signifies more offsets than we provided space for, - * so don't touch nmatches. - */ - if (regmatch && (ret > 0)) { - regmatch->used = ret; - - if (regmatch->subject) talloc_const_free(regmatch->subject); - regmatch->subject = talloc_bstrndup(regmatch, subject, len); - if (!regmatch->subject) { - fr_strerror_const("Out of memory"); - return -1; - } - } - - return 1; -} - -/** Returns the number of subcapture groups - * - * @return - * - >0 The number of subcaptures contained within the pattern - * - 0 if the number of subcaptures can't be determined. - */ -uint32_t regex_subcapture_count(regex_t const *preg) -{ - int count; - - if (pcre_fullinfo(preg->compiled, preg->extra, PCRE_INFO_CAPTURECOUNT, &count) != 0) { - fr_strerror_const("Error determining subcapture group count"); - return 0; - } - - return (uint32_t)count + 1; -} /* *###################################### *# FUNCTIONS FOR POSIX-REGEX # @@ -1249,7 +882,7 @@ uint32_t regex_subcapture_count(UNUSED regex_t const *preg) } # endif -# if defined(HAVE_REGEX_POSIX) || defined(HAVE_REGEX_PCRE) +# if defined(HAVE_REGEX_POSIX) /** Allocate vectors to fill with match data * * @param[in] ctx to allocate match vectors in. diff --git a/src/lib/util/regex.h b/src/lib/util/regex.h index 0ee635c612..7f3ec7b5ec 100644 --- a/src/lib/util/regex.h +++ b/src/lib/util/regex.h @@ -70,51 +70,6 @@ typedef struct { ///< or compiled for one off evaluation. bool jitd; //!< Whether JIT data is available. } regex_t; -/* - *###################################### - *# STRUCTURES FOR LIBPCRE # - *###################################### - */ -# elif defined(HAVE_REGEX_PCRE) -# include -/* - * Versions older then 8.20 didn't have the JIT functionality - * so, gracefully degrade. - */ -# ifndef PCRE_STUDY_JIT_COMPILE -# define PCRE_STUDY_JIT_COMPILE 0 -# endif -/* - * libpcre defines its matches as an array of ints which is a - * multiple of three. - */ -typedef struct { - int a; - int b; - int c; -} regmatch_t; - -/** Emulates the functionality of the pcre2_match_data struct - * - */ -typedef struct { - regmatch_t *match_data; //!< Slots for matches. - size_t allocd; //!< Number of slots allocated for match data. - size_t used; //!< Number of slots filled with match data. - char const *subject; //!< A local copy of the subject. -} fr_regmatch_t; - -/** Bundles compiled regular expression structures together - * - */ -typedef struct { - pcre *compiled; //!< Compiled regular expression. - pcre_extra *extra; //!< Result of studying a regular expression. - uint32_t subcaptures; //!< Number of subcaptures contained within the expression. - - bool precompiled; //!< Whether this regex was precompiled, or compiled for one off evaluation. - bool jitd; //!< Whether JIT data is available. -} regex_t; /* *###################################### *# STRUCTURES FOR POSIX-REGEX # diff --git a/src/tests/keywords/all.mk b/src/tests/keywords/all.mk index 951a4962af..80cba68610 100644 --- a/src/tests/keywords/all.mk +++ b/src/tests/keywords/all.mk @@ -23,9 +23,9 @@ FILES := $(filter-out pap-ssha2 sha2,$(FILES)) endif # -# Some tests require PCRE or PCRE2 +# Some tests require PCRE2 # -ifeq "$(AC_HAVE_REGEX_PCRE)$(AC_HAVE_REGEX_PCRE2)" "" +ifeq "$(AC_HAVE_REGEX_PCRE2)" "" FILES := $(filter-out if-regex-match-named,$(FILES)) endif