Description: Port to PCRE2.
Bug-Debian: https://bugs.debian.org/1000027
Author: Yavor Doganov <yavor@gnu.org>
Forwarded: no
Last-Update: 2023-11-21
---

--- awffull.orig/configure.ac
+++ awffull/configure.ac
@@ -266,7 +266,7 @@
                  [echo "Missing GD TrueType Font Config Capability"])
 fi
 
-AC_CHECK_LIB([pcre], [main],[], [echo "Missing Perl Reg. Ex. Library" ; exit])
+AC_CHECK_LIB([pcre2-8], [main],[], [echo "Missing Perl Reg. Ex. Library" ; exit])
 if test "$ENABLE_GEOIP" = "yes"; then
     AC_CHECK_LIB([GeoIP], [main],[], [echo "Missing GeoIP Library" ; ENABLE_GEOIP="no"])
 fi
@@ -286,9 +286,8 @@
 AC_CHECK_HEADERS([getopt.h], [], [echo "Missing getopt.h" ; exit])
 AC_CHECK_HEADERS([math.h], [], [echo "Missing math.h" ; exit])
 AC_CHECK_HEADERS([zlib.h], [], [echo "Missing zlib.h" ; exit])
-AC_CHECK_HEADERS([pcre.h], [],
-                 [ AC_CHECK_HEADERS([pcre/pcre.h], [], [ echo "Missing pcre.h" ; exit ] ])
-         )
+AC_CHECK_HEADERS([pcre2.h], [], [echo "Missing pcre2.h" ; exit],
+                            [[#define PCRE2_CODE_UNIT_WIDTH 8]])
 AC_CHECK_HEADERS([ctype.h], [], [echo "Missing ctype.h" ; exit])
 AC_CHECK_HEADERS([sys/utsname.h], [], [echo "Missing sys/utsname.h" ; exit])
 AC_CHECK_HEADERS([sys/times.h], [], [echo "Missing sys/times.h" ; exit])
--- awffull.orig/src/common.h
+++ awffull/src/common.h
@@ -105,11 +105,10 @@
 #endif          /* not __bool_true_false_are_defined */
 
 
-#if HAVE_PCRE_H
-# include <pcre.h>
-#elif HAVE_PCRE_PCRE_H
-# include <pcre/pcre.h>
-#endif          /* HAVE_PCRE_H */
+#if HAVE_PCRE2_H
+#define PCRE2_CODE_UNIT_WIDTH 8
+# include <pcre2.h>
+#endif          /* HAVE_PCRE2_H */
 
 #if HAVE_MATH_H
 # include <math.h>
--- awffull.orig/src/parser.c
+++ awffull/src/parser.c
@@ -40,17 +40,17 @@
 
 static int identify_log_format(char *);
 static void re_compile_all_regexes(void);       /* Use at first run - compiles all used regex's */
-static void re_compile_failed(int, const char *, char *);       /* Display a failed RE Compile & where */
+static void re_compile_failed(size_t, int, char *);       /* Display a failed RE Compile & where */
 static void re_check_errors(int);               /* After an RE check, deal with any errors */
 static void error_substring_extract(int, int);  /* Error when we fail on getting a substring */
 
-static pcre *cmp_log_regexp = NULL;             /* Main compiled RE - use as pointer only to one of the below */
-static pcre *cmp_log_regexp_clf = NULL;         /* CLF compiled RE */
-static pcre *cmp_log_regexp_combined = NULL;    /* Combined compiled RE */
-static pcre *cmp_log_regexp_combined_enhanced = NULL;   /* Enhanced Combined compiled RE */
-static pcre *cmp_log_regexp_xferlog = NULL;     /* FTP, xferlog format compiled RE */
-static pcre *cmp_log_regexp_squid = NULL;       /* SQUID format compiled RE */
-static pcre *cmp_log_regexp_domino = NULL;      /* Lotus Domino v6 format compiled RE */
+static pcre2_code *cmp_log_regexp = NULL;             /* Main compiled RE - use as pointer only to one of the below */
+static pcre2_code *cmp_log_regexp_clf = NULL;         /* CLF compiled RE */
+static pcre2_code *cmp_log_regexp_combined = NULL;    /* Combined compiled RE */
+static pcre2_code *cmp_log_regexp_combined_enhanced = NULL;   /* Enhanced Combined compiled RE */
+static pcre2_code *cmp_log_regexp_xferlog = NULL;     /* FTP, xferlog format compiled RE */
+static pcre2_code *cmp_log_regexp_squid = NULL;       /* SQUID format compiled RE */
+static pcre2_code *cmp_log_regexp_domino = NULL;      /* Lotus Domino v6 format compiled RE */
 
 //pcre_extra *studied_log_regexp = NULL;
 
@@ -123,48 +123,59 @@
 static int
 parse_record_ftp(char *buffer, struct log_struct *log_rec)
 {
-    int ovector[OVECCOUNT];                     /* RE substring offsets array */
+    pcre2_match_data *ovector;                  /* RE substring offsets array */
     int rc;                                     /* RE Check return value */
     int copy_substr_rtn;                        /* RE Check return from pcre_copy_substring */
 
     int buffer_length;
+    size_t pcre2len;
 
     char tmp_bytes[25 + 1];
     char completion_status[2 + 1];
 
     buffer_length = (int) strlen(buffer);
-    rc = pcre_exec(cmp_log_regexp, NULL, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
+    ovector = pcre2_match_data_create(OVECCOUNT, NULL);
+    rc = pcre2_match(cmp_log_regexp, buffer, buffer_length, 0, 0, ovector, NULL);
     /* check for RE matching errors */
     if (rc < 0) {
         re_check_errors(rc);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 1, log_rec->datetime, 29);
+    pcre2len = 29;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 1, log_rec->datetime, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 1);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
     /* Ignore time taken (in seconds) for now... */
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 3, log_rec->hostname, MAXHOST);
+    pcre2len = MAXHOST;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 3, log_rec->hostname, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 3);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 4, tmp_bytes, 20);
+    pcre2len = 20;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 4, tmp_bytes, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 4);
+        pcre2_match_data_free(ovector);
         return (0);
     }
     log_rec->xfer_size = strtoul(tmp_bytes, NULL, 10);
 
     /* URL */
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 5, log_rec->url, MAXURL);
+    pcre2len = MAXURL;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 5, log_rec->url, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 5);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
@@ -173,16 +184,20 @@
     /* Ignore Direction */
 
     /* User */
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 10, log_rec->ident, MAXIDENT);
+    pcre2len = MAXIDENT;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 10, log_rec->ident, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 10);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
     /* Completion Status - fake to a 200 or 206 */
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 14, completion_status, 2);
+    pcre2len = 2;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 14, completion_status, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 14);
+        pcre2_match_data_free(ovector);
         return (0);
     }
     if (completion_status[0] == 'i') {
@@ -192,6 +207,7 @@
         log_rec->resp_code = 200;
     }
 
+    pcre2_match_data_free(ovector);
     return (1);
 }
 
@@ -202,18 +218,20 @@
 static int
 parse_record_web(char *buffer, struct log_struct *log_rec)
 {
-    int ovector[OVECCOUNT];                     /* RE substring offsets array */
+    pcre2_match_data *ovector;                  /* RE substring offsets array */
     int rc;                                     /* RE Check return value */
     int copy_substr_rtn;                        /* RE Check return from pcre_copy_substring */
 
     int buffer_length;
+    size_t pcre2len;
 
     char tmp_status[5 + 1];
     char tmp_bytes[20 + 1];
 
     buffer_length = (int) strlen(buffer);
+    ovector = pcre2_match_data_create(OVECCOUNT, NULL);
 //    rc = pcre_exec (cmp_log_regexp, studied_log_regexp, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
-    rc = pcre_exec(cmp_log_regexp, NULL, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
+    rc = pcre2_match(cmp_log_regexp, buffer, buffer_length, 0, 0, ovector, NULL);
     /* check for RE matching errors */
     if (rc < 0) {
         /* First see if a normal enhanced regex will work.
@@ -224,13 +242,13 @@
         if ((cmp_log_regexp != cmp_log_regexp_domino) && (cmp_log_regexp == cmp_log_regexp_combined) && (g_settings.settings.log_type == LOG_COMBINED)) {
             /* Attempt an enhanced log match */
             VPRINT(VERBOSE1, "%s\n", _("Attempting COMBINED_ENHANCED Regular Expression"));
-            rc = pcre_exec(cmp_log_regexp_combined_enhanced, NULL, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
+            rc = pcre2_match(cmp_log_regexp_combined_enhanced, buffer, buffer_length, 0, 0, ovector, NULL);
 
             /* Didn't work. Try Domino? */
             if (rc < 0 && g_settings.flags.force_log_type == false) {
                 /* Try a domino log format first - if is, switch to using domino checks instead */
                 VPRINT(VERBOSE1, "%s\n", _("Attempting COMBINED_DOMINO Regular Expression"));
-                rc = pcre_exec(cmp_log_regexp_domino, NULL, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
+                rc = pcre2_match(cmp_log_regexp_domino, buffer, buffer_length, 0, 0, ovector, NULL);
                 if (rc >= 0) {
                     /* Successfully matched as a Domino Log, apply domino RE from here on */
                     /* FIXME: The default domino RegEx is perhaps not as quick - is based on the ENHANCED */
@@ -241,60 +259,78 @@
         }
         if (rc < 0) {
             re_check_errors(rc);
+            pcre2_match_data_free(ovector);
             return (0);
         }
     }
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, LF_NCSA_ADDRESS, log_rec->hostname, MAXHOST - 1);
+    pcre2len = MAXHOST - 1;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, LF_NCSA_ADDRESS, log_rec->hostname, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, LF_NCSA_ADDRESS);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, LF_NCSA_AUTHUSER, log_rec->ident, MAXIDENT - 1);
+    pcre2len = MAXIDENT - 1;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, LF_NCSA_AUTHUSER, log_rec->ident, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, LF_NCSA_USER);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, LF_NCSA_DATE_TIME, log_rec->datetime, MAXDATETIME - 1);
+    pcre2len = MAXDATETIME - 1;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, LF_NCSA_DATE_TIME, log_rec->datetime, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, LF_NCSA_DATE_TIME);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, LF_NCSA_URL, log_rec->url, MAXURL - 1);
+    pcre2len = MAXURL - 1;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, LF_NCSA_URL, log_rec->url, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, LF_NCSA_URL);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, LF_NCSA_STATUS, tmp_status, 5);
+    pcre2len = 5;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, LF_NCSA_STATUS, tmp_status, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, LF_NCSA_STATUS);
+        pcre2_match_data_free(ovector);
         return (0);
     }
     log_rec->resp_code = atoi(tmp_status);
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, LF_NCSA_BYTES, tmp_bytes, 20);
+    pcre2len = 20;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, LF_NCSA_BYTES, tmp_bytes, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, LF_NCSA_BYTES);
+        pcre2_match_data_free(ovector);
         return (0);
     }
     log_rec->xfer_size = strtoul(tmp_bytes, NULL, 10);
 
     if (g_settings.settings.log_type == LOG_COMBINED) {
-        copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, LF_NCSA_REFERER, log_rec->refer, MAXREF - 1);
+        pcre2len = MAXREF - 1;
+        copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, LF_NCSA_REFERER, log_rec->refer, &pcre2len);
         if (copy_substr_rtn < 0) {
             error_substring_extract(copy_substr_rtn, LF_NCSA_REFERER);
+            pcre2_match_data_free(ovector);
             return (0);
         }
-        copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, LF_NCSA_BROWSER, log_rec->agent, MAXAGENT - 1);
+        pcre2len = MAXAGENT - 1;
+        copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, LF_NCSA_BROWSER, log_rec->agent, &pcre2len);
         if (copy_substr_rtn < 0) {
             error_substring_extract(copy_substr_rtn, LF_NCSA_BROWSER);
+            pcre2_match_data_free(ovector);
             return (0);
         }
     }
+    pcre2_match_data_free(ovector);
     return (1);
 }
 
@@ -305,54 +341,68 @@
 static int
 parse_record_squid(char *buffer, struct log_struct *log_rec)
 {
-    int ovector[OVECCOUNT];                     /* RE substring offsets array */
+    pcre2_match_data *ovector;                  /* RE substring offsets array */
     int rc;                                     /* RE Check return value */
     int copy_substr_rtn;                        /* RE Check return from pcre_copy_substring */
 
     int buffer_length;
+    size_t pcre2len;
 
     char tmp_bytes[25 + 1];
 
     buffer_length = (int) strlen(buffer);
-    rc = pcre_exec(cmp_log_regexp, NULL, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
+    ovector = pcre2_match_data_create(OVECCOUNT, NULL);
+    rc = pcre2_match(cmp_log_regexp, buffer, buffer_length, 0, 0, ovector, NULL);
     /* check for RE matching errors */
     if (rc < 0) {
         re_check_errors(rc);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 1, log_rec->datetime, 29);
+    pcre2len = 29;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 1, log_rec->datetime, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 1);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 4, log_rec->hostname, MAXHOST - 1);
+    pcre2len = MAXHOST - 1;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 4, log_rec->hostname, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 1);
+        pcre2_match_data_free(ovector);
         return (0);
     }
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 6, tmp_bytes, 20);
+    pcre2len = 20;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 6, tmp_bytes, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 1);
+        pcre2_match_data_free(ovector);
         return (0);
     }
     log_rec->resp_code = strtoul(tmp_bytes, NULL, 10);
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 7, tmp_bytes, 20);
+    pcre2len = 20;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 7, tmp_bytes, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 1);
+        pcre2_match_data_free(ovector);
         return (0);
     }
     log_rec->xfer_size = strtoul(tmp_bytes, NULL, 10);
 
-    copy_substr_rtn = pcre_copy_substring(buffer, ovector, rc, 9, log_rec->url, MAXURL - 1);
+    pcre2len = MAXURL - 1;
+    copy_substr_rtn = pcre2_substring_copy_bynumber(ovector, 9, log_rec->url, &pcre2len);
     if (copy_substr_rtn < 0) {
         error_substring_extract(copy_substr_rtn, 1);
+pcre2_match_data_free(ovector);
         return (0);
     }
 
+    pcre2_match_data_free(ovector);
     return (1);
 }
 
@@ -382,10 +432,10 @@
 parse_check_not_page(char *url)
 {
     char regex_page[MAX_RE_LENGTH + 1] = "";    /* Hold the PAGE RE */
-    static pcre *cmp_regex_page = NULL;         /* NotPage compiled RE */
+    static pcre2_code *cmp_regex_page = NULL;   /* NotPage compiled RE */
 
-    const char *error;                          /* RE error pointer, offset */
-    int erroffset;                              /* RE error value */
+    int error;                                  /* RE error code */
+    size_t erroffset;                           /* RE error offset */
     int str_length, tmp_length;
     int rc;                                     /* RE Check return value */
     static int max_type_length = 0;
@@ -412,7 +462,7 @@
         VPRINT(VERBOSE2, "PCRE: New NotPAGE RegEx: '%s',  Max: %d\n", regex_page, max_type_length);
 
         /* Compile the RegEx */
-        cmp_regex_page = pcre_compile(regex_page, 0, &error, &erroffset, NULL);
+        cmp_regex_page = pcre2_compile(regex_page, strlen(regex_page), 0, &error, &erroffset, NULL);
         VPRINT(VERBOSE2, "PCRE: Compile PAGE%s", "\n");
         if (cmp_regex_page == NULL) {
             re_compile_failed(erroffset, error, regex_page);
@@ -429,7 +479,7 @@
     }
     VPRINT(VERBOSE4, "  Was: '%s', Is: %s\n", url, str_start);
 
-    rc = pcre_exec(cmp_regex_page, NULL, str_start, tmp_length, 0, 0, NULL, 0);
+    rc = pcre2_match(cmp_regex_page, str_start, tmp_length, 0, 0, NULL, NULL);
     /* check for RE matching */
     if (rc >= 0) {
         /* Have matched! */
@@ -466,10 +516,10 @@
 parse_is_page(char *url)
 {
     char regex_page[MAX_RE_LENGTH + 1] = "";    /* Hold the PAGE RE */
-    static pcre *cmp_regex_page = NULL;         /* Page compiled RE */
+    static pcre2_code *cmp_regex_page = NULL;   /* Page compiled RE */
 
-    const char *error;                          /* RE error pointer, offset */
-    int erroffset;                              /* RE error value */
+    int error;                                  /* RE error code */
+    size_t erroffset;                           /* RE error offset */
     int str_length;
     int rc;                                     /* RE Check return value */
     char reverse[MAXURL + 1] = "";
@@ -508,7 +558,7 @@
         VPRINT(VERBOSE2, "PCRE: New PAGE RegEx: '%s'\n", regex_page);
 
         /* Compile the RegEx */
-        cmp_regex_page = pcre_compile(regex_page, 0, &error, &erroffset, NULL);
+        cmp_regex_page = pcre2_compile(regex_page, strlen(regex_page), 0, &error, &erroffset, NULL);
         VPRINT(VERBOSE2, "PCRE: Compile PAGE%s", "\n");
         if (cmp_regex_page == NULL) {
             re_compile_failed(erroffset, error, regex_page);
@@ -524,7 +574,7 @@
     }
     *(reverse + j) = '\0';                      /* Probably not needed as we provide the length... */
 
-    rc = pcre_exec(cmp_regex_page, NULL, reverse, str_length, 0, 0, NULL, 0);
+    rc = pcre2_match(cmp_regex_page, reverse, str_length, 0, 0, NULL, NULL);
     /* check for RE matching */
     if (rc >= 0) {
         /* Have matched! */
@@ -546,7 +596,7 @@
 static int
 identify_log_format(char *buffer)
 {
-    int ovector[OVECCOUNT];                     /* RE substring offsets array */
+    pcre2_match_data *ovector;                  /* RE substring offsets array */
     int rc;                                     /* RE Check return value */
     int buffer_length;
 
@@ -554,43 +604,49 @@
     buffer_length = (int) strlen(buffer);
 
     /* Check for COMBINED */
-    rc = pcre_exec(cmp_log_regexp_combined, NULL, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
+    ovector = pcre2_match_data_create(OVECCOUNT, NULL);
+    rc = pcre2_match(cmp_log_regexp_combined, buffer, buffer_length, 0, 0, ovector, NULL);
     if (rc >= 0) {
         /* Matches against COMBINED */
         VPRINT(VERBOSE1, "%s\n", _("Using COMBINED Log Format"));
+        pcre2_match_data_free(ovector);
         return (LOG_COMBINED);
     }
 
     /* Check for COMBINED_DOMINO */
     /* If the first line is a non logged in user, it'll probably register as COMBINED... */
-    rc = pcre_exec(cmp_log_regexp_domino, NULL, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
+    rc = pcre2_match(cmp_log_regexp_domino, buffer, buffer_length, 0, 0, ovector, NULL);
     if (rc >= 0) {
         /* Matches against COMBINED_DOMINO */
         VPRINT(VERBOSE1, "%s\n", _("Using COMBINED_DOMINO Log Format"));
+        pcre2_match_data_free(ovector);
         return (LOG_DOMINO);
     }
 
-    rc = pcre_exec(cmp_log_regexp_clf, NULL, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
+    rc = pcre2_match(cmp_log_regexp_clf, buffer, buffer_length, 0, 0, ovector, NULL);
     if (rc >= 0) {
         /* Matches against COMBINED */
         VPRINT(VERBOSE1, "%s\n", _("Using CLF Log Format"));
+        pcre2_match_data_free(ovector);
         return (LOG_CLF);
     }
 
-    rc = pcre_exec(cmp_log_regexp_xferlog, NULL, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
+    rc = pcre2_match(cmp_log_regexp_xferlog, buffer, buffer_length, 0, 0, ovector, NULL);
     if (rc >= 0) {
         /* Matches against FTP/XFERLOG */
         VPRINT(VERBOSE1, "%s\n", _("Using FTP/XFERLOG Log Format"));
+        pcre2_match_data_free(ovector);
         /* Invalid tables for this log type. Zero them away and hence not display. */
         g_settings.top.agents = 0;
         g_settings.top.refs = 0;
         return (LOG_FTP);
     }
 
-    rc = pcre_exec(cmp_log_regexp_squid, NULL, buffer, buffer_length, 0, 0, ovector, OVECCOUNT);
+    rc = pcre2_match(cmp_log_regexp_squid, buffer, buffer_length, 0, 0, ovector, NULL);
     if (rc >= 0) {
         /* Matches against SQUID */
         VPRINT(VERBOSE1, "%s\n", _("Using SQUID Log Format"));
+        pcre2_match_data_free(ovector);
         /* Invalid tables for this log type. Zero them away and hence not display. */
         g_settings.top.agents = 0;
         g_settings.top.refs = 0;
@@ -598,6 +654,7 @@
     }
 
     VPRINT(VERBOSE1, "%s\n", _("Unrecognised Log Format"));
+    pcre2_match_data_free(ovector);
     return (-1);                                /* Failed to match any, unknown format */
 }
 
@@ -623,46 +680,46 @@
     char log_regexp_squid[MAX_RE_LENGTH] = PATTERN_SQUID;
     char log_regexp_domino[MAX_RE_LENGTH] = PATTERN_DOMINO;
 
-    const char *error;                          /* RE error pointer, offset */
-    int erroffset;                              /* RE error value */
+    int error;                                  /* RE error code */
+    size_t erroffset;                           /* RE error offset */
 
     /* CLF */
-    cmp_log_regexp_clf = pcre_compile(log_regexp_clf, 0, &error, &erroffset, NULL);
+    cmp_log_regexp_clf = pcre2_compile(log_regexp_clf, strlen(log_regexp_clf), 0, &error, &erroffset, NULL);
     VPRINT(VERBOSE2, "PCRE: Compile CLF%s", "\n");
     if (cmp_log_regexp_clf == NULL) {
         re_compile_failed(erroffset, error, log_regexp_clf);
     }
 
     /* Combined */
-    cmp_log_regexp_combined = pcre_compile(log_regexp_combined, 0, &error, &erroffset, NULL);
+    cmp_log_regexp_combined = pcre2_compile(log_regexp_combined, strlen(log_regexp_combined), 0, &error, &erroffset, NULL);
     VPRINT(VERBOSE2, "PCRE: Compile COMBINED%s", "\n");
     if (cmp_log_regexp_combined == NULL) {
         re_compile_failed(erroffset, error, log_regexp_combined);
     }
 
     /* Enhanced Combined */
-    cmp_log_regexp_combined_enhanced = pcre_compile(log_regexp_combined_enhanced, 0, &error, &erroffset, NULL);
+    cmp_log_regexp_combined_enhanced = pcre2_compile(log_regexp_combined_enhanced, strlen(log_regexp_combined_enhanced), 0, &error, &erroffset, NULL);
     VPRINT(VERBOSE2, "PCRE: Compile COMBINED_ENHANCED%s", "\n");
     if (cmp_log_regexp_combined_enhanced == NULL) {
         re_compile_failed(erroffset, error, log_regexp_combined_enhanced);
     }
 
     /* FTP XFERLOG */
-    cmp_log_regexp_xferlog = pcre_compile(log_regexp_xferlog, 0, &error, &erroffset, NULL);
+    cmp_log_regexp_xferlog = pcre2_compile(log_regexp_xferlog, strlen(log_regexp_xferlog), 0, &error, &erroffset, NULL);
     VPRINT(VERBOSE2, "PCRE: Compile PATTERN_XFERLOG%s", "\n");
     if (cmp_log_regexp_xferlog == NULL) {
         re_compile_failed(erroffset, error, log_regexp_xferlog);
     }
 
     /* SQUID LOG */
-    cmp_log_regexp_squid = pcre_compile(log_regexp_squid, 0, &error, &erroffset, NULL);
+    cmp_log_regexp_squid = pcre2_compile(log_regexp_squid, strlen(log_regexp_squid), 0, &error, &erroffset, NULL);
     VPRINT(VERBOSE2, "PCRE: Compile PATTERN_SQUID%s", "\n");
     if (cmp_log_regexp_squid == NULL) {
         re_compile_failed(erroffset, error, log_regexp_squid);
     }
 
     /* DOMINO LOG */
-    cmp_log_regexp_domino = pcre_compile(log_regexp_domino, 0, &error, &erroffset, NULL);
+    cmp_log_regexp_domino = pcre2_compile(log_regexp_domino, strlen(log_regexp_domino), 0, &error, &erroffset, NULL);
     VPRINT(VERBOSE2, "PCRE: Compile PATTERN_COMBINED_DOMINO%s", "\n");
     if (cmp_log_regexp_domino == NULL) {
         re_compile_failed(erroffset, error, log_regexp_domino);
@@ -683,7 +740,7 @@
 
     /* Matching failed: handle error cases */
     switch (err) {
-    case PCRE_ERROR_NOMATCH:
+    case PCRE2_ERROR_NOMATCH:
         ERRVPRINT(VERBOSE1, "%s", _("Warning: No Regular Expression Match. "));
         break;
         /*  Leave out the more explicit failure messages - we show the number, so can be found.
@@ -716,9 +773,12 @@
  * FATAL failure. Will exit the run.                                    *
  ************************************************************************/
 static void
-re_compile_failed(int err, const char *err_offset, char *re_str)
+re_compile_failed(size_t err_offset, int err, char *re_str)
 {
-    ERRVPRINT(VERBOSE0, "%s %d %s\n", _("FATAL ERROR! PCRE compilation failed at offset"), err, err_offset);
+    PCRE2_UCHAR buffer[256];
+
+    pcre2_get_error_message(err, buffer, sizeof(buffer));
+    ERRVPRINT(VERBOSE0, "%s %lu %s\n", _("FATAL ERROR! PCRE compilation failed at offset"), err_offset, buffer);
     ERRVPRINT(VERBOSE0, "%s %s\n", _("  Using Regular Expression:"), re_str);
     exit(1);                                    /* FIXME - table of exit codes! */
 }
@@ -735,10 +795,10 @@
 {
     ERRVPRINT(VERBOSE1, "%s %d\n", _("Error: Failed to extract substring:"), substr_idx);
     switch (err) {
-    case PCRE_ERROR_NOMEMORY:
+    case PCRE2_ERROR_NOMEMORY:
         ERRVPRINT(VERBOSE2, "  PCRE: Insufficient Memory\n");
         break;
-    case PCRE_ERROR_NOSUBSTRING:
+    case PCRE2_ERROR_NOSUBSTRING:
         ERRVPRINT(VERBOSE2, "  PCRE: Substring doesn't exist.\n");
         break;
     default:
