• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23352517976

20 Mar 2026 04:32PM UTC coverage: 65.866% (-13.4%) from 79.315%
23352517976

Pull #15072

github

web-flow
Merge abcd1935f into 6587e363a
Pull Request #15072: Stack 8001 v16.3

41 of 70 new or added lines in 10 files covered. (58.57%)

18894 existing lines in 577 files now uncovered.

143735 of 218225 relevant lines covered (65.87%)

4342818.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.38
/src/detect-msg.c
1
/* Copyright (C) 2007-2010 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
/**
19
 * \file
20
 *
21
 * \author Victor Julien <victor@inliniac.net>
22
 *
23
 * Implements the msg keyword
24
 */
25

26
#include "suricata-common.h"
27
#include "detect.h"
28
#include "util-classification-config.h"
29
#include "util-debug.h"
30
#include "util-unittest.h"
31

32
#include "detect-parse.h"
33
#include "detect-engine.h"
34
#include "detect-engine-mpm.h"
35
#include "detect-msg.h"
36

37
static int DetectMsgSetup (DetectEngineCtx *, Signature *, const char *);
38
#ifdef UNITTESTS
39
static void DetectMsgRegisterTests(void);
40
#endif
41

42
void DetectMsgRegister (void)
43
{
2,212✔
44
    sigmatch_table[DETECT_MSG].name = "msg";
2,212✔
45
    sigmatch_table[DETECT_MSG].desc = "information about the rule and the possible alert";
2,212✔
46
    sigmatch_table[DETECT_MSG].url = "/rules/meta.html#msg-message";
2,212✔
47
    sigmatch_table[DETECT_MSG].Match = NULL;
2,212✔
48
    sigmatch_table[DETECT_MSG].Setup = DetectMsgSetup;
2,212✔
49
    sigmatch_table[DETECT_MSG].Free = NULL;
2,212✔
50
#ifdef UNITTESTS
51
    sigmatch_table[DETECT_MSG].RegisterTests = DetectMsgRegisterTests;
52
#endif
53
    sigmatch_table[DETECT_MSG].flags = (SIGMATCH_QUOTES_MANDATORY | SIGMATCH_SUPPORT_FIREWALL);
2,212✔
54
}
2,212✔
55

56
static int DetectMsgSetup (DetectEngineCtx *de_ctx, Signature *s, const char *msgstr)
57
{
108,440✔
58
    size_t slen = strlen(msgstr);
108,440✔
59
    if (slen == 0)
108,440✔
60
        return -1;
×
61

62
    if (s->msg != NULL) {
108,440✔
UNCOV
63
        SCLogError("duplicated 'msg' keyword detected");
×
UNCOV
64
        return -1;
×
UNCOV
65
    }
×
66

67
    char *str = SCStrdup(msgstr);
108,440✔
68
    if (str == NULL)
108,440✔
69
        return -1;
×
70

71
    char converted = 0;
108,440✔
72

73
    {
108,440✔
74
        size_t i, x;
108,440✔
75
        uint8_t escape = 0;
108,440✔
76

77
        /* it doesn't matter if we need to escape or not we remove the extra "\" to mimic snort */
78
        for (i = 0, x = 0; i < slen; i++) {
3,628,780✔
79
            //printf("str[%02u]: %c\n", i, str[i]);
80
            if(!escape && str[i] == '\\') {
3,520,340✔
81
                escape = 1;
12✔
82
            } else if (escape) {
3,520,328✔
83
                if (str[i] != ':' &&
12✔
84
                        str[i] != ';' &&
12✔
85
                        str[i] != '\\' &&
12✔
86
                        str[i] != '\"')
12✔
87
                {
12✔
88
                    SCLogDebug("character \"%c\" does not need to be escaped but is" ,str[i]);
12✔
89
                }
12✔
90
                escape = 0;
12✔
91
                converted = 1;
12✔
92

93
                str[x] = str[i];
12✔
94
                x++;
12✔
95
            }else{
3,520,316✔
96
                str[x] = str[i];
3,520,316✔
97
                x++;
3,520,316✔
98
            }
3,520,316✔
99

100
        }
3,520,340✔
101
#if 0 //def DEBUG
102
        if (SCLogDebugEnabled()) {
103
            for (i = 0; i < x; i++) {
104
                printf("%c", str[i]);
105
            }
106
            printf("\n");
107
        }
108
#endif
109

110
        if (converted) {
108,440✔
111
            slen = x;
10✔
112
            str[slen] = '\0';
10✔
113
        }
10✔
114
    }
108,440✔
115

116
    s->msg = str;
108,440✔
117
    return 0;
108,440✔
118
}
108,440✔
119

120
/* -------------------------------------Unittests-----------------------------*/
121

122
#ifdef UNITTESTS
123
static int DetectMsgParseTest01(void)
124
{
125
    const char *teststringparsed = "flow stateless to_server";
126
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
127
    FAIL_IF_NULL(de_ctx);
128

129
    SCClassConfDeInitContext(de_ctx);
130
    FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01();
131
    SCClassConfLoadClassificationConfigFile(de_ctx, fd);
132

133
    Signature *sig = DetectEngineAppendSig(de_ctx,
134
            "alert tcp any any -> any any (msg:\"flow stateless to_server\"; "
135
            "flow:stateless,to_server; content:\"flowstatelesscheck\"; "
136
            "classtype:bad-unknown; sid: 40000002; rev: 1;)");
137
    FAIL_IF_NULL(sig);
138
    FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
139

140
    SCClassConfDeInitContext(de_ctx);
141
    DetectEngineCtxFree(de_ctx);
142
    PASS;
143
}
144

145
static int DetectMsgParseTest02(void)
146
{
147
    const char *teststringparsed = "msg escape tests wxy'\"\\;:";
148
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
149
    FAIL_IF_NULL(de_ctx);
150

151
    Signature *sig = DetectEngineAppendSig(de_ctx,
152
            "alert tcp any any -> any any (msg:\"msg escape tests \\w\\x\\y\\'\\\"\\\\;\\:\"; "
153
            "flow:to_server,established; content:\"blah\"; uricontent:\"/blah/\"; sid: 100;)");
154
    FAIL_IF_NULL(sig);
155

156
    FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
157

158
    DetectEngineCtxFree(de_ctx);
159

160
    PASS;
161
}
162

163
static int DetectMsgParseTest03(void)
164
{
165
    const char *teststringparsed = "flow stateless to_server";
166
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
167
    FAIL_IF_NULL(de_ctx);
168

169
    SCClassConfDeInitContext(de_ctx);
170
    FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01();
171
    SCClassConfLoadClassificationConfigFile(de_ctx, fd);
172

173
    Signature *sig = DetectEngineAppendSig(de_ctx,
174
            "alert tcp any any -> any any (msg: \"flow stateless to_server\"; "
175
            "flow:stateless,to_server; content:\"flowstatelesscheck\"; "
176
            "classtype:bad-unknown; sid: 40000002; rev: 1;)");
177
    FAIL_IF_NULL(sig);
178
    FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
179

180
    SCClassConfDeInitContext(de_ctx);
181
    DetectEngineCtxFree(de_ctx);
182
    PASS;
183
}
184

185
/**
186
 * \brief this function registers unit tests for DetectMsg
187
 */
188
void DetectMsgRegisterTests(void)
189
{
190
    UtRegisterTest("DetectMsgParseTest01", DetectMsgParseTest01);
191
    UtRegisterTest("DetectMsgParseTest02", DetectMsgParseTest02);
192
    UtRegisterTest("DetectMsgParseTest03", DetectMsgParseTest03);
193
}
194
#endif /* UNITTESTS */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc