]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
pcre2: migrate utility uses of pcre
authorPhilippe Antoine <contact@catenacyber.fr>
Tue, 13 Apr 2021 12:08:09 +0000 (14:08 +0200)
committerPhilippe Antoine <contact@catenacyber.fr>
Tue, 28 Sep 2021 15:46:19 +0000 (17:46 +0200)
src/detect-engine-analyzer.c
src/log-pcap.c
src/util-classification-config.c
src/util-debug.c
src/util-debug.h
src/util-host-info.c
src/util-misc.c
src/util-reference-config.c
src/util-threshold-config.c
src/util-unittest.c

index 9e5037d57654bd4572e22ec81785020c17bb9470..21b98df42c4cd99d48fad376c85d74a5a29275cc 100644 (file)
 #include "detect-tcp-flags.h"
 #include "feature.h"
 #include "util-print.h"
+#include <pcre2.h>
 
 static int rule_warnings_only = 0;
 static FILE *rule_engine_analysis_FD = NULL;
 static FILE *fp_engine_analysis_FD = NULL;
-static pcre *percent_re = NULL;
-static pcre_extra *percent_re_study = NULL;
+static pcre2_code *percent_re = NULL;
+static pcre2_match_data *percent_re_match = NULL;
 static char log_path[PATH_MAX];
 
 typedef struct FpPatternStats_ {
@@ -417,6 +418,10 @@ void CleanupRuleAnalyzer(void)
         fclose(rule_engine_analysis_FD);
         rule_engine_analysis_FD = NULL;
     }
+    if (percent_re != NULL) {
+        pcre2_code_free(percent_re);
+    }
+    pcre2_match_data_free(percent_re_match);
 }
 
 /**
@@ -427,22 +432,21 @@ void CleanupRuleAnalyzer(void)
 int PerCentEncodingSetup ()
 {
 #define DETECT_PERCENT_ENCODING_REGEX "%[0-9|a-f|A-F]{2}"
-    const char *eb = NULL;
-    int eo = 0;
+    int en;
+    PCRE2_SIZE eo = 0;
     int opts = 0;    //PCRE_NEWLINE_ANY??
 
-    percent_re = pcre_compile(DETECT_PERCENT_ENCODING_REGEX, opts, &eb, &eo, NULL);
+    percent_re = pcre2_compile((PCRE2_SPTR8)DETECT_PERCENT_ENCODING_REGEX, PCRE2_ZERO_TERMINATED,
+            opts, &en, &eo, NULL);
     if (percent_re == NULL) {
-        SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",
-                   DETECT_PERCENT_ENCODING_REGEX, eo, eb);
+        PCRE2_UCHAR errbuffer[256];
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %d: %s",
+                DETECT_PERCENT_ENCODING_REGEX, (int)eo, errbuffer);
         return 0;
     }
 
-    percent_re_study = pcre_study(percent_re, 0, &eb);
-    if (eb != NULL) {
-        SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
-        return 0;
-    }
+    percent_re_match = pcre2_match_data_create_from_pattern(percent_re, NULL);
     return 1;
 }
 
@@ -455,11 +459,9 @@ int PerCentEncodingSetup ()
  */
 int PerCentEncodingMatch (uint8_t *content, uint8_t content_len)
 {
-#define MAX_ENCODED_CHARS 240
     int ret = 0;
-    int ov[MAX_ENCODED_CHARS];
 
-    ret = pcre_exec(percent_re, percent_re_study, (char *)content, content_len, 0, 0, ov, MAX_ENCODED_CHARS);
+    ret = pcre2_match(percent_re, (PCRE2_SPTR8)content, content_len, 0, 0, percent_re_match, NULL);
     if (ret == -1) {
         return 0;
     }
index 07ac49452c5be2c81ea7572b82d67011c0e89917..0a954023e70672d8c9106c532908117a874f74ad 100644 (file)
@@ -58,6 +58,7 @@
 #include "util-misc.h"
 #include "util-cpu.h"
 #include "util-atomic.h"
+#include <pcre2.h>
 
 #include "source-pcap.h"
 
@@ -186,8 +187,8 @@ typedef struct PcapLogThreadData_ {
 
 /* Pattern for extracting timestamp from pcap log files. */
 static const char timestamp_pattern[] = ".*?(\\d+)(\\.(\\d+))?";
-static pcre *pcre_timestamp_code = NULL;
-static pcre_extra *pcre_timestamp_extra = NULL;
+static pcre2_code *pcre_timestamp_code = NULL;
+static pcre2_match_data *pcre_timestamp_match = NULL;
 
 /* global pcap data for when we're using multi mode. At exit we'll
  * merge counters into this one and then report counters. */
@@ -717,13 +718,11 @@ static PcapLogData *PcapLogDataCopy(const PcapLogData *pl)
 static int PcapLogGetTimeOfFile(const char *filename, uint64_t *secs,
     uint32_t *usecs)
 {
-    int pcre_ovecsize = 4 * 3;
-    int pcre_ovec[pcre_ovecsize];
     char buf[PATH_MAX];
+    size_t copylen;
 
-    int n = pcre_exec(pcre_timestamp_code, pcre_timestamp_extra,
-        filename, strlen(filename), 0, 0, pcre_ovec,
-        pcre_ovecsize);
+    int n = pcre2_match(pcre_timestamp_code, (PCRE2_SPTR8)filename, strlen(filename), 0, 0,
+            pcre_timestamp_match, NULL);
     if (n != 2 && n != 4) {
         /* No match. */
         return 0;
@@ -731,8 +730,9 @@ static int PcapLogGetTimeOfFile(const char *filename, uint64_t *secs,
 
     if (n >= 2) {
         /* Extract seconds. */
-        if (pcre_copy_substring(filename, pcre_ovec, pcre_ovecsize,
-                1, buf, sizeof(buf)) < 0) {
+        copylen = sizeof(buf);
+        if (pcre2_substring_copy_bynumber(pcre_timestamp_match, 1, (PCRE2_UCHAR8 *)buf, &copylen) <
+                0) {
             return 0;
         }
         if (StringParseUint64(secs, 10, 0, buf) < 0) {
@@ -741,8 +741,9 @@ static int PcapLogGetTimeOfFile(const char *filename, uint64_t *secs,
     }
     if (n == 4) {
         /* Extract microseconds. */
-        if (pcre_copy_substring(filename, pcre_ovec, pcre_ovecsize,
-                3, buf, sizeof(buf)) < 0) {
+        copylen = sizeof(buf);
+        if (pcre2_substring_copy_bynumber(pcre_timestamp_match, 3, (PCRE2_UCHAR8 *)buf, &copylen) <
+                0) {
             return 0;
         }
         if (StringParseUint32(usecs, 10, 0, buf) < 0) {
@@ -1172,8 +1173,8 @@ error:
 static OutputInitResult PcapLogInitCtx(ConfNode *conf)
 {
     OutputInitResult result = { NULL, false };
-    const char *pcre_errbuf;
-    int pcre_erroffset;
+    int en;
+    PCRE2_SIZE eo = 0;
 
     PcapLogData *pl = SCMalloc(sizeof(PcapLogData));
     if (unlikely(pl == NULL)) {
@@ -1200,17 +1201,15 @@ static OutputInitResult PcapLogInitCtx(ConfNode *conf)
     SCMutexInit(&pl->plog_lock, NULL);
 
     /* Initialize PCREs. */
-    pcre_timestamp_code = pcre_compile(timestamp_pattern, 0, &pcre_errbuf,
-        &pcre_erroffset, NULL);
+    pcre_timestamp_code =
+            pcre2_compile((PCRE2_SPTR8)timestamp_pattern, PCRE2_ZERO_TERMINATED, 0, &en, &eo, NULL);
     if (pcre_timestamp_code == NULL) {
-        FatalError(SC_ERR_PCRE_COMPILE,
-            "Failed to compile \"%s\" at offset %"PRIu32": %s",
-            timestamp_pattern, pcre_erroffset, pcre_errbuf);
-    }
-    pcre_timestamp_extra = pcre_study(pcre_timestamp_code, 0, &pcre_errbuf);
-    if (pcre_errbuf != NULL) {
-        FatalError(SC_ERR_PCRE_STUDY, "Fail to study pcre: %s", pcre_errbuf);
+        PCRE2_UCHAR errbuffer[256];
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        FatalError(SC_ERR_PCRE_COMPILE, "Failed to compile \"%s\" at offset %d: %s",
+                timestamp_pattern, (int)eo, errbuffer);
     }
+    pcre_timestamp_match = pcre2_match_data_create_from_pattern(pcre_timestamp_code, NULL);
 
     /* conf params */
 
@@ -1523,6 +1522,10 @@ static void PcapLogFileDeInitCtx(OutputCtx *output_ctx)
     }
     PcapLogDataFree(pl);
     SCFree(output_ctx);
+
+    pcre2_code_free(pcre_timestamp_code);
+    pcre2_match_data_free(pcre_timestamp_match);
+
     return;
 }
 
index 6006973734d9391edeedbc12975fdb621c3c62fa..0f875ffa6434bcf746e2756d3dfa13b320759b6c 100644 (file)
@@ -35,6 +35,7 @@
 #include "util-debug.h"
 #include "util-fmemopen.h"
 #include "util-byte.h"
+#include <pcre2.h>
 
 /* Regex to parse the classtype argument from a Signature.  The first substring
  * holds the classtype name, the second substring holds the classtype the
@@ -48,8 +49,8 @@
 #define SC_CLASS_CONF_DEF_CONF_FILEPATH CONFIG_DIR "/classification.config"
 #endif
 
-static pcre *regex = NULL;
-static pcre_extra *regex_study = NULL;
+static pcre2_code *regex = NULL;
+static pcre2_match_data *regex_match = NULL;
 
 uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen);
 char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1,
@@ -63,36 +64,34 @@ static void SCClassConfDeAllocClasstype(SCClassConfClasstype *ct);
 
 void SCClassConfInit(void)
 {
-    const char *eb = NULL;
-    int eo;
+    int en;
+    PCRE2_SIZE eo;
     int opts = 0;
 
-    regex = pcre_compile(DETECT_CLASSCONFIG_REGEX, opts, &eb, &eo, NULL);
+    regex = pcre2_compile(
+            (PCRE2_SPTR8)DETECT_CLASSCONFIG_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
     if (regex == NULL) {
-        SCLogDebug("Compile of \"%s\" failed at offset %" PRId32 ": %s",
-                   DETECT_CLASSCONFIG_REGEX, eo, eb);
-        return;
-    }
-
-    regex_study = pcre_study(regex, 0, &eb);
-    if (eb != NULL) {
-        pcre_free(regex);
-        regex = NULL;
-        SCLogDebug("pcre study failed: %s", eb);
+        PCRE2_UCHAR errbuffer[256];
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        SCLogWarning(SC_ERR_PCRE_COMPILE,
+                "pcre2 compile of \"%s\" failed at "
+                "offset %d: %s",
+                DETECT_CLASSCONFIG_REGEX, (int)eo, errbuffer);
         return;
     }
+    regex_match = pcre2_match_data_create_from_pattern(regex, NULL);
     return;
 }
 
 void SCClassConfDeinit(void)
 {
     if (regex != NULL) {
-        pcre_free(regex);
+        pcre2_code_free(regex);
         regex = NULL;
     }
-    if (regex_study != NULL) {
-        pcre_free(regex_study);
-        regex_study = NULL;
+    if (regex_match != NULL) {
+        pcre2_match_data_free(regex_match);
+        regex_match = NULL;
     }
 }
 
@@ -251,35 +250,36 @@ int SCClassConfAddClasstype(DetectEngineCtx *de_ctx, char *rawstr, uint16_t inde
     SCClassConfClasstype *ct_new = NULL;
     SCClassConfClasstype *ct_lookup = NULL;
 
-#define MAX_SUBSTRINGS 30
     int ret = 0;
-    int ov[MAX_SUBSTRINGS];
 
-    ret = pcre_exec(regex, regex_study, rawstr, strlen(rawstr), 0, 0, ov, 30);
+    ret = pcre2_match(regex, (PCRE2_SPTR8)rawstr, strlen(rawstr), 0, 0, regex_match, NULL);
     if (ret < 0) {
         SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid Classtype in "
                    "classification.config file");
         goto error;
     }
 
+    size_t copylen = sizeof(ct_name);
     /* retrieve the classtype name */
-    ret = pcre_copy_substring((char *)rawstr, ov, 30, 1, ct_name, sizeof(ct_name));
+    ret = pcre2_substring_copy_bynumber(regex_match, 1, (PCRE2_UCHAR8 *)ct_name, &copylen);
     if (ret < 0) {
-        SCLogInfo("pcre_copy_substring() failed");
+        SCLogInfo("pcre2_substring_copy_bynumber() failed");
         goto error;
     }
 
     /* retrieve the classtype description */
-    ret = pcre_copy_substring((char *)rawstr, ov, 30, 2, ct_desc, sizeof(ct_desc));
+    copylen = sizeof(ct_desc);
+    ret = pcre2_substring_copy_bynumber(regex_match, 2, (PCRE2_UCHAR8 *)ct_desc, &copylen);
     if (ret < 0) {
-        SCLogInfo("pcre_copy_substring() failed");
+        SCLogInfo("pcre2_substring_copy_bynumber() failed");
         goto error;
     }
 
     /* retrieve the classtype priority */
-    ret = pcre_copy_substring((char *)rawstr, ov, 30, 3, ct_priority_str, sizeof(ct_priority_str));
+    copylen = sizeof(ct_priority_str);
+    ret = pcre2_substring_copy_bynumber(regex_match, 3, (PCRE2_UCHAR8 *)ct_priority_str, &copylen);
     if (ret < 0) {
-        SCLogInfo("pcre_copy_substring() failed");
+        SCLogInfo("pcre2_substring_copy_bynumber() failed");
         goto error;
     }
     if (StringParseUint32(&ct_priority, 10, 0, (const char *)ct_priority_str) < 0) {
index 60322b95a9e91cdfd71f4379fb675fbc75911bfc..648471af92ba4fc9110b66765f3efe5a18ed0b52 100644 (file)
@@ -492,16 +492,10 @@ static SCError SCLogMessageGetBuffer(
     }
 
     if (sc_log_config->op_filter_regex != NULL) {
-#define MAX_SUBSTRINGS 30
-        int ov[MAX_SUBSTRINGS];
-
-        if (pcre_exec(sc_log_config->op_filter_regex,
-                      sc_log_config->op_filter_regex_study,
-                      buffer, strlen(buffer), 0, 0, ov, MAX_SUBSTRINGS) < 0)
-        {
+        if (pcre2_match(sc_log_config->op_filter_regex, (PCRE2_SPTR8)buffer, strlen(buffer), 0, 0,
+                    sc_log_config->op_filter_regex_match, NULL) < 0) {
             return SC_ERR_LOG_FG_FILTER_MATCH; // bit hacky, but just return !0
         }
-#undef MAX_SUBSTRINGS
     }
 
     return SC_OK;
@@ -1109,8 +1103,8 @@ static inline void SCLogSetOPFilter(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
     const char *filter = NULL;
 
     int opts = 0;
-    const char *ep;
-    int eo = 0;
+    int en;
+    PCRE2_SIZE eo = 0;
 
     /* envvar overrides */
     filter = getenv(SC_LOG_ENV_LOG_OP_FILTER);
@@ -1126,20 +1120,18 @@ static inline void SCLogSetOPFilter(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
             printf("pcre filter alloc failed\n");
             return;
         }
-        sc_lc->op_filter_regex = pcre_compile(filter, opts, &ep, &eo, NULL);
+        sc_lc->op_filter_regex =
+                pcre2_compile((PCRE2_SPTR8)filter, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
         if (sc_lc->op_filter_regex == NULL) {
             SCFree(sc_lc->op_filter);
-            printf("pcre compile of \"%s\" failed at offset %d : %s\n", filter,
-                   eo, ep);
-            return;
-        }
-
-        sc_lc->op_filter_regex_study = pcre_study(sc_lc->op_filter_regex, 0,
-                                                  &ep);
-        if (ep != NULL) {
-            printf("pcre study failed: %s\n", ep);
+            PCRE2_UCHAR errbuffer[256];
+            pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+            printf("pcre2 compile of \"%s\" failed at offset %d : %s\n", filter, (int)eo,
+                    errbuffer);
             return;
         }
+        sc_lc->op_filter_regex_match =
+                pcre2_match_data_create_from_pattern(sc_lc->op_filter_regex, NULL);
     }
 
     return;
@@ -1199,9 +1191,9 @@ static inline void SCLogFreeLogConfig(SCLogConfig *sc_lc)
             SCFree(sc_lc->op_filter);
 
         if (sc_lc->op_filter_regex != NULL)
-            pcre_free(sc_lc->op_filter_regex);
-        if (sc_lc->op_filter_regex_study)
-            pcre_free_study(sc_lc->op_filter_regex_study);
+            pcre2_code_free(sc_lc->op_filter_regex);
+        if (sc_lc->op_filter_regex_match)
+            pcre2_match_data_free(sc_lc->op_filter_regex_match);
 
         SCLogFreeLogOPIfaceCtx(sc_lc->op_ifaces);
         SCFree(sc_lc);
index 9c93b5ce5150ab19dd79042652788dc2e6b27d10..ff032aecf4e1ffb72f4bc743919a627fd337a3b0 100644 (file)
@@ -31,6 +31,7 @@
 #include "util-error.h"
 #include "util-debug-filters.h"
 #include "util-atomic.h"
+#include <pcre2.h>
 
 /**
  * \brief ENV vars that can be used to set the properties for the logging module
@@ -176,8 +177,8 @@ typedef struct SCLogConfig_ {
 
     char *op_filter;
     /* compiled pcre filter expression */
-    pcre *op_filter_regex;
-    pcre_extra *op_filter_regex_study;
+    pcre2_code *op_filter_regex;
+    pcre2_match_data *op_filter_regex_match;
 
     /* op ifaces used */
     SCLogOPIfaceCtx *op_ifaces;
index 0f02d98190bd4fd21ffcfeb6f4871b987f5f3d34..afd186dca27ad7f677317976f6ddf91a406a7540 100644 (file)
@@ -27,6 +27,7 @@
 #include "suricata-common.h"
 #include "util-host-info.h"
 #include "util-byte.h"
+#include <pcre2.h>
 
 #ifndef OS_WIN32
 #include <sys/utsname.h>
 int SCKernelVersionIsAtLeast(int major, int minor)
 {
     struct utsname kuname;
-    pcre *version_regex;
-    pcre_extra *version_regex_study;
-    const char *eb;
+    pcre2_code *version_regex;
+    pcre2_match_data *version_regex_match;
+    int en;
     int opts = 0;
-    int eo;
-#define MAX_SUBSTRINGS 3 * 6
-    int ov[MAX_SUBSTRINGS];
+    PCRE2_SIZE eo;
     int ret;
     int kmajor, kminor;
-    const char **list;
+    PCRE2_UCHAR **list;
 
     /* get local version */
     if (uname(&kuname) != 0) {
@@ -56,20 +55,21 @@ int SCKernelVersionIsAtLeast(int major, int minor)
 
     SCLogDebug("Kernel release is '%s'", kuname.release);
 
-    version_regex = pcre_compile(VERSION_REGEX, opts, &eb, &eo, NULL);
+    version_regex =
+            pcre2_compile((PCRE2_SPTR8)VERSION_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
     if (version_regex == NULL) {
-        SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", VERSION_REGEX, eo, eb);
+        PCRE2_UCHAR errbuffer[256];
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        SCLogError(SC_ERR_PCRE_COMPILE,
+                "pcre2 compile of \"%s\" failed at "
+                "offset %d: %s",
+                VERSION_REGEX, (int)eo, errbuffer);
         goto error;
     }
+    version_regex_match = pcre2_match_data_create_from_pattern(version_regex, NULL);
 
-    version_regex_study = pcre_study(version_regex, 0, &eb);
-    if (eb != NULL) {
-        SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
-        goto error;
-    }
-
-    ret = pcre_exec(version_regex, version_regex_study, kuname.release,
-                    strlen(kuname.release), 0, 0, ov, MAX_SUBSTRINGS);
+    ret = pcre2_match(version_regex, (PCRE2_SPTR8)kuname.release, strlen(kuname.release), 0, 0,
+            version_regex_match, NULL);
 
     if (ret < 0) {
         SCLogError(SC_ERR_PCRE_MATCH, "Version did not cut");
@@ -81,7 +81,7 @@ int SCKernelVersionIsAtLeast(int major, int minor)
         goto error;
     }
 
-    pcre_get_substring_list(kuname.release, ov, ret, &list);
+    pcre2_substring_list_get(version_regex_match, &list, NULL);
 
     bool err = false;
     if (StringParseInt32(&kmajor, 10, 0, (const char *)list[1]) < 0) {
@@ -93,9 +93,9 @@ int SCKernelVersionIsAtLeast(int major, int minor)
         err = true;
     }
 
-    pcre_free_substring_list(list);
-    pcre_free_study(version_regex_study);
-    pcre_free(version_regex);
+    pcre2_substring_list_free((PCRE2_SPTR *)list);
+    pcre2_match_data_free(version_regex_match);
+    pcre2_code_free(version_regex);
 
     if (err)
         goto error;
index 2190d5aae25a544291f21b6950e24180e32ee62d..deafedfa90c1caab48598ca6a2d5574fce6695e3 100644 (file)
 #include "util-debug.h"
 #include "util-unittest.h"
 #include "util-misc.h"
+#include <pcre2.h>
 
 #define PARSE_REGEX "^\\s*(\\d+(?:.\\d+)?)\\s*([a-zA-Z]{2})?\\s*$"
-static pcre *parse_regex = NULL;
-static pcre_extra *parse_regex_study = NULL;
+static pcre2_code *parse_regex = NULL;
+static pcre2_match_data *parse_regex_match = NULL;
 
 void ParseSizeInit(void)
 {
-    const char *eb = NULL;
-    int eo;
+    int en;
+    PCRE2_SIZE eo;
     int opts = 0;
 
-    parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL);
+    parse_regex =
+            pcre2_compile((PCRE2_SPTR8)PARSE_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
     if (parse_regex == NULL) {
-        SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset "
-                   "%" PRId32 ": %s", PARSE_REGEX, eo, eb);
-        exit(EXIT_FAILURE);
-    }
-    parse_regex_study = pcre_study(parse_regex, 0, &eb);
-    if (eb != NULL) {
-        SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
+        PCRE2_UCHAR errbuffer[256];
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        SCLogError(SC_ERR_PCRE_COMPILE,
+                "pcre2 compile of \"%s\" failed at "
+                "offset %d: %s",
+                PARSE_REGEX, (int)eo, errbuffer);
         exit(EXIT_FAILURE);
     }
+    parse_regex_match = pcre2_match_data_create_from_pattern(parse_regex, NULL);
 }
 
 void ParseSizeDeinit(void)
 {
-
-    if (parse_regex != NULL)
-        pcre_free(parse_regex);
-    if (parse_regex_study != NULL)
-        pcre_free_study(parse_regex_study);
+    pcre2_code_free(parse_regex);
+    pcre2_match_data_free(parse_regex_match);
 }
 
 /* size string parsing API */
 
 static int ParseSizeString(const char *size, double *res)
 {
-#define MAX_SUBSTRINGS 30
-    int pcre_exec_ret;
+    int pcre2_match_ret;
     int r;
-    int ov[MAX_SUBSTRINGS];
     int retval = 0;
     char str[128];
     char str2[128];
@@ -86,9 +83,10 @@ static int ParseSizeString(const char *size, double *res)
         goto end;
     }
 
-    pcre_exec_ret = pcre_exec(parse_regex, parse_regex_study, size, strlen(size), 0, 0,
-                    ov, MAX_SUBSTRINGS);
-    if (!(pcre_exec_ret == 2 || pcre_exec_ret == 3)) {
+    pcre2_match_ret = pcre2_match(
+            parse_regex, (PCRE2_SPTR8)size, strlen(size), 0, 0, parse_regex_match, NULL);
+
+    if (!(pcre2_match_ret == 2 || pcre2_match_ret == 3)) {
         SCLogError(SC_ERR_PCRE_MATCH, "invalid size argument - %s. Valid size "
                    "argument should be in the format - \n"
                    "xxx <- indicates it is just bytes\n"
@@ -100,10 +98,10 @@ static int ParseSizeString(const char *size, double *res)
         goto end;
     }
 
-    r = pcre_copy_substring((char *)size, ov, MAX_SUBSTRINGS, 1,
-                             str, sizeof(str));
+    size_t copylen = sizeof(str);
+    r = pcre2_substring_copy_bynumber(parse_regex_match, 1, (PCRE2_UCHAR8 *)str, &copylen);
     if (r < 0) {
-        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
+        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed");
         retval = -2;
         goto end;
     }
@@ -121,11 +119,12 @@ static int ParseSizeString(const char *size, double *res)
         goto end;
     }
 
-    if (pcre_exec_ret == 3) {
-        r = pcre_copy_substring((char *)size, ov, MAX_SUBSTRINGS, 2,
-                                 str2, sizeof(str2));
+    if (pcre2_match_ret == 3) {
+        copylen = sizeof(str2);
+        r = pcre2_substring_copy_bynumber(parse_regex_match, 2, (PCRE2_UCHAR8 *)str2, &copylen);
+
         if (r < 0) {
-            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
+            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed");
             retval = -2;
             goto end;
         }
index 4519b7b019e4c1bddcd0675aae167824e9615b4d..6768ec5448a7365c4f5a0c12e5fe850ca96dd070 100644 (file)
@@ -25,6 +25,7 @@
 #include "detect.h"
 #include "detect-engine.h"
 #include "util-hash.h"
+#include <pcre2.h>
 
 #include "util-reference-config.h"
 #include "conf.h"
@@ -41,8 +42,8 @@
 /* Default path for the reference.conf file */
 #define SC_RCONF_DEFAULT_FILE_PATH CONFIG_DIR "/reference.config"
 
-static pcre *regex = NULL;
-static pcre_extra *regex_study = NULL;
+static pcre2_code *regex = NULL;
+static pcre2_match_data *regex_match = NULL;
 
 /* the hash functions */
 uint32_t SCRConfReferenceHashFunc(HashTable *ht, void *data, uint16_t datalen);
@@ -55,24 +56,21 @@ static const char *SCRConfGetConfFilename(const DetectEngineCtx *de_ctx);
 
 void SCReferenceConfInit(void)
 {
-    const char *eb = NULL;
-    int eo;
+    int en;
+    PCRE2_SIZE eo;
     int opts = 0;
 
-    regex = pcre_compile(SC_RCONF_REGEX, opts, &eb, &eo, NULL);
+    regex = pcre2_compile((PCRE2_SPTR8)SC_RCONF_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
     if (regex == NULL) {
-        SCLogDebug("Compile of \"%s\" failed at offset %" PRId32 ": %s",
-                   SC_RCONF_REGEX, eo, eb);
-        return;
-    }
-
-    regex_study = pcre_study(regex, 0, &eb);
-    if (eb != NULL) {
-        pcre_free(regex);
-        regex = NULL;
-        SCLogDebug("pcre study failed: %s", eb);
+        PCRE2_UCHAR errbuffer[256];
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        SCLogWarning(SC_ERR_PCRE_COMPILE,
+                "pcre2 compile of \"%s\" failed at "
+                "offset %d: %s",
+                SC_RCONF_REGEX, (int)eo, errbuffer);
         return;
     }
+    regex_match = pcre2_match_data_create_from_pattern(regex, NULL);
 
     return;
 }
@@ -80,12 +78,12 @@ void SCReferenceConfInit(void)
 void SCReferenceConfDeinit(void)
 {
     if (regex != NULL) {
-        pcre_free(regex);
+        pcre2_code_free(regex);
         regex = NULL;
     }
-    if (regex_study != NULL) {
-        pcre_free(regex_study);
-        regex_study = NULL;
+    if (regex_match != NULL) {
+        pcre2_match_data_free(regex_match);
+        regex_match = NULL;
     }
 }
 
@@ -238,11 +236,9 @@ int SCRConfAddReference(DetectEngineCtx *de_ctx, const char *line)
     SCRConfReference *ref_new = NULL;
     SCRConfReference *ref_lookup = NULL;
 
-#define MAX_SUBSTRINGS 30
     int ret = 0;
-    int ov[MAX_SUBSTRINGS];
 
-    ret = pcre_exec(regex, regex_study, line, strlen(line), 0, 0, ov, 30);
+    ret = pcre2_match(regex, (PCRE2_SPTR8)line, strlen(line), 0, 0, regex_match, NULL);
     if (ret < 0) {
         SCLogError(SC_ERR_REFERENCE_CONFIG, "Invalid Reference Config in "
                    "reference.config file");
@@ -250,16 +246,18 @@ int SCRConfAddReference(DetectEngineCtx *de_ctx, const char *line)
     }
 
     /* retrieve the reference system */
-    ret = pcre_copy_substring((char *)line, ov, 30, 1, system, sizeof(system));
+    size_t copylen = sizeof(system);
+    ret = pcre2_substring_copy_bynumber(regex_match, 1, (PCRE2_UCHAR8 *)system, &copylen);
     if (ret < 0) {
-        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring() failed");
+        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber() failed");
         goto error;
     }
 
     /* retrieve the reference url */
-    ret = pcre_copy_substring((char *)line, ov, 30, 2, url, sizeof(url));
+    copylen = sizeof(url);
+    ret = pcre2_substring_copy_bynumber(regex_match, 2, (PCRE2_UCHAR8 *)url, &copylen);
     if (ret < 0) {
-        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring() failed");
+        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber() failed");
         goto error;
     }
 
index e81d14a569ace1df7b5726d0d4a73ae9469d797b..d22a755a756a2422d1fc0a8d52b7e90bcd7c1d19 100644 (file)
@@ -87,104 +87,108 @@ static FILE *g_ut_threshold_fp = NULL;
 #define THRESHOLD_CONF_DEF_CONF_FILEPATH CONFIG_DIR "/threshold.config"
 #endif
 
-static pcre *regex_base = NULL;
-static pcre_extra *regex_base_study = NULL;
+static pcre2_code *regex_base = NULL;
+static pcre2_match_data *regex_base_match = NULL;
 
-static pcre *regex_threshold = NULL;
-static pcre_extra *regex_threshold_study = NULL;
+static pcre2_code *regex_threshold = NULL;
+static pcre2_match_data *regex_threshold_match = NULL;
 
-static pcre *regex_rate = NULL;
-static pcre_extra *regex_rate_study = NULL;
+static pcre2_code *regex_rate = NULL;
+static pcre2_match_data *regex_rate_match = NULL;
 
-static pcre *regex_suppress = NULL;
-static pcre_extra *regex_suppress_study = NULL;
+static pcre2_code *regex_suppress = NULL;
+static pcre2_match_data *regex_suppress_match = NULL;
 
 static void SCThresholdConfDeInitContext(DetectEngineCtx *de_ctx, FILE *fd);
 
 void SCThresholdConfGlobalInit(void)
 {
-    const char *eb = NULL;
-    int eo;
+    int en;
+    PCRE2_SIZE eo;
     int opts = 0;
+    PCRE2_UCHAR errbuffer[256];
 
-    regex_base = pcre_compile(DETECT_BASE_REGEX, opts, &eb, &eo, NULL);
+    regex_base = pcre2_compile(
+            (PCRE2_SPTR8)DETECT_BASE_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
     if (regex_base == NULL) {
-        FatalError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",DETECT_BASE_REGEX, eo, eb);
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        FatalError(SC_ERR_PCRE_COMPILE,
+                "pcre2 compile of \"%s\" failed at "
+                "offset %d: %s",
+                DETECT_BASE_REGEX, (int)eo, errbuffer);
     }
+    regex_base_match = pcre2_match_data_create_from_pattern(regex_base, NULL);
 
-    regex_base_study = pcre_study(regex_base, 0, &eb);
-    if (eb != NULL) {
-        FatalError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
-    }
-
-    regex_threshold = pcre_compile(DETECT_THRESHOLD_REGEX, opts, &eb, &eo, NULL);
+    regex_threshold = pcre2_compile(
+            (PCRE2_SPTR8)DETECT_THRESHOLD_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
     if (regex_threshold == NULL) {
-        FatalError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",DETECT_THRESHOLD_REGEX, eo, eb);
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        FatalError(SC_ERR_PCRE_COMPILE,
+                "pcre2 compile of \"%s\" failed at "
+                "offset %d: %s",
+                DETECT_THRESHOLD_REGEX, (int)eo, errbuffer);
     }
+    regex_threshold_match = pcre2_match_data_create_from_pattern(regex_threshold, NULL);
 
-    regex_threshold_study = pcre_study(regex_threshold, 0, &eb);
-    if (eb != NULL) {
-        FatalError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
-    }
-
-    regex_rate = pcre_compile(DETECT_RATE_REGEX, opts, &eb, &eo, NULL);
+    regex_rate = pcre2_compile(
+            (PCRE2_SPTR8)DETECT_RATE_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
     if (regex_rate == NULL) {
-        FatalError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",DETECT_RATE_REGEX, eo, eb);
-    }
-
-    regex_rate_study = pcre_study(regex_rate, 0, &eb);
-    if (eb != NULL) {
-        FatalError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        FatalError(SC_ERR_PCRE_COMPILE,
+                "pcre2 compile of \"%s\" failed at "
+                "offset %d: %s",
+                DETECT_RATE_REGEX, (int)eo, errbuffer);
     }
+    regex_rate_match = pcre2_match_data_create_from_pattern(regex_rate, NULL);
 
-    regex_suppress = pcre_compile(DETECT_SUPPRESS_REGEX, opts, &eb, &eo, NULL);
+    regex_suppress = pcre2_compile(
+            (PCRE2_SPTR8)DETECT_SUPPRESS_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
     if (regex_suppress == NULL) {
-        FatalError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",DETECT_SUPPRESS_REGEX, eo, eb);
-    }
-
-    regex_suppress_study = pcre_study(regex_suppress, 0, &eb);
-    if (eb != NULL) {
-        FatalError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        FatalError(SC_ERR_PCRE_COMPILE,
+                "pcre2 compile of \"%s\" failed at "
+                "offset %d: %s",
+                DETECT_SUPPRESS_REGEX, (int)eo, errbuffer);
     }
-
+    regex_suppress_match = pcre2_match_data_create_from_pattern(regex_suppress, NULL);
 }
 
 void SCThresholdConfGlobalFree(void)
 {
     if (regex_base != NULL) {
-        pcre_free(regex_base);
+        pcre2_code_free(regex_base);
         regex_base = NULL;
     }
-    if (regex_base_study != NULL) {
-        pcre_free(regex_base_study);
-        regex_base_study = NULL;
+    if (regex_base_match != NULL) {
+        pcre2_match_data_free(regex_base_match);
+        regex_base_match = NULL;
     }
 
     if (regex_threshold != NULL) {
-        pcre_free(regex_threshold);
+        pcre2_code_free(regex_threshold);
         regex_threshold = NULL;
     }
-    if (regex_threshold_study != NULL) {
-        pcre_free(regex_threshold_study);
-        regex_threshold_study = NULL;
+    if (regex_threshold_match != NULL) {
+        pcre2_match_data_free(regex_threshold_match);
+        regex_threshold_match = NULL;
     }
 
     if (regex_rate != NULL) {
-        pcre_free(regex_rate);
+        pcre2_code_free(regex_rate);
         regex_rate = NULL;
     }
-    if (regex_rate_study != NULL) {
-        pcre_free(regex_rate_study);
-        regex_rate_study = NULL;
+    if (regex_rate_match != NULL) {
+        pcre2_match_data_free(regex_rate_match);
+        regex_rate_match = NULL;
     }
 
     if (regex_suppress != NULL) {
-        pcre_free(regex_suppress);
+        pcre2_code_free(regex_suppress);
         regex_suppress = NULL;
     }
-    if (regex_suppress_study != NULL) {
-        pcre_free(regex_suppress_study);
-        regex_suppress_study = NULL;
+    if (regex_suppress_match != NULL) {
+        pcre2_match_data_free(regex_suppress_match);
+        regex_suppress_match = NULL;
     }
 }
 
@@ -648,43 +652,49 @@ static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr,
     uint32_t parsed_timeout = 0;
 
     int ret = 0;
-    int ov[MAX_SUBSTRINGS];
     uint32_t id = 0, gid = 0;
     ThresholdRuleType rule_type;
 
     if (de_ctx == NULL)
         return -1;
 
-    ret = pcre_exec(regex_base, regex_base_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
+    ret = pcre2_match(
+            regex_base, (PCRE2_SPTR8)rawstr, strlen(rawstr), 0, 0, regex_base_match, NULL);
     if (ret < 4) {
-        SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
+        SCLogError(SC_ERR_PCRE_MATCH, "pcre2_match parse error, ret %" PRId32 ", string %s", ret,
+                rawstr);
         goto error;
     }
 
     /* retrieve the classtype name */
-    ret = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, th_rule_type, sizeof(th_rule_type));
+    size_t copylen = sizeof(th_rule_type);
+    ret = pcre2_substring_copy_bynumber(
+            regex_base_match, 1, (PCRE2_UCHAR8 *)th_rule_type, &copylen);
     if (ret < 0) {
-        SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+        SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
         goto error;
     }
 
     /* retrieve the classtype name */
-    ret = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, th_gid, sizeof(th_gid));
+    copylen = sizeof(th_gid);
+    ret = pcre2_substring_copy_bynumber(regex_base_match, 2, (PCRE2_UCHAR8 *)th_gid, &copylen);
     if (ret < 0) {
-        SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+        SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
         goto error;
     }
 
-    ret = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3, th_sid, sizeof(th_sid));
+    copylen = sizeof(th_sid);
+    ret = pcre2_substring_copy_bynumber(regex_base_match, 3, (PCRE2_UCHAR8 *)th_sid, &copylen);
     if (ret < 0) {
-        SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+        SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
         goto error;
     }
 
     /* Use "get" for heap allocation */
-    ret = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 4, &rule_extend);
+    ret = pcre2_substring_get_bynumber(
+            regex_base_match, 4, (PCRE2_UCHAR8 **)&rule_extend, &copylen);
     if (ret < 0) {
-        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
         goto error;
     }
 
@@ -707,37 +717,44 @@ static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr,
         case THRESHOLD_TYPE_EVENT_FILTER:
         case THRESHOLD_TYPE_THRESHOLD:
             if (strlen(rule_extend) > 0) {
-                ret = pcre_exec(regex_threshold, regex_threshold_study,
-                        rule_extend, strlen(rule_extend),
-                        0, 0, ov, MAX_SUBSTRINGS);
+                ret = pcre2_match(regex_threshold, (PCRE2_SPTR8)rule_extend, strlen(rule_extend), 0,
+                        0, regex_threshold_match, NULL);
                 if (ret < 4) {
                     SCLogError(SC_ERR_PCRE_MATCH,
-                            "pcre_exec parse error, ret %" PRId32 ", string %s",
-                            ret, rule_extend);
+                            "pcre2_match parse error, ret %" PRId32 ", string %s", ret,
+                            rule_extend);
                     goto error;
                 }
 
-                ret = pcre_copy_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 1, th_type, sizeof(th_type));
+                copylen = sizeof(th_type);
+                ret = pcre2_substring_copy_bynumber(
+                        regex_threshold_match, 1, (PCRE2_UCHAR8 *)th_type, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
                     goto error;
                 }
 
-                ret = pcre_copy_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 2, th_track, sizeof(th_track));
+                copylen = sizeof(th_track);
+                ret = pcre2_substring_copy_bynumber(
+                        regex_threshold_match, 2, (PCRE2_UCHAR8 *)th_track, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
                     goto error;
                 }
 
-                ret = pcre_copy_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 3, th_count, sizeof(th_count));
+                copylen = sizeof(th_count);
+                ret = pcre2_substring_copy_bynumber(
+                        regex_threshold_match, 3, (PCRE2_UCHAR8 *)th_count, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
                     goto error;
                 }
 
-                ret = pcre_copy_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 4, th_seconds, sizeof(th_seconds));
+                copylen = sizeof(th_seconds);
+                ret = pcre2_substring_copy_bynumber(
+                        regex_threshold_match, 4, (PCRE2_UCHAR8 *)th_seconds, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
                     goto error;
                 }
 
@@ -758,25 +775,27 @@ static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr,
             break;
         case THRESHOLD_TYPE_SUPPRESS:
             if (strlen(rule_extend) > 0) {
-                ret = pcre_exec(regex_suppress, regex_suppress_study,
-                        rule_extend, strlen(rule_extend),
-                        0, 0, ov, MAX_SUBSTRINGS);
+                ret = pcre2_match(regex_suppress, (PCRE2_SPTR8)rule_extend, strlen(rule_extend), 0,
+                        0, regex_suppress_match, NULL);
                 if (ret < 2) {
                     SCLogError(SC_ERR_PCRE_MATCH,
-                            "pcre_exec parse error, ret %" PRId32 ", string %s",
-                            ret, rule_extend);
+                            "pcre2_match parse error, ret %" PRId32 ", string %s", ret,
+                            rule_extend);
                     goto error;
                 }
                 /* retrieve the track mode */
-                ret = pcre_copy_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 1, th_track, sizeof(th_track));
+                copylen = sizeof(th_seconds);
+                ret = pcre2_substring_copy_bynumber(
+                        regex_suppress_match, 1, (PCRE2_UCHAR8 *)th_track, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
                     goto error;
                 }
                 /* retrieve the IP; use "get" for heap allocation */
-                ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 2, &th_ip);
+                ret = pcre2_substring_get_bynumber(
+                        regex_suppress_match, 2, (PCRE2_UCHAR8 **)&th_ip, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+                    SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
                     goto error;
                 }
             } else {
@@ -786,43 +805,52 @@ static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr,
             break;
         case THRESHOLD_TYPE_RATE:
             if (strlen(rule_extend) > 0) {
-                ret = pcre_exec(regex_rate, regex_rate_study,
-                        rule_extend, strlen(rule_extend),
-                        0, 0, ov, MAX_SUBSTRINGS);
+                ret = pcre2_match(regex_rate, (PCRE2_SPTR8)rule_extend, strlen(rule_extend), 0, 0,
+                        regex_rate_match, NULL);
                 if (ret < 5) {
                     SCLogError(SC_ERR_PCRE_MATCH,
-                            "pcre_exec parse error, ret %" PRId32 ", string %s",
-                            ret, rule_extend);
+                            "pcre2_match parse error, ret %" PRId32 ", string %s", ret,
+                            rule_extend);
                     goto error;
                 }
 
-                ret = pcre_copy_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 1, th_track, sizeof(th_track));
+                copylen = sizeof(th_track);
+                ret = pcre2_substring_copy_bynumber(
+                        regex_rate_match, 1, (PCRE2_UCHAR8 *)th_track, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
                     goto error;
                 }
 
-                ret = pcre_copy_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 2, th_count, sizeof(th_count));
+                copylen = sizeof(th_count);
+                ret = pcre2_substring_copy_bynumber(
+                        regex_rate_match, 2, (PCRE2_UCHAR8 *)th_count, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
                     goto error;
                 }
 
-                ret = pcre_copy_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 3, th_seconds, sizeof(th_seconds));
+                copylen = sizeof(th_seconds);
+                ret = pcre2_substring_copy_bynumber(
+                        regex_rate_match, 3, (PCRE2_UCHAR8 *)th_seconds, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
                     goto error;
                 }
 
-                ret = pcre_copy_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 4, th_new_action, sizeof(th_new_action));
+                copylen = sizeof(th_new_action);
+                ret = pcre2_substring_copy_bynumber(
+                        regex_rate_match, 4, (PCRE2_UCHAR8 *)th_new_action, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
                     goto error;
                 }
 
-                ret = pcre_copy_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 5, th_timeout, sizeof(th_timeout));
+                copylen = sizeof(th_timeout);
+                ret = pcre2_substring_copy_bynumber(
+                        regex_rate_match, 5, (PCRE2_UCHAR8 *)th_timeout, &copylen);
                 if (ret < 0) {
-                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                    SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre2_substring_copy_bynumber failed");
                     goto error;
                 }
 
@@ -926,18 +954,16 @@ static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr,
     *ret_th_ip = NULL;
     if (th_ip != NULL) {
         *ret_th_ip = (char *)th_ip;
-    } else {
-        SCFree((char *)th_ip);
     }
-    SCFree((char *)rule_extend);
+    pcre2_substring_free((PCRE2_UCHAR8 *)rule_extend);
     return 0;
 
 error:
     if (rule_extend != NULL) {
-        SCFree((char *)rule_extend);
+        pcre2_substring_free((PCRE2_UCHAR8 *)rule_extend);
     }
     if (th_ip != NULL) {
-        SCFree((char *)th_ip);
+        pcre2_substring_free((PCRE2_UCHAR8 *)th_ip);
     }
     return -1;
 }
@@ -983,11 +1009,11 @@ static int SCThresholdConfAddThresholdtype(char *rawstr, DetectEngineCtx *de_ctx
         goto error;
     }
 
-    SCFree(th_ip);
+    pcre2_substring_free((PCRE2_UCHAR8 *)th_ip);
     return 0;
 error:
     if (th_ip != NULL)
-        SCFree(th_ip);
+        pcre2_substring_free((PCRE2_UCHAR8 *)th_ip);
     return -1;
 }
 
index 57d5f94d03d0d7d7bce620b606452cd32bf4432a..a9645ac0e7c08c7dd399f6001b59e3e331c889ad 100644 (file)
 #include "util-debug.h"
 #include "util-time.h"
 #include "conf.h"
+#include <pcre2.h>
 
 #include "stream-tcp.h"
 #include "stream-tcp-reassemble.h"
 
 #ifdef UNITTESTS
 
-static pcre *parse_regex;
-static pcre_extra *parse_regex_study;
+static pcre2_code *parse_regex;
+static pcre2_match_data *parse_regex_match;
 
 static UtTest *ut_list;
 
@@ -124,26 +125,26 @@ void UtRegisterTest(const char *name, int(*TestFn)(void))
  */
 static int UtRegex (const char *regex_arg)
 {
-    const char *eb;
-    int eo;
-    int opts = PCRE_CASELESS;;
+    int en;
+    PCRE2_SIZE eo;
+    int opts = PCRE2_CASELESS;
 
     if(regex_arg == NULL)
         return -1;
 
-    parse_regex = pcre_compile(regex_arg, opts, &eb, &eo, NULL);
+    parse_regex =
+            pcre2_compile((PCRE2_SPTR8)regex_arg, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
     if(parse_regex == NULL)
     {
-        printf("pcre compile of \"%s\" failed at offset %" PRId32 ": %s\n", regex_arg, eo, eb);
-        goto error;
-    }
-
-    parse_regex_study = pcre_study(parse_regex, 0, &eb);
-    if(eb != NULL)
-    {
-        printf("pcre study failed: %s\n", eb);
+        PCRE2_UCHAR errbuffer[256];
+        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
+        SCLogError(SC_ERR_PCRE_COMPILE,
+                "pcre2 compile of \"%s\" failed at "
+                "offset %d: %s",
+                regex_arg, (int)eo, errbuffer);
         goto error;
     }
+    parse_regex_match = pcre2_match_data_create_from_pattern(parse_regex, NULL);
 
     return 1;
 
@@ -151,8 +152,6 @@ error:
     return -1;
 }
 
-#define MAX_SUBSTRINGS 30
-
 /** \brief List all registered unit tests.
  *
  *  \param regex_arg Regular expression to limit listed tests.
@@ -161,14 +160,13 @@ void UtListTests(const char *regex_arg)
 {
     UtTest *ut;
     int ret = 0, rcomp = 0;
-    int ov[MAX_SUBSTRINGS];
 
     rcomp = UtRegex(regex_arg);
 
     for (ut = ut_list; ut != NULL; ut = ut->next) {
         if (rcomp == 1)  {
-            ret = pcre_exec(parse_regex, parse_regex_study, ut->name,
-                strlen(ut->name), 0, 0, ov, MAX_SUBSTRINGS);
+            ret = pcre2_match(parse_regex, (PCRE2_SPTR8)ut->name, strlen(ut->name), 0, 0,
+                    parse_regex_match, NULL);
             if (ret >= 1) {
                 printf("%s\n", ut->name);
             }
@@ -177,6 +175,8 @@ void UtListTests(const char *regex_arg)
             printf("%s\n", ut->name);
         }
     }
+    pcre2_code_free(parse_regex);
+    pcre2_match_data_free(parse_regex_match);
 }
 
 /** \brief Run all registered unittests.
@@ -192,7 +192,6 @@ uint32_t UtRunTests(const char *regex_arg)
     UtTest *ut;
     uint32_t good = 0, bad = 0, matchcnt = 0;
     int ret = 0, rcomp = 0;
-    int ov[MAX_SUBSTRINGS];
 
     StreamTcpInitMemuse();
     StreamTcpReassembleInitMemuse();
@@ -201,7 +200,8 @@ uint32_t UtRunTests(const char *regex_arg)
 
     if(rcomp == 1){
         for (ut = ut_list; ut != NULL; ut = ut->next) {
-            ret = pcre_exec(parse_regex, parse_regex_study, ut->name, strlen(ut->name), 0, 0, ov, MAX_SUBSTRINGS);
+            ret = pcre2_match(parse_regex, (PCRE2_SPTR8)ut->name, strlen(ut->name), 0, 0,
+                    parse_regex_match, NULL);
             if( ret >= 1 )  {
                 printf("Test %-60.60s : ", ut->name);
                 matchcnt++;
@@ -251,6 +251,8 @@ uint32_t UtRunTests(const char *regex_arg)
     } else {
         SCLogInfo("UtRunTests: pcre compilation failed");
     }
+    pcre2_code_free(parse_regex);
+    pcre2_match_data_free(parse_regex_match);
     return bad;
 }
 /**