Coverage Report

Created: 2026-09-06 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata8/src/util-spm-bs.c
Line
Count
Source
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
 * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com>
23
 *
24
 * bs is a bruteforce search. It will try to search the pattern
25
 * from all characters until the available text len is less
26
 * than the length of the pattern. It needs no context but it
27
 * time cost is not good.
28
 */
29
30
#include "suricata-common.h"
31
#include "suricata.h"
32
33
#include "util-debug.h"
34
#include "util-spm-bs.h"
35
36
/**
37
 * \brief Basic search improved. Limits are better handled, so
38
 * it doesn't start searches that wont fit in the remaining buffer
39
 *
40
 * \param haystack pointer to the buffer to search in
41
 * \param haystack_len length limit of the buffer
42
 * \param needle pointer to the pattern we ar searching for
43
 * \param needle_len length limit of the needle
44
 *
45
 * \retval ptr to start of the match; NULL if no match
46
 */
47
uint8_t *BasicSearch(const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint16_t needle_len)
48
17.1k
{
49
17.1k
    SCEnter();
50
51
17.1k
    const uint8_t *h, *n;
52
17.1k
    const uint8_t *hmax = haystack + haystack_len;
53
17.1k
    const uint8_t *nmax = needle + needle_len;
54
55
17.1k
    if (needle_len == 0 || needle_len > haystack_len) {
56
671
        SCReturnPtr(NULL, "uint8_t");
57
671
    }
58
59
    //PrintRawDataFp(stdout,needle,needle_len);
60
61
    //PrintRawDataFp(stdout,haystack,haystack_len);
62
63
13.5M
    for (n = needle; nmax - n <= hmax - haystack; haystack++) {
64
13.5M
        if (*haystack != *n) {
65
13.3M
            continue;
66
13.3M
        }
67
68
174k
        SCLogDebug("*haystack == *n, %c == %c", *haystack, *n);
69
70
        /* one byte needles */
71
174k
        if (needle_len == 1) {
72
0
            SCReturnPtr((uint8_t *)haystack, "uint8_t");
73
0
        }
74
75
176k
        for (h = haystack+1, n++; nmax - n <= hmax - haystack; h++, n++) {
76
176k
            if (*h != *n) {
77
174k
                break;
78
174k
            }
79
1.20k
            SCLogDebug("*haystack == *n, %c == %c", *haystack, *n);
80
            /* if we run out of needle we fully matched */
81
1.20k
            if (n == nmax - 1) {
82
25
                SCReturnPtr((uint8_t *)haystack, "uint8_t");
83
25
            }
84
1.20k
        }
85
174k
        n = needle;
86
174k
    }
87
88
16.5k
    SCReturnPtr(NULL, "uint8_t");
89
16.5k
}
90
91
/**
92
 * \brief Basic search case less
93
 *
94
 * \param haystack pointer to the buffer to search in
95
 * \param haystack_len length limit of the buffer
96
 * \param needle pointer to the pattern we ar searching for
97
 * \param needle_len length limit of the needle
98
 *
99
 * \retval ptr to start of the match; NULL if no match
100
 */
101
uint8_t *BasicSearchNocase(const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint16_t needle_len)
102
0
{
103
0
    const uint8_t *h, *n;
104
0
    const uint8_t *hmax = haystack + haystack_len;
105
0
    const uint8_t *nmax = needle + needle_len;
106
107
0
    if (needle_len == 0 || needle_len > haystack_len)
108
0
        return NULL;
109
110
0
    for (n = needle; nmax - n <= hmax - haystack; haystack++) {
111
0
        if (u8_tolower(*haystack) != u8_tolower(*n)) {
112
0
            continue;
113
0
        }
114
        /* one byte needles */
115
0
        if (needle_len == 1) {
116
0
            return (uint8_t *)haystack;
117
0
        }
118
119
0
        for (h = haystack+1, n++; nmax - n <= hmax - h ; h++, n++) {
120
0
            if (u8_tolower(*h) != u8_tolower(*n)) {
121
0
                break;
122
0
            }
123
            /* if we run out of needle we fully matched */
124
0
            if (n == nmax - 1) {
125
0
                return (uint8_t *)haystack;
126
0
            }
127
0
        }
128
0
        n = needle;
129
0
    }
130
131
0
    return NULL;
132
0
}
133
134
uint32_t BasicSearchNocaseIndex(
135
        const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint16_t needle_len)
136
0
{
137
0
    uint8_t *r = BasicSearchNocase(haystack, haystack_len, needle, needle_len);
138
0
    if (r == NULL) {
139
0
        return haystack_len;
140
0
    }
141
0
    return (uint32_t)(r - haystack);
142
0
}