|
|
|
@ -350,6 +350,7 @@ static DetectPcreData *DetectPcreParse (DetectEngineCtx *de_ctx,
|
|
|
|
const char *regexstr, int *sm_list, char *capture_names,
|
|
|
|
const char *regexstr, int *sm_list, char *capture_names,
|
|
|
|
size_t capture_names_size, bool negate, AppProto *alproto)
|
|
|
|
size_t capture_names_size, bool negate, AppProto *alproto)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
pcre2_match_data *match = NULL;
|
|
|
|
int en;
|
|
|
|
int en;
|
|
|
|
PCRE2_SIZE eo2;
|
|
|
|
PCRE2_SIZE eo2;
|
|
|
|
int opts = 0;
|
|
|
|
int opts = 0;
|
|
|
|
@ -403,25 +404,31 @@ static DetectPcreData *DetectPcreParse (DetectEngineCtx *de_ctx,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char re[slen];
|
|
|
|
char re[slen];
|
|
|
|
ret = pcre2_match(
|
|
|
|
|
|
|
|
parse_regex->regex, (PCRE2_SPTR8)regexstr, slen, 0, 0, parse_regex->match, NULL);
|
|
|
|
match = pcre2_match_data_create_from_pattern(parse_regex->regex, NULL);
|
|
|
|
|
|
|
|
if (!match) {
|
|
|
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ret = pcre2_match(parse_regex->regex, (PCRE2_SPTR8)regexstr, slen, 0, 0, match, NULL);
|
|
|
|
if (ret <= 0) {
|
|
|
|
if (ret <= 0) {
|
|
|
|
SCLogError("pcre parse error: %s", regexstr);
|
|
|
|
SCLogError("pcre parse error: %s", regexstr);
|
|
|
|
goto error;
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
res = pcre2_substring_copy_bynumber(parse_regex->match, 1, (PCRE2_UCHAR8 *)re, &slen);
|
|
|
|
res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)re, &slen);
|
|
|
|
if (res < 0) {
|
|
|
|
if (res < 0) {
|
|
|
|
SCLogError("pcre2_substring_copy_bynumber failed");
|
|
|
|
SCLogError("pcre2_substring_copy_bynumber failed");
|
|
|
|
|
|
|
|
pcre2_match_data_free(match);
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ret > 2) {
|
|
|
|
if (ret > 2) {
|
|
|
|
size_t copylen = sizeof(op_str);
|
|
|
|
size_t copylen = sizeof(op_str);
|
|
|
|
res = pcre2_substring_copy_bynumber(
|
|
|
|
res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)op_str, ©len);
|
|
|
|
parse_regex->match, 2, (PCRE2_UCHAR8 *)op_str, ©len);
|
|
|
|
|
|
|
|
if (res < 0) {
|
|
|
|
if (res < 0) {
|
|
|
|
SCLogError("pcre2_substring_copy_bynumber failed");
|
|
|
|
SCLogError("pcre2_substring_copy_bynumber failed");
|
|
|
|
|
|
|
|
pcre2_match_data_free(match);
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
op = op_str;
|
|
|
|
op = op_str;
|
|
|
|
@ -683,9 +690,12 @@ static DetectPcreData *DetectPcreParse (DetectEngineCtx *de_ctx,
|
|
|
|
pcre2_set_match_limit(pd->parse_regex.context, SC_MATCH_LIMIT_DEFAULT);
|
|
|
|
pcre2_set_match_limit(pd->parse_regex.context, SC_MATCH_LIMIT_DEFAULT);
|
|
|
|
pcre2_set_recursion_limit(pd->parse_regex.context, SC_MATCH_LIMIT_RECURSION_DEFAULT);
|
|
|
|
pcre2_set_recursion_limit(pd->parse_regex.context, SC_MATCH_LIMIT_RECURSION_DEFAULT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pcre2_match_data_free(match);
|
|
|
|
return pd;
|
|
|
|
return pd;
|
|
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
error:
|
|
|
|
|
|
|
|
pcre2_match_data_free(match);
|
|
|
|
DetectPcreFree(de_ctx, pd);
|
|
|
|
DetectPcreFree(de_ctx, pd);
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -704,6 +714,7 @@ static int DetectPcreParseCapture(const char *regexstr, DetectEngineCtx *de_ctx,
|
|
|
|
int capture_cnt = 0;
|
|
|
|
int capture_cnt = 0;
|
|
|
|
int key = 0;
|
|
|
|
int key = 0;
|
|
|
|
size_t copylen;
|
|
|
|
size_t copylen;
|
|
|
|
|
|
|
|
pcre2_match_data *match = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
SCLogDebug("regexstr %s, pd %p", regexstr, pd);
|
|
|
|
SCLogDebug("regexstr %s, pd %p", regexstr, pd);
|
|
|
|
|
|
|
|
|
|
|
|
@ -773,21 +784,19 @@ static int DetectPcreParseCapture(const char *regexstr, DetectEngineCtx *de_ctx,
|
|
|
|
while (1) {
|
|
|
|
while (1) {
|
|
|
|
SCLogDebug("\'%s\'", regexstr);
|
|
|
|
SCLogDebug("\'%s\'", regexstr);
|
|
|
|
|
|
|
|
|
|
|
|
ret = pcre2_match(parse_capture_regex->regex, (PCRE2_SPTR8)regexstr, strlen(regexstr), 0, 0,
|
|
|
|
ret = DetectParsePcreExec(parse_capture_regex, &match, regexstr, 0, 0);
|
|
|
|
parse_capture_regex->match, NULL);
|
|
|
|
|
|
|
|
if (ret < 3) {
|
|
|
|
if (ret < 3) {
|
|
|
|
|
|
|
|
pcre2_match_data_free(match);
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
copylen = sizeof(type_str);
|
|
|
|
copylen = sizeof(type_str);
|
|
|
|
res = pcre2_substring_copy_bynumber(
|
|
|
|
res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)type_str, ©len);
|
|
|
|
parse_capture_regex->match, 1, (PCRE2_UCHAR8 *)type_str, ©len);
|
|
|
|
|
|
|
|
if (res != 0) {
|
|
|
|
if (res != 0) {
|
|
|
|
SCLogError("pcre2_substring_copy_bynumber failed");
|
|
|
|
SCLogError("pcre2_substring_copy_bynumber failed");
|
|
|
|
goto error;
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cap_buffer_len = strlen(regexstr) + 1;
|
|
|
|
cap_buffer_len = strlen(regexstr) + 1;
|
|
|
|
res = pcre2_substring_copy_bynumber(
|
|
|
|
res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)capture_str, &cap_buffer_len);
|
|
|
|
parse_capture_regex->match, 2, (PCRE2_UCHAR8 *)capture_str, &cap_buffer_len);
|
|
|
|
|
|
|
|
if (res != 0) {
|
|
|
|
if (res != 0) {
|
|
|
|
SCLogError("pcre2_substring_copy_bynumber failed");
|
|
|
|
SCLogError("pcre2_substring_copy_bynumber failed");
|
|
|
|
goto error;
|
|
|
|
goto error;
|
|
|
|
@ -803,6 +812,7 @@ static int DetectPcreParseCapture(const char *regexstr, DetectEngineCtx *de_ctx,
|
|
|
|
SCLogError("rule can have maximally %d pkt/flow "
|
|
|
|
SCLogError("rule can have maximally %d pkt/flow "
|
|
|
|
"var captures",
|
|
|
|
"var captures",
|
|
|
|
DETECT_PCRE_CAPTURE_MAX);
|
|
|
|
DETECT_PCRE_CAPTURE_MAX);
|
|
|
|
|
|
|
|
pcre2_match_data_free(match);
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -818,15 +828,19 @@ static int DetectPcreParseCapture(const char *regexstr, DetectEngineCtx *de_ctx,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//SCLogNotice("pd->capname %s", pd->capname);
|
|
|
|
//SCLogNotice("pd->capname %s", pd->capname);
|
|
|
|
PCRE2_SIZE *ov = pcre2_get_ovector_pointer(parse_capture_regex->match);
|
|
|
|
PCRE2_SIZE *ov = pcre2_get_ovector_pointer(match);
|
|
|
|
regexstr += ov[1];
|
|
|
|
regexstr += ov[1];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pcre2_match_data_free(match);
|
|
|
|
|
|
|
|
match = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (regexstr >= orig_right_edge)
|
|
|
|
if (regexstr >= orig_right_edge)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
error:
|
|
|
|
|
|
|
|
pcre2_match_data_free(match);
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|