From: Arran Cudbard-Bell Date: Fri, 19 Apr 2019 14:12:53 +0000 (-0400) Subject: PCRE2_COPY_MATCHED_SUBJECT doesn't work for pcre2_jit_match apparently X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4a44a2f4d2fbf0eba7fcbbff4cbbc4ff69dd52d;p=thirdparty%2Ffreeradius-server.git PCRE2_COPY_MATCHED_SUBJECT doesn't work for pcre2_jit_match apparently --- diff --git a/src/lib/server/regex.c b/src/lib/server/regex.c index fd325ce5839..6a3b3977e32 100644 --- a/src/lib/server/regex.c +++ b/src/lib/server/regex.c @@ -128,7 +128,7 @@ int regex_request_to_sub(TALLOC_CTX *ctx, char **out, REQUEST *request, uint32_t *out = NULL; return 1; } - match_data = rc->regmatch->match_data; + match_data = talloc_get_type_abort(rc->regmatch->match_data, pcre2_match_data); ret = pcre2_substring_length_bynumber(match_data, num, &len); switch (ret) { diff --git a/src/lib/util/regex.c b/src/lib/util/regex.c index 55d2325e574..72b3fda1d5f 100644 --- a/src/lib/util/regex.c +++ b/src/lib/util/regex.c @@ -284,9 +284,8 @@ int regex_exec(regex_t *preg, char const *subject, size_t len, fr_regmatch_t *re int ret; uint32_t options = 0; -#ifndef PCRE2_COPY_MATCHED_SUBJECT char *our_subject = NULL; -#endif + bool dup_subject = true; /* * Thread local initialisation @@ -294,33 +293,45 @@ int regex_exec(regex_t *preg, char const *subject, size_t len, fr_regmatch_t *re if (!fr_pcre2_tls && (fr_pcre2_tls_init() < 0)) return -1; if (regmatch) { -#ifndef PCRE2_COPY_MATCHED_SUBJECT +#ifdef PCRE2_COPY_MATCHED_SUBJECT /* - * We have to dup and operate on the duplicate - * of the subject, because pcre2_jit_match and - * pcre2_match store a pointer to the subject - * in the regmatch structure. + * This is apparently only supported for pcre2_match + * NOT pcre2_jit_match. */ - subject = our_subject = talloc_bstrndup(regmatch, subject, len); - if (!subject) { - fr_strerror_printf("Out of memory"); - return -1; + if (!preg->jitd) { + dup_subject = false; + + /* + * If PCRE2_COPY_MATCHED_SUBJECT is available + * and set as an options flag, pcre2_match will + * strdup the subject string if pcre2_match is + * successful and store a pointer to it in the + * regmatch struct. + * + * The lifetime of the string memory will be + * bound to the regmatch struct. This is more + * efficient that doing it ourselves, as the + * strdup only occurs if the subject matches. + */ + options |= PCRE2_COPY_MATCHED_SUBJECT; } -#else - /* - * If PCRE2_COPY_MATCHED_SUBJECT is available - * and set as an options flag, pcre2_match will - * strdup the subject string if pcre2_match is - * successful and store a pointer to it in the - * regmatch struct. - * - * The lifetime of the string memory will be - * bound to the regmatch struct. This is more - * efficient that doing it ourselves, as the - * strdup only occurs if the subject matches. - */ - options |= PCRE2_COPY_MATCHED_SUBJECT; #endif + if (dup_subject) { + /* + * We have to dup and operate on the duplicate + * of the subject, because pcre2_jit_match and + * pcre2_match store a pointer to the subject + * in the regmatch structure. + */ + subject = our_subject = talloc_bstrndup(regmatch, subject, len); + if (!subject) { + fr_strerror_printf("Out of memory"); + return -1; + } +#ifndef NDEBUG + regmatch->subject = subject; /* Stored only for tracking memory issues */ +#endif + } } if (preg->jitd) { @@ -333,9 +344,7 @@ int regex_exec(regex_t *preg, char const *subject, size_t len, fr_regmatch_t *re if (ret < 0) { PCRE2_UCHAR errbuff[128]; -#ifndef PCRE2_COPY_MATCHED_SUBJECT - talloc_free(our_subject); -#endif + if (dup_subject) talloc_free(our_subject); if (ret == PCRE2_ERROR_NOMATCH) { if (regmatch) regmatch->used = 0; diff --git a/src/lib/util/regex.h b/src/lib/util/regex.h index 8e6aa6a9232..212b35952ba 100644 --- a/src/lib/util/regex.h +++ b/src/lib/util/regex.h @@ -55,6 +55,9 @@ typedef struct { pcre2_match_data *match_data; //!< Match data containing the subject ///< and various match offsets. size_t used; //!< Number of slots filled with match data. +#ifndef NDEBUG + char const *subject; //!< Here for debugging purposes if we explicitly duped the string. +#endif } fr_regmatch_t; typedef struct {