pcre2: migrate utility uses of pcre

pull/6414/head
Philippe Antoine 5 years ago
parent 95a07c8957
commit 3633c48e6e

@ -38,12 +38,13 @@
#include "detect-tcp-flags.h" #include "detect-tcp-flags.h"
#include "feature.h" #include "feature.h"
#include "util-print.h" #include "util-print.h"
#include <pcre2.h>
static int rule_warnings_only = 0; static int rule_warnings_only = 0;
static FILE *rule_engine_analysis_FD = NULL; static FILE *rule_engine_analysis_FD = NULL;
static FILE *fp_engine_analysis_FD = NULL; static FILE *fp_engine_analysis_FD = NULL;
static pcre *percent_re = NULL; static pcre2_code *percent_re = NULL;
static pcre_extra *percent_re_study = NULL; static pcre2_match_data *percent_re_match = NULL;
static char log_path[PATH_MAX]; static char log_path[PATH_MAX];
typedef struct FpPatternStats_ { typedef struct FpPatternStats_ {
@ -417,6 +418,10 @@ void CleanupRuleAnalyzer(void)
fclose(rule_engine_analysis_FD); fclose(rule_engine_analysis_FD);
rule_engine_analysis_FD = NULL; 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 () int PerCentEncodingSetup ()
{ {
#define DETECT_PERCENT_ENCODING_REGEX "%[0-9|a-f|A-F]{2}" #define DETECT_PERCENT_ENCODING_REGEX "%[0-9|a-f|A-F]{2}"
const char *eb = NULL; int en;
int eo = 0; PCRE2_SIZE eo = 0;
int opts = 0; //PCRE_NEWLINE_ANY?? 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) { if (percent_re == NULL) {
SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", PCRE2_UCHAR errbuffer[256];
DETECT_PERCENT_ENCODING_REGEX, eo, eb); 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; return 0;
} }
percent_re_study = pcre_study(percent_re, 0, &eb); percent_re_match = pcre2_match_data_create_from_pattern(percent_re, NULL);
if (eb != NULL) {
SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
return 0;
}
return 1; return 1;
} }
@ -455,11 +459,9 @@ int PerCentEncodingSetup ()
*/ */
int PerCentEncodingMatch (uint8_t *content, uint8_t content_len) int PerCentEncodingMatch (uint8_t *content, uint8_t content_len)
{ {
#define MAX_ENCODED_CHARS 240
int ret = 0; 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) { if (ret == -1) {
return 0; return 0;
} }

@ -58,6 +58,7 @@
#include "util-misc.h" #include "util-misc.h"
#include "util-cpu.h" #include "util-cpu.h"
#include "util-atomic.h" #include "util-atomic.h"
#include <pcre2.h>
#include "source-pcap.h" #include "source-pcap.h"
@ -186,8 +187,8 @@ typedef struct PcapLogThreadData_ {
/* Pattern for extracting timestamp from pcap log files. */ /* Pattern for extracting timestamp from pcap log files. */
static const char timestamp_pattern[] = ".*?(\\d+)(\\.(\\d+))?"; static const char timestamp_pattern[] = ".*?(\\d+)(\\.(\\d+))?";
static pcre *pcre_timestamp_code = NULL; static pcre2_code *pcre_timestamp_code = NULL;
static pcre_extra *pcre_timestamp_extra = NULL; static pcre2_match_data *pcre_timestamp_match = NULL;
/* global pcap data for when we're using multi mode. At exit we'll /* global pcap data for when we're using multi mode. At exit we'll
* merge counters into this one and then report counters. */ * 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, static int PcapLogGetTimeOfFile(const char *filename, uint64_t *secs,
uint32_t *usecs) uint32_t *usecs)
{ {
int pcre_ovecsize = 4 * 3;
int pcre_ovec[pcre_ovecsize];
char buf[PATH_MAX]; char buf[PATH_MAX];
size_t copylen;
int n = pcre_exec(pcre_timestamp_code, pcre_timestamp_extra, int n = pcre2_match(pcre_timestamp_code, (PCRE2_SPTR8)filename, strlen(filename), 0, 0,
filename, strlen(filename), 0, 0, pcre_ovec, pcre_timestamp_match, NULL);
pcre_ovecsize);
if (n != 2 && n != 4) { if (n != 2 && n != 4) {
/* No match. */ /* No match. */
return 0; return 0;
@ -731,8 +730,9 @@ static int PcapLogGetTimeOfFile(const char *filename, uint64_t *secs,
if (n >= 2) { if (n >= 2) {
/* Extract seconds. */ /* Extract seconds. */
if (pcre_copy_substring(filename, pcre_ovec, pcre_ovecsize, copylen = sizeof(buf);
1, buf, sizeof(buf)) < 0) { if (pcre2_substring_copy_bynumber(pcre_timestamp_match, 1, (PCRE2_UCHAR8 *)buf, &copylen) <
0) {
return 0; return 0;
} }
if (StringParseUint64(secs, 10, 0, buf) < 0) { if (StringParseUint64(secs, 10, 0, buf) < 0) {
@ -741,8 +741,9 @@ static int PcapLogGetTimeOfFile(const char *filename, uint64_t *secs,
} }
if (n == 4) { if (n == 4) {
/* Extract microseconds. */ /* Extract microseconds. */
if (pcre_copy_substring(filename, pcre_ovec, pcre_ovecsize, copylen = sizeof(buf);
3, buf, sizeof(buf)) < 0) { if (pcre2_substring_copy_bynumber(pcre_timestamp_match, 3, (PCRE2_UCHAR8 *)buf, &copylen) <
0) {
return 0; return 0;
} }
if (StringParseUint32(usecs, 10, 0, buf) < 0) { if (StringParseUint32(usecs, 10, 0, buf) < 0) {
@ -1172,8 +1173,8 @@ error:
static OutputInitResult PcapLogInitCtx(ConfNode *conf) static OutputInitResult PcapLogInitCtx(ConfNode *conf)
{ {
OutputInitResult result = { NULL, false }; OutputInitResult result = { NULL, false };
const char *pcre_errbuf; int en;
int pcre_erroffset; PCRE2_SIZE eo = 0;
PcapLogData *pl = SCMalloc(sizeof(PcapLogData)); PcapLogData *pl = SCMalloc(sizeof(PcapLogData));
if (unlikely(pl == NULL)) { if (unlikely(pl == NULL)) {
@ -1200,17 +1201,15 @@ static OutputInitResult PcapLogInitCtx(ConfNode *conf)
SCMutexInit(&pl->plog_lock, NULL); SCMutexInit(&pl->plog_lock, NULL);
/* Initialize PCREs. */ /* Initialize PCREs. */
pcre_timestamp_code = pcre_compile(timestamp_pattern, 0, &pcre_errbuf, pcre_timestamp_code =
&pcre_erroffset, NULL); pcre2_compile((PCRE2_SPTR8)timestamp_pattern, PCRE2_ZERO_TERMINATED, 0, &en, &eo, NULL);
if (pcre_timestamp_code == NULL) { if (pcre_timestamp_code == NULL) {
FatalError(SC_ERR_PCRE_COMPILE, PCRE2_UCHAR errbuffer[256];
"Failed to compile \"%s\" at offset %"PRIu32": %s", pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
timestamp_pattern, pcre_erroffset, pcre_errbuf); FatalError(SC_ERR_PCRE_COMPILE, "Failed to compile \"%s\" at offset %d: %s",
} timestamp_pattern, (int)eo, errbuffer);
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);
} }
pcre_timestamp_match = pcre2_match_data_create_from_pattern(pcre_timestamp_code, NULL);
/* conf params */ /* conf params */
@ -1523,6 +1522,10 @@ static void PcapLogFileDeInitCtx(OutputCtx *output_ctx)
} }
PcapLogDataFree(pl); PcapLogDataFree(pl);
SCFree(output_ctx); SCFree(output_ctx);
pcre2_code_free(pcre_timestamp_code);
pcre2_match_data_free(pcre_timestamp_match);
return; return;
} }

@ -35,6 +35,7 @@
#include "util-debug.h" #include "util-debug.h"
#include "util-fmemopen.h" #include "util-fmemopen.h"
#include "util-byte.h" #include "util-byte.h"
#include <pcre2.h>
/* Regex to parse the classtype argument from a Signature. The first substring /* Regex to parse the classtype argument from a Signature. The first substring
* holds the classtype name, the second substring holds the classtype the * 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" #define SC_CLASS_CONF_DEF_CONF_FILEPATH CONFIG_DIR "/classification.config"
#endif #endif
static pcre *regex = NULL; static pcre2_code *regex = NULL;
static pcre_extra *regex_study = NULL; static pcre2_match_data *regex_match = NULL;
uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen); uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen);
char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1, char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1,
@ -63,36 +64,34 @@ static void SCClassConfDeAllocClasstype(SCClassConfClasstype *ct);
void SCClassConfInit(void) void SCClassConfInit(void)
{ {
const char *eb = NULL; int en;
int eo; PCRE2_SIZE eo;
int opts = 0; 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) { if (regex == NULL) {
SCLogDebug("Compile of \"%s\" failed at offset %" PRId32 ": %s", PCRE2_UCHAR errbuffer[256];
DETECT_CLASSCONFIG_REGEX, eo, eb); pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
return; SCLogWarning(SC_ERR_PCRE_COMPILE,
} "pcre2 compile of \"%s\" failed at "
"offset %d: %s",
regex_study = pcre_study(regex, 0, &eb); DETECT_CLASSCONFIG_REGEX, (int)eo, errbuffer);
if (eb != NULL) {
pcre_free(regex);
regex = NULL;
SCLogDebug("pcre study failed: %s", eb);
return; return;
} }
regex_match = pcre2_match_data_create_from_pattern(regex, NULL);
return; return;
} }
void SCClassConfDeinit(void) void SCClassConfDeinit(void)
{ {
if (regex != NULL) { if (regex != NULL) {
pcre_free(regex); pcre2_code_free(regex);
regex = NULL; regex = NULL;
} }
if (regex_study != NULL) { if (regex_match != NULL) {
pcre_free(regex_study); pcre2_match_data_free(regex_match);
regex_study = NULL; regex_match = NULL;
} }
} }
@ -251,35 +250,36 @@ int SCClassConfAddClasstype(DetectEngineCtx *de_ctx, char *rawstr, uint16_t inde
SCClassConfClasstype *ct_new = NULL; SCClassConfClasstype *ct_new = NULL;
SCClassConfClasstype *ct_lookup = NULL; SCClassConfClasstype *ct_lookup = NULL;
#define MAX_SUBSTRINGS 30
int ret = 0; 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) { if (ret < 0) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid Classtype in " SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid Classtype in "
"classification.config file"); "classification.config file");
goto error; goto error;
} }
size_t copylen = sizeof(ct_name);
/* retrieve the classtype 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) { if (ret < 0) {
SCLogInfo("pcre_copy_substring() failed"); SCLogInfo("pcre2_substring_copy_bynumber() failed");
goto error; goto error;
} }
/* retrieve the classtype description */ /* 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) { if (ret < 0) {
SCLogInfo("pcre_copy_substring() failed"); SCLogInfo("pcre2_substring_copy_bynumber() failed");
goto error; goto error;
} }
/* retrieve the classtype priority */ /* 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) { if (ret < 0) {
SCLogInfo("pcre_copy_substring() failed"); SCLogInfo("pcre2_substring_copy_bynumber() failed");
goto error; goto error;
} }
if (StringParseUint32(&ct_priority, 10, 0, (const char *)ct_priority_str) < 0) { if (StringParseUint32(&ct_priority, 10, 0, (const char *)ct_priority_str) < 0) {

@ -492,16 +492,10 @@ static SCError SCLogMessageGetBuffer(
} }
if (sc_log_config->op_filter_regex != NULL) { if (sc_log_config->op_filter_regex != NULL) {
#define MAX_SUBSTRINGS 30 if (pcre2_match(sc_log_config->op_filter_regex, (PCRE2_SPTR8)buffer, strlen(buffer), 0, 0,
int ov[MAX_SUBSTRINGS]; sc_log_config->op_filter_regex_match, NULL) < 0) {
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)
{
return SC_ERR_LOG_FG_FILTER_MATCH; // bit hacky, but just return !0 return SC_ERR_LOG_FG_FILTER_MATCH; // bit hacky, but just return !0
} }
#undef MAX_SUBSTRINGS
} }
return SC_OK; return SC_OK;
@ -1109,8 +1103,8 @@ static inline void SCLogSetOPFilter(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
const char *filter = NULL; const char *filter = NULL;
int opts = 0; int opts = 0;
const char *ep; int en;
int eo = 0; PCRE2_SIZE eo = 0;
/* envvar overrides */ /* envvar overrides */
filter = getenv(SC_LOG_ENV_LOG_OP_FILTER); 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"); printf("pcre filter alloc failed\n");
return; 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) { if (sc_lc->op_filter_regex == NULL) {
SCFree(sc_lc->op_filter); SCFree(sc_lc->op_filter);
printf("pcre compile of \"%s\" failed at offset %d : %s\n", filter, PCRE2_UCHAR errbuffer[256];
eo, ep); pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
return; printf("pcre2 compile of \"%s\" failed at offset %d : %s\n", filter, (int)eo,
} errbuffer);
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);
return; return;
} }
sc_lc->op_filter_regex_match =
pcre2_match_data_create_from_pattern(sc_lc->op_filter_regex, NULL);
} }
return; return;
@ -1199,9 +1191,9 @@ static inline void SCLogFreeLogConfig(SCLogConfig *sc_lc)
SCFree(sc_lc->op_filter); SCFree(sc_lc->op_filter);
if (sc_lc->op_filter_regex != NULL) if (sc_lc->op_filter_regex != NULL)
pcre_free(sc_lc->op_filter_regex); pcre2_code_free(sc_lc->op_filter_regex);
if (sc_lc->op_filter_regex_study) if (sc_lc->op_filter_regex_match)
pcre_free_study(sc_lc->op_filter_regex_study); pcre2_match_data_free(sc_lc->op_filter_regex_match);
SCLogFreeLogOPIfaceCtx(sc_lc->op_ifaces); SCLogFreeLogOPIfaceCtx(sc_lc->op_ifaces);
SCFree(sc_lc); SCFree(sc_lc);

@ -31,6 +31,7 @@
#include "util-error.h" #include "util-error.h"
#include "util-debug-filters.h" #include "util-debug-filters.h"
#include "util-atomic.h" #include "util-atomic.h"
#include <pcre2.h>
/** /**
* \brief ENV vars that can be used to set the properties for the logging module * \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; char *op_filter;
/* compiled pcre filter expression */ /* compiled pcre filter expression */
pcre *op_filter_regex; pcre2_code *op_filter_regex;
pcre_extra *op_filter_regex_study; pcre2_match_data *op_filter_regex_match;
/* op ifaces used */ /* op ifaces used */
SCLogOPIfaceCtx *op_ifaces; SCLogOPIfaceCtx *op_ifaces;

@ -27,6 +27,7 @@
#include "suricata-common.h" #include "suricata-common.h"
#include "util-host-info.h" #include "util-host-info.h"
#include "util-byte.h" #include "util-byte.h"
#include <pcre2.h>
#ifndef OS_WIN32 #ifndef OS_WIN32
#include <sys/utsname.h> #include <sys/utsname.h>
@ -36,16 +37,14 @@
int SCKernelVersionIsAtLeast(int major, int minor) int SCKernelVersionIsAtLeast(int major, int minor)
{ {
struct utsname kuname; struct utsname kuname;
pcre *version_regex; pcre2_code *version_regex;
pcre_extra *version_regex_study; pcre2_match_data *version_regex_match;
const char *eb; int en;
int opts = 0; int opts = 0;
int eo; PCRE2_SIZE eo;
#define MAX_SUBSTRINGS 3 * 6
int ov[MAX_SUBSTRINGS];
int ret; int ret;
int kmajor, kminor; int kmajor, kminor;
const char **list; PCRE2_UCHAR **list;
/* get local version */ /* get local version */
if (uname(&kuname) != 0) { if (uname(&kuname) != 0) {
@ -56,20 +55,21 @@ int SCKernelVersionIsAtLeast(int major, int minor)
SCLogDebug("Kernel release is '%s'", kuname.release); 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) { 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; goto error;
} }
version_regex_match = pcre2_match_data_create_from_pattern(version_regex, NULL);
version_regex_study = pcre_study(version_regex, 0, &eb); ret = pcre2_match(version_regex, (PCRE2_SPTR8)kuname.release, strlen(kuname.release), 0, 0,
if (eb != NULL) { version_regex_match, 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);
if (ret < 0) { if (ret < 0) {
SCLogError(SC_ERR_PCRE_MATCH, "Version did not cut"); SCLogError(SC_ERR_PCRE_MATCH, "Version did not cut");
@ -81,7 +81,7 @@ int SCKernelVersionIsAtLeast(int major, int minor)
goto error; goto error;
} }
pcre_get_substring_list(kuname.release, ov, ret, &list); pcre2_substring_list_get(version_regex_match, &list, NULL);
bool err = false; bool err = false;
if (StringParseInt32(&kmajor, 10, 0, (const char *)list[1]) < 0) { if (StringParseInt32(&kmajor, 10, 0, (const char *)list[1]) < 0) {
@ -93,9 +93,9 @@ int SCKernelVersionIsAtLeast(int major, int minor)
err = true; err = true;
} }
pcre_free_substring_list(list); pcre2_substring_list_free((PCRE2_SPTR *)list);
pcre_free_study(version_regex_study); pcre2_match_data_free(version_regex_match);
pcre_free(version_regex); pcre2_code_free(version_regex);
if (err) if (err)
goto error; goto error;

@ -27,47 +27,44 @@
#include "util-debug.h" #include "util-debug.h"
#include "util-unittest.h" #include "util-unittest.h"
#include "util-misc.h" #include "util-misc.h"
#include <pcre2.h>
#define PARSE_REGEX "^\\s*(\\d+(?:.\\d+)?)\\s*([a-zA-Z]{2})?\\s*$" #define PARSE_REGEX "^\\s*(\\d+(?:.\\d+)?)\\s*([a-zA-Z]{2})?\\s*$"
static pcre *parse_regex = NULL; static pcre2_code *parse_regex = NULL;
static pcre_extra *parse_regex_study = NULL; static pcre2_match_data *parse_regex_match = NULL;
void ParseSizeInit(void) void ParseSizeInit(void)
{ {
const char *eb = NULL; int en;
int eo; PCRE2_SIZE eo;
int opts = 0; 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) { if (parse_regex == NULL) {
SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset " PCRE2_UCHAR errbuffer[256];
"%" PRId32 ": %s", PARSE_REGEX, eo, eb); pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
exit(EXIT_FAILURE); SCLogError(SC_ERR_PCRE_COMPILE,
} "pcre2 compile of \"%s\" failed at "
parse_regex_study = pcre_study(parse_regex, 0, &eb); "offset %d: %s",
if (eb != NULL) { PARSE_REGEX, (int)eo, errbuffer);
SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
parse_regex_match = pcre2_match_data_create_from_pattern(parse_regex, NULL);
} }
void ParseSizeDeinit(void) void ParseSizeDeinit(void)
{ {
pcre2_code_free(parse_regex);
if (parse_regex != NULL) pcre2_match_data_free(parse_regex_match);
pcre_free(parse_regex);
if (parse_regex_study != NULL)
pcre_free_study(parse_regex_study);
} }
/* size string parsing API */ /* size string parsing API */
static int ParseSizeString(const char *size, double *res) static int ParseSizeString(const char *size, double *res)
{ {
#define MAX_SUBSTRINGS 30 int pcre2_match_ret;
int pcre_exec_ret;
int r; int r;
int ov[MAX_SUBSTRINGS];
int retval = 0; int retval = 0;
char str[128]; char str[128];
char str2[128]; char str2[128];
@ -86,9 +83,10 @@ static int ParseSizeString(const char *size, double *res)
goto end; goto end;
} }
pcre_exec_ret = pcre_exec(parse_regex, parse_regex_study, size, strlen(size), 0, 0, pcre2_match_ret = pcre2_match(
ov, MAX_SUBSTRINGS); parse_regex, (PCRE2_SPTR8)size, strlen(size), 0, 0, parse_regex_match, NULL);
if (!(pcre_exec_ret == 2 || pcre_exec_ret == 3)) {
if (!(pcre2_match_ret == 2 || pcre2_match_ret == 3)) {
SCLogError(SC_ERR_PCRE_MATCH, "invalid size argument - %s. Valid size " SCLogError(SC_ERR_PCRE_MATCH, "invalid size argument - %s. Valid size "
"argument should be in the format - \n" "argument should be in the format - \n"
"xxx <- indicates it is just bytes\n" "xxx <- indicates it is just bytes\n"
@ -100,10 +98,10 @@ static int ParseSizeString(const char *size, double *res)
goto end; goto end;
} }
r = pcre_copy_substring((char *)size, ov, MAX_SUBSTRINGS, 1, size_t copylen = sizeof(str);
str, sizeof(str)); r = pcre2_substring_copy_bynumber(parse_regex_match, 1, (PCRE2_UCHAR8 *)str, &copylen);
if (r < 0) { 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; retval = -2;
goto end; goto end;
} }
@ -121,11 +119,12 @@ static int ParseSizeString(const char *size, double *res)
goto end; goto end;
} }
if (pcre_exec_ret == 3) { if (pcre2_match_ret == 3) {
r = pcre_copy_substring((char *)size, ov, MAX_SUBSTRINGS, 2, copylen = sizeof(str2);
str2, sizeof(str2)); r = pcre2_substring_copy_bynumber(parse_regex_match, 2, (PCRE2_UCHAR8 *)str2, &copylen);
if (r < 0) { 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; retval = -2;
goto end; goto end;
} }

@ -25,6 +25,7 @@
#include "detect.h" #include "detect.h"
#include "detect-engine.h" #include "detect-engine.h"
#include "util-hash.h" #include "util-hash.h"
#include <pcre2.h>
#include "util-reference-config.h" #include "util-reference-config.h"
#include "conf.h" #include "conf.h"
@ -41,8 +42,8 @@
/* Default path for the reference.conf file */ /* Default path for the reference.conf file */
#define SC_RCONF_DEFAULT_FILE_PATH CONFIG_DIR "/reference.config" #define SC_RCONF_DEFAULT_FILE_PATH CONFIG_DIR "/reference.config"
static pcre *regex = NULL; static pcre2_code *regex = NULL;
static pcre_extra *regex_study = NULL; static pcre2_match_data *regex_match = NULL;
/* the hash functions */ /* the hash functions */
uint32_t SCRConfReferenceHashFunc(HashTable *ht, void *data, uint16_t datalen); 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) void SCReferenceConfInit(void)
{ {
const char *eb = NULL; int en;
int eo; PCRE2_SIZE eo;
int opts = 0; 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) { if (regex == NULL) {
SCLogDebug("Compile of \"%s\" failed at offset %" PRId32 ": %s", PCRE2_UCHAR errbuffer[256];
SC_RCONF_REGEX, eo, eb); pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
return; SCLogWarning(SC_ERR_PCRE_COMPILE,
} "pcre2 compile of \"%s\" failed at "
"offset %d: %s",
regex_study = pcre_study(regex, 0, &eb); SC_RCONF_REGEX, (int)eo, errbuffer);
if (eb != NULL) {
pcre_free(regex);
regex = NULL;
SCLogDebug("pcre study failed: %s", eb);
return; return;
} }
regex_match = pcre2_match_data_create_from_pattern(regex, NULL);
return; return;
} }
@ -80,12 +78,12 @@ void SCReferenceConfInit(void)
void SCReferenceConfDeinit(void) void SCReferenceConfDeinit(void)
{ {
if (regex != NULL) { if (regex != NULL) {
pcre_free(regex); pcre2_code_free(regex);
regex = NULL; regex = NULL;
} }
if (regex_study != NULL) { if (regex_match != NULL) {
pcre_free(regex_study); pcre2_match_data_free(regex_match);
regex_study = NULL; regex_match = NULL;
} }
} }
@ -238,11 +236,9 @@ int SCRConfAddReference(DetectEngineCtx *de_ctx, const char *line)
SCRConfReference *ref_new = NULL; SCRConfReference *ref_new = NULL;
SCRConfReference *ref_lookup = NULL; SCRConfReference *ref_lookup = NULL;
#define MAX_SUBSTRINGS 30
int ret = 0; 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) { if (ret < 0) {
SCLogError(SC_ERR_REFERENCE_CONFIG, "Invalid Reference Config in " SCLogError(SC_ERR_REFERENCE_CONFIG, "Invalid Reference Config in "
"reference.config file"); "reference.config file");
@ -250,16 +246,18 @@ int SCRConfAddReference(DetectEngineCtx *de_ctx, const char *line)
} }
/* retrieve the reference system */ /* 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) { 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; goto error;
} }
/* retrieve the reference url */ /* 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) { 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; goto error;
} }

@ -87,104 +87,108 @@ static FILE *g_ut_threshold_fp = NULL;
#define THRESHOLD_CONF_DEF_CONF_FILEPATH CONFIG_DIR "/threshold.config" #define THRESHOLD_CONF_DEF_CONF_FILEPATH CONFIG_DIR "/threshold.config"
#endif #endif
static pcre *regex_base = NULL; static pcre2_code *regex_base = NULL;
static pcre_extra *regex_base_study = NULL; static pcre2_match_data *regex_base_match = NULL;
static pcre *regex_threshold = NULL; static pcre2_code *regex_threshold = NULL;
static pcre_extra *regex_threshold_study = NULL; static pcre2_match_data *regex_threshold_match = NULL;
static pcre *regex_rate = NULL; static pcre2_code *regex_rate = NULL;
static pcre_extra *regex_rate_study = NULL; static pcre2_match_data *regex_rate_match = NULL;
static pcre *regex_suppress = NULL; static pcre2_code *regex_suppress = NULL;
static pcre_extra *regex_suppress_study = NULL; static pcre2_match_data *regex_suppress_match = NULL;
static void SCThresholdConfDeInitContext(DetectEngineCtx *de_ctx, FILE *fd); static void SCThresholdConfDeInitContext(DetectEngineCtx *de_ctx, FILE *fd);
void SCThresholdConfGlobalInit(void) void SCThresholdConfGlobalInit(void)
{ {
const char *eb = NULL; int en;
int eo; PCRE2_SIZE eo;
int opts = 0; 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) { 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); regex_threshold = pcre2_compile(
if (eb != NULL) { (PCRE2_SPTR8)DETECT_THRESHOLD_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
FatalError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
}
regex_threshold = pcre_compile(DETECT_THRESHOLD_REGEX, opts, &eb, &eo, NULL);
if (regex_threshold == 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); regex_rate = pcre2_compile(
if (eb != NULL) { (PCRE2_SPTR8)DETECT_RATE_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
FatalError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
}
regex_rate = pcre_compile(DETECT_RATE_REGEX, opts, &eb, &eo, NULL);
if (regex_rate == NULL) { if (regex_rate == NULL) {
FatalError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",DETECT_RATE_REGEX, eo, eb); pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
} FatalError(SC_ERR_PCRE_COMPILE,
"pcre2 compile of \"%s\" failed at "
regex_rate_study = pcre_study(regex_rate, 0, &eb); "offset %d: %s",
if (eb != NULL) { DETECT_RATE_REGEX, (int)eo, errbuffer);
FatalError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
} }
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) { if (regex_suppress == NULL) {
FatalError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",DETECT_SUPPRESS_REGEX, eo, eb); pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
} FatalError(SC_ERR_PCRE_COMPILE,
"pcre2 compile of \"%s\" failed at "
regex_suppress_study = pcre_study(regex_suppress, 0, &eb); "offset %d: %s",
if (eb != NULL) { DETECT_SUPPRESS_REGEX, (int)eo, errbuffer);
FatalError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
} }
regex_suppress_match = pcre2_match_data_create_from_pattern(regex_suppress, NULL);
} }
void SCThresholdConfGlobalFree(void) void SCThresholdConfGlobalFree(void)
{ {
if (regex_base != NULL) { if (regex_base != NULL) {
pcre_free(regex_base); pcre2_code_free(regex_base);
regex_base = NULL; regex_base = NULL;
} }
if (regex_base_study != NULL) { if (regex_base_match != NULL) {
pcre_free(regex_base_study); pcre2_match_data_free(regex_base_match);
regex_base_study = NULL; regex_base_match = NULL;
} }
if (regex_threshold != NULL) { if (regex_threshold != NULL) {
pcre_free(regex_threshold); pcre2_code_free(regex_threshold);
regex_threshold = NULL; regex_threshold = NULL;
} }
if (regex_threshold_study != NULL) { if (regex_threshold_match != NULL) {
pcre_free(regex_threshold_study); pcre2_match_data_free(regex_threshold_match);
regex_threshold_study = NULL; regex_threshold_match = NULL;
} }
if (regex_rate != NULL) { if (regex_rate != NULL) {
pcre_free(regex_rate); pcre2_code_free(regex_rate);
regex_rate = NULL; regex_rate = NULL;
} }
if (regex_rate_study != NULL) { if (regex_rate_match != NULL) {
pcre_free(regex_rate_study); pcre2_match_data_free(regex_rate_match);
regex_rate_study = NULL; regex_rate_match = NULL;
} }
if (regex_suppress != NULL) { if (regex_suppress != NULL) {
pcre_free(regex_suppress); pcre2_code_free(regex_suppress);
regex_suppress = NULL; regex_suppress = NULL;
} }
if (regex_suppress_study != NULL) { if (regex_suppress_match != NULL) {
pcre_free(regex_suppress_study); pcre2_match_data_free(regex_suppress_match);
regex_suppress_study = NULL; regex_suppress_match = NULL;
} }
} }
@ -648,43 +652,49 @@ static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr,
uint32_t parsed_timeout = 0; uint32_t parsed_timeout = 0;
int ret = 0; int ret = 0;
int ov[MAX_SUBSTRINGS];
uint32_t id = 0, gid = 0; uint32_t id = 0, gid = 0;
ThresholdRuleType rule_type; ThresholdRuleType rule_type;
if (de_ctx == NULL) if (de_ctx == NULL)
return -1; 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) { 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; goto error;
} }
/* retrieve the classtype name */ /* 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) { 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; goto error;
} }
/* retrieve the classtype name */ /* 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) { 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; 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) { 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; goto error;
} }
/* Use "get" for heap allocation */ /* 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) { 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; goto error;
} }
@ -707,37 +717,44 @@ static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr,
case THRESHOLD_TYPE_EVENT_FILTER: case THRESHOLD_TYPE_EVENT_FILTER:
case THRESHOLD_TYPE_THRESHOLD: case THRESHOLD_TYPE_THRESHOLD:
if (strlen(rule_extend) > 0) { if (strlen(rule_extend) > 0) {
ret = pcre_exec(regex_threshold, regex_threshold_study, ret = pcre2_match(regex_threshold, (PCRE2_SPTR8)rule_extend, strlen(rule_extend), 0,
rule_extend, strlen(rule_extend), 0, regex_threshold_match, NULL);
0, 0, ov, MAX_SUBSTRINGS);
if (ret < 4) { if (ret < 4) {
SCLogError(SC_ERR_PCRE_MATCH, SCLogError(SC_ERR_PCRE_MATCH,
"pcre_exec parse error, ret %" PRId32 ", string %s", "pcre2_match parse error, ret %" PRId32 ", string %s", ret,
ret, rule_extend); rule_extend);
goto error; 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) { 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; 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) { 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; 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) { 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; 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) { 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; goto error;
} }
@ -758,25 +775,27 @@ static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr,
break; break;
case THRESHOLD_TYPE_SUPPRESS: case THRESHOLD_TYPE_SUPPRESS:
if (strlen(rule_extend) > 0) { if (strlen(rule_extend) > 0) {
ret = pcre_exec(regex_suppress, regex_suppress_study, ret = pcre2_match(regex_suppress, (PCRE2_SPTR8)rule_extend, strlen(rule_extend), 0,
rule_extend, strlen(rule_extend), 0, regex_suppress_match, NULL);
0, 0, ov, MAX_SUBSTRINGS);
if (ret < 2) { if (ret < 2) {
SCLogError(SC_ERR_PCRE_MATCH, SCLogError(SC_ERR_PCRE_MATCH,
"pcre_exec parse error, ret %" PRId32 ", string %s", "pcre2_match parse error, ret %" PRId32 ", string %s", ret,
ret, rule_extend); rule_extend);
goto error; goto error;
} }
/* retrieve the track mode */ /* 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) { 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; goto error;
} }
/* retrieve the IP; use "get" for heap allocation */ /* 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) { 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; goto error;
} }
} else { } else {
@ -786,43 +805,52 @@ static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr,
break; break;
case THRESHOLD_TYPE_RATE: case THRESHOLD_TYPE_RATE:
if (strlen(rule_extend) > 0) { if (strlen(rule_extend) > 0) {
ret = pcre_exec(regex_rate, regex_rate_study, ret = pcre2_match(regex_rate, (PCRE2_SPTR8)rule_extend, strlen(rule_extend), 0, 0,
rule_extend, strlen(rule_extend), regex_rate_match, NULL);
0, 0, ov, MAX_SUBSTRINGS);
if (ret < 5) { if (ret < 5) {
SCLogError(SC_ERR_PCRE_MATCH, SCLogError(SC_ERR_PCRE_MATCH,
"pcre_exec parse error, ret %" PRId32 ", string %s", "pcre2_match parse error, ret %" PRId32 ", string %s", ret,
ret, rule_extend); rule_extend);
goto error; 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) { 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; 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) { 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; 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) { 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; 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) { 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; 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) { 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; goto error;
} }
@ -926,18 +954,16 @@ static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr,
*ret_th_ip = NULL; *ret_th_ip = NULL;
if (th_ip != NULL) { if (th_ip != NULL) {
*ret_th_ip = (char *)th_ip; *ret_th_ip = (char *)th_ip;
} else {
SCFree((char *)th_ip);
} }
SCFree((char *)rule_extend); pcre2_substring_free((PCRE2_UCHAR8 *)rule_extend);
return 0; return 0;
error: error:
if (rule_extend != NULL) { if (rule_extend != NULL) {
SCFree((char *)rule_extend); pcre2_substring_free((PCRE2_UCHAR8 *)rule_extend);
} }
if (th_ip != NULL) { if (th_ip != NULL) {
SCFree((char *)th_ip); pcre2_substring_free((PCRE2_UCHAR8 *)th_ip);
} }
return -1; return -1;
} }
@ -983,11 +1009,11 @@ static int SCThresholdConfAddThresholdtype(char *rawstr, DetectEngineCtx *de_ctx
goto error; goto error;
} }
SCFree(th_ip); pcre2_substring_free((PCRE2_UCHAR8 *)th_ip);
return 0; return 0;
error: error:
if (th_ip != NULL) if (th_ip != NULL)
SCFree(th_ip); pcre2_substring_free((PCRE2_UCHAR8 *)th_ip);
return -1; return -1;
} }

@ -38,14 +38,15 @@
#include "util-debug.h" #include "util-debug.h"
#include "util-time.h" #include "util-time.h"
#include "conf.h" #include "conf.h"
#include <pcre2.h>
#include "stream-tcp.h" #include "stream-tcp.h"
#include "stream-tcp-reassemble.h" #include "stream-tcp-reassemble.h"
#ifdef UNITTESTS #ifdef UNITTESTS
static pcre *parse_regex; static pcre2_code *parse_regex;
static pcre_extra *parse_regex_study; static pcre2_match_data *parse_regex_match;
static UtTest *ut_list; static UtTest *ut_list;
@ -124,26 +125,26 @@ void UtRegisterTest(const char *name, int(*TestFn)(void))
*/ */
static int UtRegex (const char *regex_arg) static int UtRegex (const char *regex_arg)
{ {
const char *eb; int en;
int eo; PCRE2_SIZE eo;
int opts = PCRE_CASELESS;; int opts = PCRE2_CASELESS;
if(regex_arg == NULL) if(regex_arg == NULL)
return -1; 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) if(parse_regex == NULL)
{ {
printf("pcre compile of \"%s\" failed at offset %" PRId32 ": %s\n", regex_arg, eo, eb); PCRE2_UCHAR errbuffer[256];
goto error; pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
} SCLogError(SC_ERR_PCRE_COMPILE,
"pcre2 compile of \"%s\" failed at "
parse_regex_study = pcre_study(parse_regex, 0, &eb); "offset %d: %s",
if(eb != NULL) regex_arg, (int)eo, errbuffer);
{
printf("pcre study failed: %s\n", eb);
goto error; goto error;
} }
parse_regex_match = pcre2_match_data_create_from_pattern(parse_regex, NULL);
return 1; return 1;
@ -151,8 +152,6 @@ error:
return -1; return -1;
} }
#define MAX_SUBSTRINGS 30
/** \brief List all registered unit tests. /** \brief List all registered unit tests.
* *
* \param regex_arg Regular expression to limit listed tests. * \param regex_arg Regular expression to limit listed tests.
@ -161,14 +160,13 @@ void UtListTests(const char *regex_arg)
{ {
UtTest *ut; UtTest *ut;
int ret = 0, rcomp = 0; int ret = 0, rcomp = 0;
int ov[MAX_SUBSTRINGS];
rcomp = UtRegex(regex_arg); rcomp = UtRegex(regex_arg);
for (ut = ut_list; ut != NULL; ut = ut->next) { for (ut = ut_list; ut != NULL; ut = ut->next) {
if (rcomp == 1) { if (rcomp == 1) {
ret = pcre_exec(parse_regex, parse_regex_study, ut->name, ret = pcre2_match(parse_regex, (PCRE2_SPTR8)ut->name, strlen(ut->name), 0, 0,
strlen(ut->name), 0, 0, ov, MAX_SUBSTRINGS); parse_regex_match, NULL);
if (ret >= 1) { if (ret >= 1) {
printf("%s\n", ut->name); printf("%s\n", ut->name);
} }
@ -177,6 +175,8 @@ void UtListTests(const char *regex_arg)
printf("%s\n", ut->name); printf("%s\n", ut->name);
} }
} }
pcre2_code_free(parse_regex);
pcre2_match_data_free(parse_regex_match);
} }
/** \brief Run all registered unittests. /** \brief Run all registered unittests.
@ -192,7 +192,6 @@ uint32_t UtRunTests(const char *regex_arg)
UtTest *ut; UtTest *ut;
uint32_t good = 0, bad = 0, matchcnt = 0; uint32_t good = 0, bad = 0, matchcnt = 0;
int ret = 0, rcomp = 0; int ret = 0, rcomp = 0;
int ov[MAX_SUBSTRINGS];
StreamTcpInitMemuse(); StreamTcpInitMemuse();
StreamTcpReassembleInitMemuse(); StreamTcpReassembleInitMemuse();
@ -201,7 +200,8 @@ uint32_t UtRunTests(const char *regex_arg)
if(rcomp == 1){ if(rcomp == 1){
for (ut = ut_list; ut != NULL; ut = ut->next) { 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 ) { if( ret >= 1 ) {
printf("Test %-60.60s : ", ut->name); printf("Test %-60.60s : ", ut->name);
matchcnt++; matchcnt++;
@ -251,6 +251,8 @@ uint32_t UtRunTests(const char *regex_arg)
} else { } else {
SCLogInfo("UtRunTests: pcre compilation failed"); SCLogInfo("UtRunTests: pcre compilation failed");
} }
pcre2_code_free(parse_regex);
pcre2_match_data_free(parse_regex_match);
return bad; return bad;
} }
/** /**

Loading…
Cancel
Save