[PATCH 0 of 4] PCRE2 support

Tatsuhiko Kubo cubicdaiya at gmail.com
Wed Dec 15 00:42:39 UTC 2021


Hello,

Thank you for your reply. The build works fine after applying the
additional patch.

Thanks.

--
Tatsuhiko Kubo

2021年12月15日(水) 1:09 Maxim Dounin <mdounin at mdounin.ru>:

>
> Hello!
>
> On Tue, Dec 14, 2021 at 03:09:43PM +0900, Tatsuhiko Kubo wrote:
>
> > Hello,
> >
> > I'm trying these patches and the build of nginx with the option
> > "--with-pcre-jit" fails.
> >
> > $ cd nginx-1.21.4 # with applied patches
> > $ ./configure --with-pcre=../pcre2/pcre2-10.39 --with-pcre-jit
> > $ make
> > ...
> > cc -c -pipe  -O -Wall -Wextra -Wpointer-arith
> > -Wconditional-uninitialized -Wno-unused-parameter
> > -Wno-deprecated-declarations -Werror -g  -I src/core -I src/event -I
> > src/event/modules -I src/os/unix -I ../pcre2/pcre2-10.39/src/ -I objs
> > \
> >                 -o objs/src/core/ngx_regex.o \
> >                 src/core/ngx_regex.c
> > src/core/ngx_regex.c:590:15: error: use of undeclared identifier
> > 'PCRE_STUDY_JIT_COMPILE'
> >         opt = PCRE_STUDY_JIT_COMPILE;
>
> Thanks, looks like a mismerge in the last patch at some point during
> development.  The following patch should fix this:
>
> diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c
> --- a/src/core/ngx_regex.c
> +++ b/src/core/ngx_regex.c
> @@ -585,10 +585,16 @@ ngx_regex_module_init(ngx_cycle_t *cycle
>
>      rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
>
> -#if (NGX_HAVE_PCRE_JIT)
> +#if (NGX_PCRE2 || NGX_HAVE_PCRE_JIT)
> +
>      if (rcf->pcre_jit) {
> +#if (NGX_PCRE2)
> +        opt = 1;
> +#else
>          opt = PCRE_STUDY_JIT_COMPILE;
> +#endif
>      }
> +
>  #endif
>
>      ngx_regex_malloc_init(cycle->pool);
>
>
> Full series updated:
>
> # HG changeset patch
> # User Maxim Dounin <mdounin at mdounin.ru>
> # Date 1639495851 -10800
> #      Tue Dec 14 18:30:51 2021 +0300
> # Node ID 4f979a9f2a68b25b8b2ce8a0bd15671095f6c327
> # Parent  a7a77549265ef46f1f0fdb3897f4beabf9e09c40
> Core: fixed ngx_pcre_studies cleanup.
>
> If a configuration parsing fails for some reason, ngx_regex_module_init()
> is not called, and ngx_pcre_studies remained set despite the fact that
> the pool it was allocated from is already freed.  This might result in
> a segmentation fault during runtime regular expression compilation, such
> as in SSI, for example, in the single process mode, or if a worker process
> dies and respawn from a master process in such an inconsistent state.
>
> Fix is to clear ngx_pcre_studies from the pool cleanup handler (which is
> anyway used to free JIT-compiled patterns).
>
> diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c
> --- a/src/core/ngx_regex.c
> +++ b/src/core/ngx_regex.c
> @@ -10,15 +10,14 @@
>
>
>  typedef struct {
> -    ngx_flag_t  pcre_jit;
> +    ngx_flag_t   pcre_jit;
> +    ngx_list_t  *studies;
>  } ngx_regex_conf_t;
>
>
>  static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
>  static void ngx_libc_cdecl ngx_regex_free(void *p);
> -#if (NGX_HAVE_PCRE_JIT)
> -static void ngx_pcre_free_studies(void *data);
> -#endif
> +static void ngx_regex_cleanup(void *data);
>
>  static ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle);
>
> @@ -248,18 +247,17 @@ ngx_regex_free(void *p)
>  }
>
>
> +static void
> +ngx_regex_cleanup(void *data)
> +{
>  #if (NGX_HAVE_PCRE_JIT)
> -
> -static void
> -ngx_pcre_free_studies(void *data)
> -{
> -    ngx_list_t *studies = data;
> +    ngx_regex_conf_t *rcf = data;
>
>      ngx_uint_t        i;
>      ngx_list_part_t  *part;
>      ngx_regex_elt_t  *elts;
>
> -    part = &studies->part;
> +    part = &rcf->studies->part;
>      elts = part->elts;
>
>      for (i = 0; /* void */ ; i++) {
> @@ -274,56 +272,50 @@ ngx_pcre_free_studies(void *data)
>              i = 0;
>          }
>
> -        if (elts[i].regex->extra != NULL) {
> -            pcre_free_study(elts[i].regex->extra);
> -        }
> -    }
> -}
> -
> -#endif
> -
> -
> -static ngx_int_t
> -ngx_regex_module_init(ngx_cycle_t *cycle)
> -{
> -    int               opt;
> -    const char       *errstr;
> -    ngx_uint_t        i;
> -    ngx_list_part_t  *part;
> -    ngx_regex_elt_t  *elts;
> -
> -    opt = 0;
> -
> -#if (NGX_HAVE_PCRE_JIT)
> -    {
> -    ngx_regex_conf_t    *rcf;
> -    ngx_pool_cleanup_t  *cln;
> -
> -    rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
> -
> -    if (rcf->pcre_jit) {
> -        opt = PCRE_STUDY_JIT_COMPILE;
> -
>          /*
>           * The PCRE JIT compiler uses mmap for its executable codes, so we
>           * have to explicitly call the pcre_free_study() function to free
>           * this memory.
>           */
>
> -        cln = ngx_pool_cleanup_add(cycle->pool, 0);
> -        if (cln == NULL) {
> -            return NGX_ERROR;
> +        if (elts[i].regex->extra != NULL) {
> +            pcre_free_study(elts[i].regex->extra);
>          }
> +    }
> +#endif
>
> -        cln->handler = ngx_pcre_free_studies;
> -        cln->data = ngx_pcre_studies;
> -    }
> +    /*
> +     * On configuration parsing errors ngx_regex_module_init() will not
> +     * be called.  Make sure ngx_pcre_studies is properly cleared anyway.
> +     */
> +
> +    ngx_pcre_studies = NULL;
> +}
> +
> +
> +static ngx_int_t
> +ngx_regex_module_init(ngx_cycle_t *cycle)
> +{
> +    int                opt;
> +    const char        *errstr;
> +    ngx_uint_t         i;
> +    ngx_list_part_t   *part;
> +    ngx_regex_elt_t   *elts;
> +    ngx_regex_conf_t  *rcf;
> +
> +    opt = 0;
> +
> +    rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
> +
> +#if (NGX_HAVE_PCRE_JIT)
> +    if (rcf->pcre_jit) {
> +        opt = PCRE_STUDY_JIT_COMPILE;
>      }
>  #endif
>
>      ngx_regex_malloc_init(cycle->pool);
>
> -    part = &ngx_pcre_studies->part;
> +    part = &rcf->studies->part;
>      elts = part->elts;
>
>      for (i = 0; /* void */ ; i++) {
> @@ -374,7 +366,8 @@ ngx_regex_module_init(ngx_cycle_t *cycle
>  static void *
>  ngx_regex_create_conf(ngx_cycle_t *cycle)
>  {
> -    ngx_regex_conf_t  *rcf;
> +    ngx_regex_conf_t    *rcf;
> +    ngx_pool_cleanup_t  *cln;
>
>      rcf = ngx_pcalloc(cycle->pool, sizeof(ngx_regex_conf_t));
>      if (rcf == NULL) {
> @@ -383,11 +376,21 @@ ngx_regex_create_conf(ngx_cycle_t *cycle
>
>      rcf->pcre_jit = NGX_CONF_UNSET;
>
> -    ngx_pcre_studies = ngx_list_create(cycle->pool, 8, sizeof(ngx_regex_elt_t));
> -    if (ngx_pcre_studies == NULL) {
> +    cln = ngx_pool_cleanup_add(cycle->pool, 0);
> +    if (cln == NULL) {
>          return NULL;
>      }
>
> +    cln->handler = ngx_regex_cleanup;
> +    cln->data = rcf;
> +
> +    rcf->studies = ngx_list_create(cycle->pool, 8, sizeof(ngx_regex_elt_t));
> +    if (rcf->studies == NULL) {
> +        return NULL;
> +    }
> +
> +    ngx_pcre_studies = rcf->studies;
> +
>      return rcf;
>  }
>
> # HG changeset patch
> # User Maxim Dounin <mdounin at mdounin.ru>
> # Date 1639497274 -10800
> #      Tue Dec 14 18:54:34 2021 +0300
> # Node ID 8f00e80ade356c768a678c44711e8c2a7223ceef
> # Parent  4f979a9f2a68b25b8b2ce8a0bd15671095f6c327
> Core: ngx_regex.c style cleanup.
>
> Notably, ngx_pcre_pool and ngx_pcre_studies are renamed to ngx_regex_pool
> and ngx_regex_studies, respectively.
>
> diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c
> --- a/src/core/ngx_regex.c
> +++ b/src/core/ngx_regex.c
> @@ -64,8 +64,8 @@ ngx_module_t  ngx_regex_module = {
>  };
>
>
> -static ngx_pool_t  *ngx_pcre_pool;
> -static ngx_list_t  *ngx_pcre_studies;
> +static ngx_pool_t  *ngx_regex_pool;
> +static ngx_list_t  *ngx_regex_studies;
>
>
>  void
> @@ -79,14 +79,14 @@ ngx_regex_init(void)
>  static ngx_inline void
>  ngx_regex_malloc_init(ngx_pool_t *pool)
>  {
> -    ngx_pcre_pool = pool;
> +    ngx_regex_pool = pool;
>  }
>
>
>  static ngx_inline void
>  ngx_regex_malloc_done(void)
>  {
> -    ngx_pcre_pool = NULL;
> +    ngx_regex_pool = NULL;
>  }
>
>
> @@ -112,13 +112,13 @@ ngx_regex_compile(ngx_regex_compile_t *r
>             rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
>                                "pcre_compile() failed: %s in \"%V\"",
>                                 errstr, &rc->pattern)
> -                      - rc->err.data;
> +                         - rc->err.data;
>
>          } else {
>             rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
>                                "pcre_compile() failed: %s in \"%V\" at \"%s\"",
>                                 errstr, &rc->pattern, rc->pattern.data + erroff)
> -                      - rc->err.data;
> +                         - rc->err.data;
>          }
>
>          return NGX_ERROR;
> @@ -133,8 +133,8 @@ ngx_regex_compile(ngx_regex_compile_t *r
>
>      /* do not study at runtime */
>
> -    if (ngx_pcre_studies != NULL) {
> -        elt = ngx_list_push(ngx_pcre_studies);
> +    if (ngx_regex_studies != NULL) {
> +        elt = ngx_list_push(ngx_regex_studies);
>          if (elt == NULL) {
>              goto nomem;
>          }
> @@ -229,11 +229,8 @@ ngx_regex_exec_array(ngx_array_t *a, ngx
>  static void * ngx_libc_cdecl
>  ngx_regex_malloc(size_t size)
>  {
> -    ngx_pool_t      *pool;
> -    pool = ngx_pcre_pool;
> -
> -    if (pool) {
> -        return ngx_palloc(pool, size);
> +    if (ngx_regex_pool) {
> +        return ngx_palloc(ngx_regex_pool, size);
>      }
>
>      return NULL;
> @@ -286,10 +283,10 @@ ngx_regex_cleanup(void *data)
>
>      /*
>       * On configuration parsing errors ngx_regex_module_init() will not
> -     * be called.  Make sure ngx_pcre_studies is properly cleared anyway.
> +     * be called.  Make sure ngx_regex_studies is properly cleared anyway.
>       */
>
> -    ngx_pcre_studies = NULL;
> +    ngx_regex_studies = NULL;
>  }
>
>
> @@ -357,7 +354,7 @@ ngx_regex_module_init(ngx_cycle_t *cycle
>
>      ngx_regex_malloc_done();
>
> -    ngx_pcre_studies = NULL;
> +    ngx_regex_studies = NULL;
>
>      return NGX_OK;
>  }
> @@ -389,7 +386,7 @@ ngx_regex_create_conf(ngx_cycle_t *cycle
>          return NULL;
>      }
>
> -    ngx_pcre_studies = rcf->studies;
> +    ngx_regex_studies = rcf->studies;
>
>      return rcf;
>  }
> # HG changeset patch
> # User Maxim Dounin <mdounin at mdounin.ru>
> # Date 1639497275 -10800
> #      Tue Dec 14 18:54:35 2021 +0300
> # Node ID 0a11d3d92a5d4c1ddcfdd1f07423d59b7c2aa863
> # Parent  8f00e80ade356c768a678c44711e8c2a7223ceef
> Configure: simplified PCRE compilation.
>
> Removed ICC-specific PCRE optimizations which tried to link with PCRE
> object files instead of the library.  Made compiler-specific code
> minimal.
>
> diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf
> --- a/auto/lib/pcre/conf
> +++ b/auto/lib/pcre/conf
> @@ -4,81 +4,24 @@
>
>
>  if [ $PCRE != NONE ]; then
> +
> +    have=NGX_PCRE . auto/have
> +
> +    if [ "$NGX_PLATFORM" = win32 ]; then
> +        have=PCRE_STATIC . auto/have
> +    fi
> +
>      CORE_INCS="$CORE_INCS $PCRE"
> +    CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
>
>      case "$NGX_CC_NAME" in
>
>          msvc | owc | bcc)
> -            have=NGX_PCRE . auto/have
> -            have=PCRE_STATIC . auto/have
> -            CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
>              LINK_DEPS="$LINK_DEPS $PCRE/pcre.lib"
>              CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
>          ;;
>
> -        icc)
> -            have=NGX_PCRE . auto/have
> -            CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
> -
> -            LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
> -
> -            echo $ngx_n "checking for PCRE library ...$ngx_c"
> -
> -            if [ -f $PCRE/pcre.h ]; then
> -                ngx_pcre_ver=`grep PCRE_MAJOR $PCRE/pcre.h \
> -                              | sed -e 's/^.*PCRE_MAJOR.* \(.*\)$/\1/'`
> -
> -            else if [ -f $PCRE/configure.in ]; then
> -                ngx_pcre_ver=`grep PCRE_MAJOR= $PCRE/configure.in \
> -                              | sed -e 's/^.*=\(.*\)$/\1/'`
> -
> -            else
> -                ngx_pcre_ver=`grep pcre_major, $PCRE/configure.ac \
> -                              | sed -e 's/^.*pcre_major,.*\[\(.*\)\].*$/\1/'`
> -            fi
> -            fi
> -
> -            echo " $ngx_pcre_ver major version found"
> -
> -            # to allow -ipo optimization we link with the *.o but not library
> -
> -            case "$ngx_pcre_ver" in
> -                4|5)
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre.o"
> -                ;;
> -
> -                6)
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
> -                ;;
> -
> -                *)
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
> -                    CORE_LIBS="$CORE_LIBS $PCRE/pcre_newline.o"
> -                ;;
> -
> -            esac
> -        ;;
> -
>          *)
> -            have=NGX_PCRE . auto/have
> -
> -            if [ "$NGX_PLATFORM" = win32 ]; then
> -                have=PCRE_STATIC . auto/have
> -            fi
> -
> -            CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
>              LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
>              CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
>          ;;
> # HG changeset patch
> # User Maxim Dounin <mdounin at mdounin.ru>
> # Date 1639497637 -10800
> #      Tue Dec 14 19:00:37 2021 +0300
> # Node ID 6915b92704ceca0030ea6d9e19f37e868a8d2303
> # Parent  0a11d3d92a5d4c1ddcfdd1f07423d59b7c2aa863
> PCRE2 library support.
>
> The PCRE2 library is now used by default if found, instead of the
> original PCRE library.  If needed for some reason, this can be disabled
> with the --without-pcre2 configure option.
>
> To make it possible to specify paths to the library and include files
> via --with-cc-opt / --with-ld-opt, the library is first tested without
> any additional paths and options.  If this fails, the pcre2-config script
> is used.
>
> Similarly to the original PCRE library, it is now possible to build PCRE2
> from sources with nginx configure, by using the --with-pcre= option.
> It automatically detects if PCRE or PCRE2 sources are provided.
>
> Note that compiling PCRE2 10.33 and later requires inttypes.h.  When
> compiling on Windows with MSVC, inttypes.h is only available starting
> with MSVC 2013.  In older versions some replacement needs to be provided
> ("echo '#include <stdint.h>' > pcre2-10.xx/src/inttypes.h" is good enough
> for MSVC 2010).
>
> The interface on nginx side remains unchanged.
>
> diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf
> --- a/auto/lib/pcre/conf
> +++ b/auto/lib/pcre/conf
> @@ -5,29 +5,61 @@
>
>  if [ $PCRE != NONE ]; then
>
> -    have=NGX_PCRE . auto/have
> +    if [ -f $PCRE/src/pcre2.h.generic ]; then
> +
> +        PCRE_LIBRARY=PCRE2
> +
> +        have=NGX_PCRE . auto/have
> +        have=NGX_PCRE2 . auto/have
> +
> +        if [ "$NGX_PLATFORM" = win32 ]; then
> +            have=PCRE2_STATIC . auto/have
> +        fi
> +
> +        CORE_INCS="$CORE_INCS $PCRE/src/"
> +        CORE_DEPS="$CORE_DEPS $PCRE/src/pcre2.h"
>
> -    if [ "$NGX_PLATFORM" = win32 ]; then
> -        have=PCRE_STATIC . auto/have
> -    fi
> +        case "$NGX_CC_NAME" in
> +
> +            msvc)
> +                LINK_DEPS="$LINK_DEPS $PCRE/src/pcre2-8.lib"
> +                CORE_LIBS="$CORE_LIBS $PCRE/src/pcre2-8.lib"
> +            ;;
>
> -    CORE_INCS="$CORE_INCS $PCRE"
> -    CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
> +            *)
> +                LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre2-8.a"
> +                CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre2-8.a"
> +            ;;
>
> -    case "$NGX_CC_NAME" in
> +        esac
>
> -        msvc | owc | bcc)
> -            LINK_DEPS="$LINK_DEPS $PCRE/pcre.lib"
> -            CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
> -        ;;
> +    else
> +
> +        PCRE_LIBRARY=PCRE
> +
> +        have=NGX_PCRE . auto/have
> +
> +        if [ "$NGX_PLATFORM" = win32 ]; then
> +            have=PCRE_STATIC . auto/have
> +        fi
> +
> +        CORE_INCS="$CORE_INCS $PCRE"
> +        CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
>
> -        *)
> -            LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
> -            CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
> -        ;;
> +        case "$NGX_CC_NAME" in
> +
> +            msvc | owc | bcc)
> +                LINK_DEPS="$LINK_DEPS $PCRE/pcre.lib"
> +                CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
> +            ;;
>
> -    esac
> +            *)
> +                LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
> +                CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
> +            ;;
>
> +        esac
> +    fi
>
>      if [ $PCRE_JIT = YES ]; then
>          have=NGX_HAVE_PCRE_JIT . auto/have
> @@ -37,8 +69,48 @@ if [ $PCRE != NONE ]; then
>  else
>
>      if [ "$NGX_PLATFORM" != win32 ]; then
> +        PCRE=NO
> +    fi
>
> -        PCRE=NO
> +    if [ $PCRE = NO -a $PCRE2 != DISABLED ]; then
> +
> +        ngx_feature="PCRE2 library"
> +        ngx_feature_name="NGX_PCRE2"
> +        ngx_feature_run=no
> +        ngx_feature_incs="#define PCRE2_CODE_UNIT_WIDTH 8
> +                          #include <pcre2.h>"
> +        ngx_feature_path=
> +        ngx_feature_libs="-lpcre2-8"
> +        ngx_feature_test="pcre2_code *re;
> +                          re = pcre2_compile(NULL, 0, 0, NULL, NULL, NULL);
> +                          if (re == NULL) return 1"
> +        . auto/feature
> +
> +        if [ $ngx_found = no ]; then
> +
> +            # pcre2-config
> +
> +            ngx_pcre2_prefix=`pcre2-config --prefix 2>/dev/null`
> +
> +            if [ -n "$ngx_pcre2_prefix" ]; then
> +                ngx_feature="PCRE2 library in $ngx_pcre2_prefix"
> +                ngx_feature_path=`pcre2-config --cflags \
> +                                  | sed -n -e 's/.*-I *\([^ ][^ ]*\).*/\1/p'`
> +                ngx_feature_libs=`pcre2-config --libs8`
> +                . auto/feature
> +            fi
> +        fi
> +
> +        if [ $ngx_found = yes ]; then
> +            have=NGX_PCRE . auto/have
> +            CORE_INCS="$CORE_INCS $ngx_feature_path"
> +            CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
> +            PCRE=YES
> +            PCRE_LIBRARY=PCRE2
> +        fi
> +    fi
> +
> +    if [ $PCRE = NO ]; then
>
>          ngx_feature="PCRE library"
>          ngx_feature_name="NGX_PCRE"
> @@ -114,6 +186,7 @@ else
>              CORE_INCS="$CORE_INCS $ngx_feature_path"
>              CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
>              PCRE=YES
> +            PCRE_LIBRARY=PCRE
>          fi
>
>          if [ $PCRE = YES ]; then
> diff --git a/auto/lib/pcre/make b/auto/lib/pcre/make
> --- a/auto/lib/pcre/make
> +++ b/auto/lib/pcre/make
> @@ -3,36 +3,138 @@
>  # Copyright (C) Nginx, Inc.
>
>
> -case "$NGX_CC_NAME" in
> +if [ $PCRE_LIBRARY = PCRE2 ]; then
> +
> +    # PCRE2
> +
> +    if [ $NGX_CC_NAME = msvc ]; then
> +
> +        # With PCRE2, it is not possible to compile all sources.
> +        # Since list of source files changes between versions, we
> +        # test files which might not be present.
>
> -    msvc)
> -        ngx_makefile=makefile.msvc
> -        ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC"
> -        ngx_pcre="PCRE=\"$PCRE\""
> -    ;;
> +        ngx_pcre_srcs="pcre2_auto_possess.c \
> +                       pcre2_chartables.c \
> +                       pcre2_compile.c \
> +                       pcre2_config.c \
> +                       pcre2_context.c \
> +                       pcre2_dfa_match.c \
> +                       pcre2_error.c \
> +                       pcre2_jit_compile.c \
> +                       pcre2_maketables.c \
> +                       pcre2_match.c \
> +                       pcre2_match_data.c \
> +                       pcre2_newline.c \
> +                       pcre2_ord2utf.c \
> +                       pcre2_pattern_info.c \
> +                       pcre2_string_utils.c \
> +                       pcre2_study.c \
> +                       pcre2_substitute.c \
> +                       pcre2_substring.c \
> +                       pcre2_tables.c \
> +                       pcre2_ucd.c \
> +                       pcre2_valid_utf.c \
> +                       pcre2_xclass.c"
> +
> +        ngx_pcre_test="pcre2_convert.c \
> +                       pcre2_extuni.c \
> +                       pcre2_find_bracket.c \
> +                       pcre2_script_run.c \
> +                       pcre2_serialize.c"
> +
> +        for ngx_src in $ngx_pcre_test
> +        do
> +            if [ -f $PCRE/src/$ngx_src ]; then
> +                ngx_pcre_srcs="$ngx_pcre_srcs $ngx_src"
> +            fi
> +        done
>
> -    owc)
> -        ngx_makefile=makefile.owc
> -        ngx_opt="CPU_OPT=\"$CPU_OPT\""
> -        ngx_pcre=`echo PCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
> -    ;;
> +        ngx_pcre_objs=`echo $ngx_pcre_srcs \
> +            | sed -e "s#\([^ ]*\.\)c#\1$ngx_objext#g"`
> +
> +        ngx_pcre_srcs=`echo $ngx_pcre_srcs \
> +            | sed -e "s/  *\([^ ][^ ]*\)/$ngx_regex_cont\1/g"`
> +        ngx_pcre_objs=`echo $ngx_pcre_objs \
> +            | sed -e "s/  *\([^ ][^ ]*\)/$ngx_regex_cont\1/g"`
> +
> +        cat << END                                            >> $NGX_MAKEFILE
> +
> +PCRE_CFLAGS =  -O2 -Ob1 -Oi -Gs $LIBC $CPU_OPT
> +PCRE_FLAGS =   -DHAVE_CONFIG_H -DPCRE2_STATIC -DPCRE2_CODE_UNIT_WIDTH=8 \\
> +               -DHAVE_MEMMOVE
> +
> +PCRE_SRCS =     $ngx_pcre_srcs
> +PCRE_OBJS =     $ngx_pcre_objs
> +
> +$PCRE/src/pcre2.h:
> +       cd $PCRE/src \\
> +       && copy /y config.h.generic config.h \\
> +       && copy /y pcre2.h.generic pcre2.h \\
> +       && copy /y pcre2_chartables.c.dist pcre2_chartables.c
>
> -    bcc)
> -        ngx_makefile=makefile.bcc
> -        ngx_opt="-DCPU_OPT=\"$CPU_OPT\""
> -        ngx_pcre=`echo \-DPCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
> -    ;;
> +$PCRE/src/pcre2-8.lib: $PCRE/src/pcre2.h $NGX_MAKEFILE
> +       cd $PCRE/src \\
> +       && cl -nologo -c \$(PCRE_CFLAGS) -I . \$(PCRE_FLAGS) \$(PCRE_SRCS) \\
> +       && link -lib -out:pcre2-8.lib -verbose:lib \$(PCRE_OBJS)
> +
> +END
> +
> +    else
> +
> +        cat << END                                            >> $NGX_MAKEFILE
> +
> +$PCRE/src/pcre2.h:     $PCRE/Makefile
>
> -    *)
> -        ngx_makefile=
> -    ;;
> +$PCRE/Makefile:        $NGX_MAKEFILE
> +       cd $PCRE \\
> +       && if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
> +       && CC="\$(CC)" CFLAGS="$PCRE_OPT" \\
> +       ./configure --disable-shared $PCRE_CONF_OPT
>
> -esac
> +$PCRE/.libs/libpcre2-8.a:      $PCRE/Makefile
> +       cd $PCRE \\
> +       && \$(MAKE) libpcre2-8.la
> +
> +END
> +
> +    fi
>
>
> -if [ -n "$ngx_makefile" ]; then
> +else
> +
> +    # PCRE
> +
> +    case "$NGX_CC_NAME" in
> +
> +        msvc)
> +            ngx_makefile=makefile.msvc
> +            ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC"
> +            ngx_pcre="PCRE=\"$PCRE\""
> +        ;;
> +
> +        owc)
> +            ngx_makefile=makefile.owc
> +            ngx_opt="CPU_OPT=\"$CPU_OPT\""
> +            ngx_pcre=`echo PCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
> +        ;;
>
> -    cat << END                                                >> $NGX_MAKEFILE
> +        bcc)
> +            ngx_makefile=makefile.bcc
> +            ngx_opt="-DCPU_OPT=\"$CPU_OPT\""
> +            ngx_pcre=`echo \-DPCRE=\"$PCRE\" \
> +                | sed -e "s/\//$ngx_regex_dirsep/g"`
> +        ;;
> +
> +        *)
> +            ngx_makefile=
> +        ;;
> +
> +    esac
> +
> +
> +    if [ -n "$ngx_makefile" ]; then
> +
> +        cat << END                                            >> $NGX_MAKEFILE
>
>  `echo "$PCRE/pcre.lib: $PCRE/pcre.h $NGX_MAKEFILE"                     \
>         | sed -e "s/\//$ngx_regex_dirsep/g"`
> @@ -43,9 +145,9 @@ if [ -n "$ngx_makefile" ]; then
>
>  END
>
> -else
> +    else
>
> -    cat << END                                                >> $NGX_MAKEFILE
> +        cat << END                                            >> $NGX_MAKEFILE
>
>  $PCRE/pcre.h:  $PCRE/Makefile
>
> @@ -61,4 +163,6 @@ else
>
>  END
>
> +    fi
> +
>  fi
> diff --git a/auto/options b/auto/options
> --- a/auto/options
> +++ b/auto/options
> @@ -146,6 +146,7 @@ PCRE=NONE
>  PCRE_OPT=
>  PCRE_CONF_OPT=
>  PCRE_JIT=NO
> +PCRE2=YES
>
>  USE_OPENSSL=NO
>  OPENSSL=NONE
> @@ -357,6 +358,7 @@ use the \"--with-mail_ssl_module\" optio
>          --with-pcre=*)                   PCRE="$value"              ;;
>          --with-pcre-opt=*)               PCRE_OPT="$value"          ;;
>          --with-pcre-jit)                 PCRE_JIT=YES               ;;
> +        --without-pcre2)                 PCRE2=DISABLED             ;;
>
>          --with-openssl=*)                OPENSSL="$value"           ;;
>          --with-openssl-opt=*)            OPENSSL_OPT="$value"       ;;
> @@ -573,6 +575,7 @@ cat << END
>    --with-pcre=DIR                    set path to PCRE library sources
>    --with-pcre-opt=OPTIONS            set additional build options for PCRE
>    --with-pcre-jit                    build PCRE with JIT compilation support
> +  --without-pcre2                    do not use PCRE2 library
>
>    --with-zlib=DIR                    set path to zlib library sources
>    --with-zlib-opt=OPTIONS            set additional build options for zlib
> diff --git a/auto/summary b/auto/summary
> --- a/auto/summary
> +++ b/auto/summary
> @@ -16,9 +16,9 @@ if [ $USE_PCRE = DISABLED ]; then
>
>  else
>      case $PCRE in
> -        YES)   echo "  + using system PCRE library" ;;
> +        YES)   echo "  + using system $PCRE_LIBRARY library" ;;
>          NONE)  echo "  + PCRE library is not used" ;;
> -        *)     echo "  + using PCRE library: $PCRE" ;;
> +        *)     echo "  + using $PCRE_LIBRARY library: $PCRE" ;;
>      esac
>  fi
>
> diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c
> --- a/src/core/ngx_regex.c
> +++ b/src/core/ngx_regex.c
> @@ -15,8 +15,16 @@ typedef struct {
>  } ngx_regex_conf_t;
>
>
> +static ngx_inline void ngx_regex_malloc_init(ngx_pool_t *pool);
> +static ngx_inline void ngx_regex_malloc_done(void);
> +
> +#if (NGX_PCRE2)
> +static void * ngx_libc_cdecl ngx_regex_malloc(size_t size, void *data);
> +static void ngx_libc_cdecl ngx_regex_free(void *p, void *data);
> +#else
>  static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
>  static void ngx_libc_cdecl ngx_regex_free(void *p);
> +#endif
>  static void ngx_regex_cleanup(void *data);
>
>  static ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle);
> @@ -64,15 +72,24 @@ ngx_module_t  ngx_regex_module = {
>  };
>
>
> -static ngx_pool_t  *ngx_regex_pool;
> -static ngx_list_t  *ngx_regex_studies;
> +static ngx_pool_t             *ngx_regex_pool;
> +static ngx_list_t             *ngx_regex_studies;
> +static ngx_uint_t              ngx_regex_direct_alloc;
> +
> +#if (NGX_PCRE2)
> +static pcre2_compile_context  *ngx_regex_compile_context;
> +static pcre2_match_data       *ngx_regex_match_data;
> +static ngx_uint_t              ngx_regex_match_data_size;
> +#endif
>
>
>  void
>  ngx_regex_init(void)
>  {
> +#if !(NGX_PCRE2)
>      pcre_malloc = ngx_regex_malloc;
>      pcre_free = ngx_regex_free;
> +#endif
>  }
>
>
> @@ -80,6 +97,7 @@ static ngx_inline void
>  ngx_regex_malloc_init(ngx_pool_t *pool)
>  {
>      ngx_regex_pool = pool;
> +    ngx_regex_direct_alloc = (pool == NULL) ? 1 : 0;
>  }
>
>
> @@ -87,9 +105,146 @@ static ngx_inline void
>  ngx_regex_malloc_done(void)
>  {
>      ngx_regex_pool = NULL;
> +    ngx_regex_direct_alloc = 0;
>  }
>
>
> +#if (NGX_PCRE2)
> +
> +ngx_int_t
> +ngx_regex_compile(ngx_regex_compile_t *rc)
> +{
> +    int                     n, errcode;
> +    char                   *p;
> +    u_char                  errstr[128];
> +    size_t                  erroff;
> +    pcre2_code             *re;
> +    ngx_regex_elt_t        *elt;
> +    pcre2_general_context  *gctx;
> +    pcre2_compile_context  *cctx;
> +
> +    if (ngx_regex_compile_context == NULL) {
> +        /*
> +         * Allocte a compile context if not yet allocated.  This uses
> +         * direct allocations from heap, so the result can be cached
> +         * even at runtime.
> +         */
> +
> +        ngx_regex_malloc_init(NULL);
> +
> +        gctx = pcre2_general_context_create(ngx_regex_malloc, ngx_regex_free,
> +                                            NULL);
> +        if (gctx == NULL) {
> +            ngx_regex_malloc_done();
> +            goto nomem;
> +        }
> +
> +        cctx = pcre2_compile_context_create(gctx);
> +        if (cctx == NULL) {
> +            pcre2_general_context_free(gctx);
> +            ngx_regex_malloc_done();
> +            goto nomem;
> +        }
> +
> +        ngx_regex_compile_context = cctx;
> +
> +        pcre2_general_context_free(gctx);
> +        ngx_regex_malloc_done();
> +    }
> +
> +    ngx_regex_malloc_init(rc->pool);
> +
> +    re = pcre2_compile(rc->pattern.data, rc->pattern.len,
> +                       (uint32_t) rc->options, &errcode, &erroff,
> +                       ngx_regex_compile_context);
> +
> +    /* ensure that there is no current pool */
> +    ngx_regex_malloc_done();
> +
> +    if (re == NULL) {
> +        pcre2_get_error_message(errcode, errstr, 128);
> +
> +        if ((size_t) erroff == rc->pattern.len) {
> +            rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
> +                              "pcre2_compile() failed: %s in \"%V\"",
> +                               errstr, &rc->pattern)
> +                          - rc->err.data;
> +
> +        } else {
> +            rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
> +                              "pcre2_compile() failed: %s in \"%V\" at \"%s\"",
> +                               errstr, &rc->pattern, rc->pattern.data + erroff)
> +                          - rc->err.data;
> +        }
> +
> +        return NGX_ERROR;
> +    }
> +
> +    rc->regex = re;
> +
> +    /* do not study at runtime */
> +
> +    if (ngx_regex_studies != NULL) {
> +        elt = ngx_list_push(ngx_regex_studies);
> +        if (elt == NULL) {
> +            goto nomem;
> +        }
> +
> +        elt->regex = rc->regex;
> +        elt->name = rc->pattern.data;
> +    }
> +
> +    n = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &rc->captures);
> +    if (n < 0) {
> +        p = "pcre2_pattern_info(\"%V\", PCRE2_INFO_CAPTURECOUNT) failed: %d";
> +        goto failed;
> +    }
> +
> +    if (rc->captures == 0) {
> +        return NGX_OK;
> +    }
> +
> +    n = pcre2_pattern_info(re, PCRE2_INFO_NAMECOUNT, &rc->named_captures);
> +    if (n < 0) {
> +        p = "pcre2_pattern_info(\"%V\", PCRE2_INFO_NAMECOUNT) failed: %d";
> +        goto failed;
> +    }
> +
> +    if (rc->named_captures == 0) {
> +        return NGX_OK;
> +    }
> +
> +    n = pcre2_pattern_info(re, PCRE2_INFO_NAMEENTRYSIZE, &rc->name_size);
> +    if (n < 0) {
> +        p = "pcre2_pattern_info(\"%V\", PCRE2_INFO_NAMEENTRYSIZE) failed: %d";
> +        goto failed;
> +    }
> +
> +    n = pcre2_pattern_info(re, PCRE2_INFO_NAMETABLE, &rc->names);
> +    if (n < 0) {
> +        p = "pcre2_pattern_info(\"%V\", PCRE2_INFO_NAMETABLE) failed: %d";
> +        goto failed;
> +    }
> +
> +    return NGX_OK;
> +
> +failed:
> +
> +    rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
> +                  - rc->err.data;
> +    return NGX_ERROR;
> +
> +nomem:
> +
> +    rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
> +                               "regex \"%V\" compilation failed: no memory",
> +                               &rc->pattern)
> +                  - rc->err.data;
> +    return NGX_ERROR;
> +}
> +
> +#else
> +
>  ngx_int_t
>  ngx_regex_compile(ngx_regex_compile_t *rc)
>  {
> @@ -192,6 +347,74 @@ nomem:
>      return NGX_ERROR;
>  }
>
> +#endif
> +
> +
> +#if (NGX_PCRE2)
> +
> +ngx_int_t
> +ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_uint_t size)
> +{
> +    size_t      *ov;
> +    ngx_int_t    rc;
> +    ngx_uint_t   n, i;
> +
> +    /*
> +     * The pcre2_match() function might allocate memory for backtracking
> +     * frames, typical allocations are from 40k and above.  So the allocator
> +     * is configured to do direct allocations from heap during matching.
> +     */
> +
> +    ngx_regex_malloc_init(NULL);
> +
> +    if (ngx_regex_match_data == NULL
> +        || size > ngx_regex_match_data_size)
> +    {
> +        /*
> +         * Allocate a match data if not yet allocated or smaller than
> +         * needed.
> +         */
> +
> +        if (ngx_regex_match_data) {
> +            pcre2_match_data_free(ngx_regex_match_data);
> +        }
> +
> +        ngx_regex_match_data_size = size;
> +        ngx_regex_match_data = pcre2_match_data_create(size / 3, NULL);
> +
> +        if (ngx_regex_match_data == NULL) {
> +            rc = PCRE2_ERROR_NOMEMORY;
> +            goto failed;
> +        }
> +    }
> +
> +    rc = pcre2_match(re, s->data, s->len, 0, 0, ngx_regex_match_data, NULL);
> +
> +    if (rc < 0) {
> +        goto failed;
> +    }
> +
> +    n = pcre2_get_ovector_count(ngx_regex_match_data);
> +    ov = pcre2_get_ovector_pointer(ngx_regex_match_data);
> +
> +    if (n > size / 3) {
> +        n = size / 3;
> +    }
> +
> +    for (i = 0; i < n; i++) {
> +        captures[i * 2] = ov[i * 2];
> +        captures[i * 2 + 1] = ov[i * 2 + 1];
> +    }
> +
> +failed:
> +
> +    ngx_regex_malloc_done();
> +
> +    return rc;
> +}
> +
> +#endif
> +
>
>  ngx_int_t
>  ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
> @@ -226,6 +449,35 @@ ngx_regex_exec_array(ngx_array_t *a, ngx
>  }
>
>
> +#if (NGX_PCRE2)
> +
> +static void * ngx_libc_cdecl
> +ngx_regex_malloc(size_t size, void *data)
> +{
> +    if (ngx_regex_pool) {
> +        return ngx_palloc(ngx_regex_pool, size);
> +    }
> +
> +    if (ngx_regex_direct_alloc) {
> +        return ngx_alloc(size, ngx_cycle->log);
> +    }
> +
> +    return NULL;
> +}
> +
> +
> +static void ngx_libc_cdecl
> +ngx_regex_free(void *p, void *data)
> +{
> +    if (ngx_regex_direct_alloc) {
> +        ngx_free(p);
> +    }
> +
> +    return;
> +}
> +
> +#else
> +
>  static void * ngx_libc_cdecl
>  ngx_regex_malloc(size_t size)
>  {
> @@ -243,11 +495,13 @@ ngx_regex_free(void *p)
>      return;
>  }
>
> +#endif
> +
>
>  static void
>  ngx_regex_cleanup(void *data)
>  {
> -#if (NGX_HAVE_PCRE_JIT)
> +#if (NGX_PCRE2 || NGX_HAVE_PCRE_JIT)
>      ngx_regex_conf_t *rcf = data;
>
>      ngx_uint_t        i;
> @@ -272,12 +526,17 @@ ngx_regex_cleanup(void *data)
>          /*
>           * The PCRE JIT compiler uses mmap for its executable codes, so we
>           * have to explicitly call the pcre_free_study() function to free
> -         * this memory.
> +         * this memory.  In PCRE2, we call the pcre2_code_free() function
> +         * for the same reason.
>           */
>
> +#if (NGX_PCRE2)
> +        pcre2_code_free(elts[i].regex);
> +#else
>          if (elts[i].regex->extra != NULL) {
>              pcre_free_study(elts[i].regex->extra);
>          }
> +#endif
>      }
>  #endif
>
> @@ -287,6 +546,26 @@ ngx_regex_cleanup(void *data)
>       */
>
>      ngx_regex_studies = NULL;
> +
> +#if (NGX_PCRE2)
> +
> +    /*
> +     * Free compile context and match data.  If needed at runtime by
> +     * the new cycle, these will be re-allocated.
> +     */
> +
> +    if (ngx_regex_compile_context) {
> +        pcre2_compile_context_free(ngx_regex_compile_context);
> +        ngx_regex_compile_context = NULL;
> +    }
> +
> +    if (ngx_regex_match_data) {
> +        pcre2_match_data_free(ngx_regex_match_data);
> +        ngx_regex_match_data = NULL;
> +        ngx_regex_match_data_size = 0;
> +    }
> +
> +#endif
>  }
>
>
> @@ -294,7 +573,9 @@ static ngx_int_t
>  ngx_regex_module_init(ngx_cycle_t *cycle)
>  {
>      int                opt;
> +#if !(NGX_PCRE2)
>      const char        *errstr;
> +#endif
>      ngx_uint_t         i;
>      ngx_list_part_t   *part;
>      ngx_regex_elt_t   *elts;
> @@ -304,10 +585,16 @@ ngx_regex_module_init(ngx_cycle_t *cycle
>
>      rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
>
> -#if (NGX_HAVE_PCRE_JIT)
> +#if (NGX_PCRE2 || NGX_HAVE_PCRE_JIT)
> +
>      if (rcf->pcre_jit) {
> +#if (NGX_PCRE2)
> +        opt = 1;
> +#else
>          opt = PCRE_STUDY_JIT_COMPILE;
> +#endif
>      }
> +
>  #endif
>
>      ngx_regex_malloc_init(cycle->pool);
> @@ -327,6 +614,23 @@ ngx_regex_module_init(ngx_cycle_t *cycle
>              i = 0;
>          }
>
> +#if (NGX_PCRE2)
> +
> +        if (opt) {
> +            int  n;
> +
> +            n = pcre2_jit_compile(elts[i].regex, PCRE2_JIT_COMPLETE);
> +
> +            if (n != 0) {
> +                ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
> +                              "pcre2_jit_compile() failed: %d in \"%s\", "
> +                              "ignored",
> +                              n, elts[i].name);
> +            }
> +        }
> +
> +#else
> +
>          elts[i].regex->extra = pcre_study(elts[i].regex->code, opt, &errstr);
>
>          if (errstr != NULL) {
> @@ -350,11 +654,15 @@ ngx_regex_module_init(ngx_cycle_t *cycle
>              }
>          }
>  #endif
> +#endif
>      }
>
>      ngx_regex_malloc_done();
>
>      ngx_regex_studies = NULL;
> +#if (NGX_PCRE2)
> +    ngx_regex_compile_context = NULL;
> +#endif
>
>      return NGX_OK;
>  }
> @@ -412,7 +720,21 @@ ngx_regex_pcre_jit(ngx_conf_t *cf, void
>          return NGX_CONF_OK;
>      }
>
> -#if (NGX_HAVE_PCRE_JIT)
> +#if (NGX_PCRE2)
> +    {
> +    int       r;
> +    uint32_t  jit;
> +
> +    jit = 0;
> +    r = pcre2_config(PCRE2_CONFIG_JIT, &jit);
> +
> +    if (r != 0 || jit != 1) {
> +        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
> +                           "PCRE2 library does not support JIT");
> +        *fp = 0;
> +    }
> +    }
> +#elif (NGX_HAVE_PCRE_JIT)
>      {
>      int  jit, r;
>
> diff --git a/src/core/ngx_regex.h b/src/core/ngx_regex.h
> --- a/src/core/ngx_regex.h
> +++ b/src/core/ngx_regex.h
> @@ -12,19 +12,31 @@
>  #include <ngx_config.h>
>  #include <ngx_core.h>
>
> +
> +#if (NGX_PCRE2)
> +
> +#define PCRE2_CODE_UNIT_WIDTH  8
> +#include <pcre2.h>
> +
> +#define NGX_REGEX_NO_MATCHED   PCRE2_ERROR_NOMATCH   /* -1 */
> +#define NGX_REGEX_CASELESS     PCRE2_CASELESS
> +
> +typedef pcre2_code  ngx_regex_t;
> +
> +#else
> +
>  #include <pcre.h>
>
> -
> -#define NGX_REGEX_NO_MATCHED  PCRE_ERROR_NOMATCH   /* -1 */
> -
> -#define NGX_REGEX_CASELESS    PCRE_CASELESS
> -
> +#define NGX_REGEX_NO_MATCHED   PCRE_ERROR_NOMATCH   /* -1 */
> +#define NGX_REGEX_CASELESS     PCRE_CASELESS
>
>  typedef struct {
>      pcre        *code;
>      pcre_extra  *extra;
>  } ngx_regex_t;
>
> +#endif
> +
>
>  typedef struct {
>      ngx_str_t     pattern;
> @@ -49,10 +61,20 @@ typedef struct {
>  void ngx_regex_init(void);
>  ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
>
> +#if (NGX_PCRE2)
> +
> +ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures,
> +    ngx_uint_t size);
> +#define ngx_regex_exec_n       "pcre2_match()"
> +
> +#else
> +
>  #define ngx_regex_exec(re, s, captures, size)                                \
>      pcre_exec(re->code, re->extra, (const char *) (s)->data, (s)->len, 0, 0, \
>                captures, size)
> -#define ngx_regex_exec_n      "pcre_exec()"
> +#define ngx_regex_exec_n       "pcre_exec()"
> +
> +#endif
>
>  ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log);
>
>
> --
> Maxim Dounin
> http://mdounin.ru/
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel


More information about the nginx-devel mailing list