#include "util-unittest.h"
#include "util-debug.h"
-#define PARSE_REGEX "([a-z]+)(?:,(.*))?"
+#define PARSE_REGEX "([a-z]+)(?:,\\s*([^\\s]*))?"
static pcre *parse_regex;
static pcre_extra *parse_regex_study;
return 0;
}
-int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr)
+static int DetectFlowbitParse(char *str, char *cmd, int cmd_len, char *name,
+ int name_len)
{
- DetectFlowbitsData *cd = NULL;
- SigMatch *sm = NULL;
- uint8_t fb_cmd = 0;
-#define MAX_SUBSTRINGS 30
- int ret = 0, res = 0;
- int ov[MAX_SUBSTRINGS];
- char fb_cmd_str[16] = "", fb_name[256] = "";
-
- ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
- if (ret != 2 && ret != 3) {
- SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for flowbits.", rawstr);
- return -1;
+ const int max_substrings = 30;
+ int count, rc;
+ int ov[max_substrings];
+
+ count = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0,
+ ov, max_substrings);
+ if (count != 2 && count != 3) {
+ SCLogError(SC_ERR_PCRE_MATCH,
+ "\"%s\" is not a valid setting for flowbits.", str);
+ return 0;
}
- res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, fb_cmd_str, sizeof(fb_cmd_str));
- if (res < 0) {
+ rc = pcre_copy_substring((char *)str, ov, max_substrings, 1, cmd, cmd_len);
+ if (rc < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
- return -1;
+ return 0;
}
- if (ret == 3) {
- res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, fb_name, sizeof(fb_name));
- if (res < 0) {
+ if (count == 3) {
+ rc = pcre_copy_substring((char *)str, ov, max_substrings, 2, name,
+ name_len);
+ if (rc < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
- goto error;
+ return 0;
}
}
+ return 1;
+}
+
+int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr)
+{
+ DetectFlowbitsData *cd = NULL;
+ SigMatch *sm = NULL;
+ uint8_t fb_cmd = 0;
+ char fb_cmd_str[16] = "", fb_name[256] = "";
+
+ if (!DetectFlowbitParse(rawstr, fb_cmd_str, sizeof(fb_cmd_str), fb_name,
+ sizeof(fb_name))) {
+ return -1;
+ }
+
if (strcmp(fb_cmd_str,"noalert") == 0) {
fb_cmd = DETECT_FLOWBITS_CMD_NOALERT;
} else if (strcmp(fb_cmd_str,"isset") == 0) {
}
#ifdef UNITTESTS
+
+static int FlowBitsTestParse01(void)
+{
+ int ret = 0;
+ char command[16] = "", name[16] = "";
+
+ /* Single argument version. */
+ if (!DetectFlowbitParse("noalert", command, sizeof(command), name,
+ sizeof(name))) {
+ goto end;
+ }
+ if (strcmp(command, "noalert") != 0) {
+ goto end;
+ }
+
+ /* No leading or trailing spaces. */
+ if (!DetectFlowbitParse("set,flowbit", command, sizeof(command), name,
+ sizeof(name))) {
+ goto end;
+ }
+ if (strcmp(command, "set") != 0) {
+ goto end;
+ }
+ if (strcmp(name, "flowbit") != 0) {
+ goto end;
+ }
+
+ /* Leading space. */
+ if (!DetectFlowbitParse("set, flowbit", command, sizeof(command), name,
+ sizeof(name))) {
+ goto end;
+ }
+ if (strcmp(command, "set") != 0) {
+ goto end;
+ }
+ if (strcmp(name, "flowbit") != 0) {
+ goto end;
+ }
+
+ /* Trailing space. */
+ if (!DetectFlowbitParse("set,flowbit ", command, sizeof(command), name,
+ sizeof(name))) {
+ goto end;
+ }
+ if (strcmp(command, "set") != 0) {
+ goto end;
+ }
+ if (strcmp(name, "flowbit") != 0) {
+ goto end;
+ }
+
+ /* Leading and trailing space. */
+ if (!DetectFlowbitParse("set, flowbit ", command, sizeof(command), name,
+ sizeof(name))) {
+ goto end;
+ }
+ if (strcmp(command, "set") != 0) {
+ goto end;
+ }
+ if (strcmp(name, "flowbit") != 0) {
+ goto end;
+ }
+
+ ret = 1;
+end:
+ return ret;
+}
+
/**
* \test FlowBitsTestSig01 is a test for a valid noalert flowbits option
*
void FlowBitsRegisterTests(void)
{
#ifdef UNITTESTS
+ UtRegisterTest("FlowBitsTestParse01", FlowBitsTestParse01, 1);
UtRegisterTest("FlowBitsTestSig01", FlowBitsTestSig01, 0);
UtRegisterTest("FlowBitsTestSig02", FlowBitsTestSig02, 0);
UtRegisterTest("FlowBitsTestSig03", FlowBitsTestSig03, 0);