Coverage Report

Created: 2026-06-30 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/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
185k
{
49
185k
    SCEnter();
50
51
185k
    const uint8_t *h, *n;
52
185k
    const uint8_t *hmax = haystack + haystack_len;
53
185k
    const uint8_t *nmax = needle + needle_len;
54
55
185k
    if (needle_len == 0 || needle_len > haystack_len) {
56
10.6k
        SCReturnPtr(NULL, "uint8_t");
57
10.6k
    }
58
59
    //PrintRawDataFp(stdout,needle,needle_len);
60
61
    //PrintRawDataFp(stdout,haystack,haystack_len);
62
63
26.3M
    for (n = needle; nmax - n <= hmax - haystack; haystack++) {
64
26.2M
        if (*haystack != *n) {
65
25.9M
            continue;
66
25.9M
        }
67
68
209k
        SCLogDebug("*haystack == *n, %c == %c", *haystack, *n);
69
70
        /* one byte needles */
71
209k
        if (needle_len == 1) {
72
0
            SCReturnPtr((uint8_t *)haystack, "uint8_t");
73
0
        }
74
75
403k
        for (h = haystack+1, n++; nmax - n <= hmax - haystack; h++, n++) {
76
403k
            if (*h != *n) {
77
151k
                break;
78
151k
            }
79
252k
            SCLogDebug("*haystack == *n, %c == %c", *haystack, *n);
80
            /* if we run out of needle we fully matched */
81
252k
            if (n == nmax - 1) {
82
58.7k
                SCReturnPtr((uint8_t *)haystack, "uint8_t");
83
58.7k
            }
84
252k
        }
85
151k
        n = needle;
86
151k
    }
87
88
174k
    SCReturnPtr(NULL, "uint8_t");
89
174k
}
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
2.41M
{
103
2.41M
    const uint8_t *h, *n;
104
2.41M
    const uint8_t *hmax = haystack + haystack_len;
105
2.41M
    const uint8_t *nmax = needle + needle_len;
106
107
2.41M
    if (needle_len == 0 || needle_len > haystack_len)
108
1.40M
        return NULL;
109
110
4.91M
    for (n = needle; nmax - n <= hmax - haystack; haystack++) {
111
4.55M
        if (u8_tolower(*haystack) != u8_tolower(*n)) {
112
3.65M
            continue;
113
3.65M
        }
114
        /* one byte needles */
115
898k
        if (needle_len == 1) {
116
0
            return (uint8_t *)haystack;
117
0
        }
118
119
2.26M
        for (h = haystack+1, n++; nmax - n <= hmax - h ; h++, n++) {
120
2.26M
            if (u8_tolower(*h) != u8_tolower(*n)) {
121
246k
                break;
122
246k
            }
123
            /* if we run out of needle we fully matched */
124
2.01M
            if (n == nmax - 1) {
125
651k
                return (uint8_t *)haystack;
126
651k
            }
127
2.01M
        }
128
246k
        n = needle;
129
246k
    }
130
131
355k
    return NULL;
132
1.00M
}
133
134
void BasicSearchInit (void)
135
0
{
136
    /* nothing no more */
137
0
}
138