From 3633c48e6e2d738a1f9521d1855aeab33b85151c Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 13 Apr 2021 14:08:09 +0200 Subject: [PATCH] pcre2: migrate utility uses of pcre --- src/detect-engine-analyzer.c | 32 ++-- src/log-pcap.c | 47 +++--- src/util-classification-config.c | 56 +++---- src/util-debug.c | 38 ++--- src/util-debug.h | 5 +- src/util-host-info.c | 42 +++--- src/util-misc.c | 59 ++++---- src/util-reference-config.c | 50 +++---- src/util-threshold-config.c | 246 +++++++++++++++++-------------- src/util-unittest.c | 44 +++--- 10 files changed, 321 insertions(+), 298 deletions(-) diff --git a/src/detect-engine-analyzer.c b/src/detect-engine-analyzer.c index 9e5037d576..21b98df42c 100644 --- a/src/detect-engine-analyzer.c +++ b/src/detect-engine-analyzer.c @@ -38,12 +38,13 @@ #include "detect-tcp-flags.h" #include "feature.h" #include "util-print.h" +#include 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; } diff --git a/src/log-pcap.c b/src/log-pcap.c index 07ac49452c..0a954023e7 100644 --- a/src/log-pcap.c +++ b/src/log-pcap.c @@ -58,6 +58,7 @@ #include "util-misc.h" #include "util-cpu.h" #include "util-atomic.h" +#include #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, ©len) < + 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, ©len) < + 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; } diff --git a/src/util-classification-config.c b/src/util-classification-config.c index 6006973734..0f875ffa64 100644 --- a/src/util-classification-config.c +++ b/src/util-classification-config.c @@ -35,6 +35,7 @@ #include "util-debug.h" #include "util-fmemopen.h" #include "util-byte.h" +#include /* 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, ©len); 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, ©len); 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, ©len); 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) { diff --git a/src/util-debug.c b/src/util-debug.c index 60322b95a9..648471af92 100644 --- a/src/util-debug.c +++ b/src/util-debug.c @@ -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); diff --git a/src/util-debug.h b/src/util-debug.h index 9c93b5ce51..ff032aecf4 100644 --- a/src/util-debug.h +++ b/src/util-debug.h @@ -31,6 +31,7 @@ #include "util-error.h" #include "util-debug-filters.h" #include "util-atomic.h" +#include /** * \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; diff --git a/src/util-host-info.c b/src/util-host-info.c index 0f02d98190..afd186dca2 100644 --- a/src/util-host-info.c +++ b/src/util-host-info.c @@ -27,6 +27,7 @@ #include "suricata-common.h" #include "util-host-info.h" #include "util-byte.h" +#include #ifndef OS_WIN32 #include @@ -36,16 +37,14 @@ 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; diff --git a/src/util-misc.c b/src/util-misc.c index 2190d5aae2..deafedfa90 100644 --- a/src/util-misc.c +++ b/src/util-misc.c @@ -27,47 +27,44 @@ #include "util-debug.h" #include "util-unittest.h" #include "util-misc.h" +#include #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, ©len); 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, ©len); + 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; } diff --git a/src/util-reference-config.c b/src/util-reference-config.c index 4519b7b019..6768ec5448 100644 --- a/src/util-reference-config.c +++ b/src/util-reference-config.c @@ -25,6 +25,7 @@ #include "detect.h" #include "detect-engine.h" #include "util-hash.h" +#include #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, ©len); 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, ©len); 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; } diff --git a/src/util-threshold-config.c b/src/util-threshold-config.c index e81d14a569..d22a755a75 100644 --- a/src/util-threshold-config.c +++ b/src/util-threshold-config.c @@ -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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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, ©len); 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; } diff --git a/src/util-unittest.c b/src/util-unittest.c index 57d5f94d03..a9645ac0e7 100644 --- a/src/util-unittest.c +++ b/src/util-unittest.c @@ -38,14 +38,15 @@ #include "util-debug.h" #include "util-time.h" #include "conf.h" +#include #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; } /**