X
X
XEHKOK2019-11-02 12:29:52
Apache HTTP Server
XEHKOK, 2019-11-02 12:29:52

How to make PCRE2 support for Apache 2.4?

Good day to all.
The next question is trying to upgrade Apache 2.4.41 to PCRE2 10.33, since the latest version still lacks PCRE2 support due to backwards compatibility with PCRE.
I downloaded the Apache 2.4.41 sources, edit the source file to work with PCRE: util_pcre.c
I corrected some functions/constants such as: PCRE2_INFO_NAMECOUNT, PCRE2_INFO_NAMEENTRYSIZE, PCRE2_INFO_NAMETABLE, that is, from PCRE_DEFINE to PCRE2_DEFINE, etc.
Also, instead of pcre.h, I included the source from PCRE2: pcre2.h

spoiler
#include "pcre2.h"
The error is somewhere in this piece of util_pcre.c code:
#include "httpd.h"
#include "apr_strings.h"
#include "apr_tables.h"
#define PCRE2_CODE_UNIT_WIDTH (0)
#include "pcre2.h"

#define APR_WANT_STRFUNC
#include "apr_want.h"

#ifndef POSIX_MALLOC_THRESHOLD
#define POSIX_MALLOC_THRESHOLD (10)
#endif

/* Table of error strings corresponding to POSIX error codes; must be
 * kept in synch with include/ap_regex.h's AP_REG_E* definitions.
 */

static const char *const pstring[] = {
    "",                         /* Dummy for value 0 */
    "internal error",           /* AP_REG_ASSERT */
    "failed to get memory",     /* AP_REG_ESPACE */
    "bad argument",             /* AP_REG_INVARG */
    "match failed"              /* AP_REG_NOMATCH */
};

AP_DECLARE(apr_size_t) ap_regerror(int errcode, const ap_regex_t *preg,
                                   char *errbuf, apr_size_t errbuf_size)
{
    const char *message, *addmessage;
    apr_size_t length, addlength;

    message = (errcode >= (int)(sizeof(pstring) / sizeof(char *))) ?
              "unknown error code" : pstring[errcode];
    length = strlen(message) + 1;

    addmessage = " at offset ";
    addlength = (preg != NULL && (int)preg->re_erroffset != -1) ?
                strlen(addmessage) + 6 : 0;

    if (errbuf_size > 0) {
        if (addlength > 0 && errbuf_size >= length + addlength)
            apr_snprintf(errbuf, errbuf_size, "%s%s%-6d", message, addmessage,
                         (int)preg->re_erroffset);
        else
            apr_cpystrn(errbuf, message, errbuf_size);
    }

    return length + addlength;
}




/*************************************************
 *           Free store held by a regex          *
 *************************************************/

AP_DECLARE(void) ap_regfree(ap_regex_t *preg)
{
    (pcre2_code_free)(preg->re_pcre);
}




/*************************************************
 *            Compile a regular expression       *
 *************************************************/

static int default_cflags = AP_REG_DOTALL |
                            AP_REG_DOLLAR_ENDONLY;

AP_DECLARE(int) ap_regcomp_get_default_cflags(void)
{
    return default_cflags;
}

AP_DECLARE(void) ap_regcomp_set_default_cflags(int cflags)
{
    default_cflags = cflags;
}

AP_DECLARE(int) ap_regcomp_default_cflag_by_name(const char *name)
{
    int cflag = 0;

    if (ap_cstr_casecmp(name, "ICASE") == 0) {
        cflag = AP_REG_ICASE;
    }
    else if (ap_cstr_casecmp(name, "DOTALL") == 0) {
        cflag = AP_REG_DOTALL;
    }
    else if (ap_cstr_casecmp(name, "DOLLAR_ENDONLY") == 0) {
        cflag = AP_REG_DOLLAR_ENDONLY;
    }
    else if (ap_cstr_casecmp(name, "EXTENDED") == 0) {
        cflag = AP_REG_EXTENDED;
    }

    return cflag;
}

/*
 * Arguments:
 *  preg        points to a structure for recording the compiled expression
 *  pattern     the pattern to compile
 *  cflags      compilation flags
 *
 * Returns:      0 on success
 *               various non-zero codes on failure
*/
AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags)
{
    const char *errorptr;
    int erroffset;
    int errcode = 0;
    int options = PCRE2_DUPNAMES;

    cflags |= default_cflags;
    if ((cflags & AP_REG_ICASE) != 0)
        options |= PCRE2_CASELESS;
    if ((cflags & AP_REG_NEWLINE) != 0)
        options |= PCRE2_MULTILINE;
    if ((cflags & AP_REG_DOTALL) != 0)
        options |= PCRE2_DOTALL;
    if ((cflags & AP_REG_DOLLAR_ENDONLY) != 0)
        options |= PCRE2_DOLLAR_ENDONLY;

    preg->re_pcre =
        pcre2_compile(pattern, options, &errcode, &errorptr, &erroffset, NULL);
    preg->re_erroffset = erroffset;

    if (preg->re_pcre == NULL) {
        /*
         * There doesn't seem to be constants defined for compile time error
         * codes. 21 is "failed to get memory" according to pcreapi(3).
         */
        if (errcode == 21)
            return AP_REG_ESPACE;
        return AP_REG_INVARG;
    }

    pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
                   PCRE2_INFO_CAPTURECOUNT, &(preg->re_nsub));
    return 0;
}

When compiling make in the console, I get the following errors:
spoiler
In file included from util_pcre.c:59:0:
util_pcre.c: In function ‘ap_regfree’:
/etc/webserver/pcre2-1033/include/pcre2.h:825:60: error: ‘pcre2_code_free_’ undeclared (first use in this function)
 #define pcre2_code_free                       PCRE2_SUFFIX(pcre2_code_free_)
/etc/webserver/pcre2-1033/include/pcre2.h:966:25: note: in definition of macro ‘PCRE2_SUFFIX’
 #define PCRE2_SUFFIX(a) a
util_pcre.c:114:6: note: in expansion of macro ‘pcre2_code_free’
     (pcre2_code_free)(preg->re_pcre);
/etc/webserver/pcre2-1033/include/pcre2.h:825:60: note: each undeclared identifier is reported only once for each function it appears in
 #define pcre2_code_free                       PCRE2_SUFFIX(pcre2_code_free_)
/etc/webserver/pcre2-1033/include/pcre2.h:966:25: note: in definition of macro ‘PCRE2_SUFFIX’
 #define PCRE2_SUFFIX(a) a
util_pcre.c:114:6: note: in expansion of macro ‘pcre2_code_free’
     (pcre2_code_free)(preg->re_pcre);
util_pcre.c: In function ‘ap_regcomp’:
/etc/webserver/pcre2-1033/include/pcre2.h:826:60: warning: implicit declaration of function ‘pcre2_compile_’ [-Wimplicit-function-declaration]
 #define pcre2_compile                         PCRE2_SUFFIX(pcre2_compile_)
/etc/webserver/pcre2-1033/include/pcre2.h:966:25: note: in definition of macro ‘PCRE2_SUFFIX’
 #define PCRE2_SUFFIX(a) a
util_pcre.c:184:9: note: in expansion of macro ‘pcre2_compile’
         pcre2_compile(pattern, options, &errcode, &errorptr, &erroffset, NULL);
util_pcre.c:183:19: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     preg->re_pcre =
util_pcre.c:197:5: warning: implicit declaration of function ‘pcre_fullinfo’ [-Wimplicit-function-declaration]
     pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
util_pcre.c:197:26: error: unknown type name ‘pcre’
     pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
util_pcre.c: In function ‘ap_regexec_len’:
util_pcre.c:253:10: warning: implicit declaration of function ‘pcre_exec’ [-Wimplicit-function-declaration]
     rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len,
util_pcre.c:253:27: error: unknown type name ‘pcre’
     rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len,
util_pcre.c: In function ‘ap_regname’:
util_pcre.c:315:26: error: unknown type name ‘pcre’
     pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
util_pcre.c:317:26: error: unknown type name ‘pcre’
     pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
util_pcre.c:319:26: error: unknown type name ‘pcre’
     pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
/etc/webserver/srcsrv/httpd-2.4.41/build/rules.mk:206: recipe for target 'util_pcre.lo' failed
make[2]: *** [util_pcre.lo] Error 1
make[2]: Leaving directory '/etc/webserver/srcsrv/httpd-2.4.41/server'
/etc/webserver/srcsrv/httpd-2.4.41/build/rules.mk:75: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/etc/webserver/srcsrv/httpd-2.4.41/server'
/etc/webserver/srcsrv/httpd-2.4.41/build/rules.mk:75: recipe for target 'all-recursive' failed
make: *** [all-recursive] Error 1

People please tell me which way to dig, and what I'm doing wrong, I just don't know this language and its features.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
X
XEHKOK, 2019-11-02
@XEHKOK

I figured out a little about this issue and found updated sources for PCRE-PCRE2 backward compatibility.
You need to do the Apache configuration:
Next, you need to download two sources such as ap_regex.h and util_pcre.c, the links are below:
ap_regex.h
util_pcre.c
The Apache git already has these files, they are written under PCRE and PCRE2, depending on the version, support will be waiting for us in the next version of apache PCRE2 Hooray comrades))
After completing the apr-1.7.0 configuration, you need to change the apr-1.7.0/build/apr_rules.mk file in this directory, and you need to add to the end of the line where:
Library connection: After these changes, you need to compile apr-1.7 .0

make
make install

And then you also need to compile APR-util from the source.
You also need to find the ap_config_auto.h file, it is located in the directory: httpd-2.4.41/include
Insert the following lines in ap_config_auto.h itself:
/* Load PCRE2 */
#define HAVE_PCRE2 1

After these steps, you can compile and enjoy:
make
make install

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question