Coverage Report

Created: 2026-01-16 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/util-buffer.c
Line
Count
Source
1
/* Copyright (C) 2007-2023 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 Anoop Saldanha <anoopsaldanha@gmail.com>
22
 */
23
24
#include "suricata-common.h"
25
#include "suricata.h"
26
#include "util-debug.h"
27
#include "util-buffer.h"
28
29
/* 10 mb */
30
197
#define MAX_LIMIT 10485760
31
32
MemBuffer *MemBufferCreateNew(uint32_t size)
33
130
{
34
130
    sc_errno = SC_OK;
35
130
    if (size > MAX_LIMIT) {
36
0
        SCLogWarning("Mem buffer asked to create "
37
0
                     "buffer with size greater than API limit - %d",
38
0
                MAX_LIMIT);
39
0
        sc_errno = SC_EINVAL;
40
0
        return NULL;
41
0
    }
42
43
130
    size_t total_size = size + sizeof(MemBuffer);
44
45
130
    MemBuffer *buffer = SCCalloc(1, total_size);
46
130
    if (unlikely(buffer == NULL)) {
47
0
        sc_errno = SC_ENOMEM;
48
0
        return NULL;
49
0
    }
50
130
    buffer->size = size;
51
130
    return buffer;
52
130
}
53
54
/** \brief expand membuffer by size of 'expand_by'
55
 *
56
 *  If expansion failed, buffer will still be valid.
57
 *
58
 *  \retval result 0 ok, -1 expansion failed
59
 */
60
67
int MemBufferExpand(MemBuffer **buffer, uint32_t expand_by) {
61
67
    if (((*buffer)->size + expand_by) > MAX_LIMIT) {
62
0
        SCLogWarning("Mem buffer asked to create "
63
0
                     "buffer with size greater than API limit - %d",
64
0
                MAX_LIMIT);
65
0
        return -1;
66
0
    }
67
68
    /* Adjust expand_by to next multiple of 4k. */
69
67
    if (expand_by % 4096 != 0) {
70
66
        expand_by = expand_by - (expand_by % 4096) + 4096;
71
66
    }
72
73
67
    size_t total_size = (*buffer)->size + sizeof(MemBuffer) + expand_by;
74
75
67
    MemBuffer *tbuffer = SCRealloc(*buffer, total_size);
76
67
    if (unlikely(tbuffer == NULL)) {
77
0
        return -1;
78
0
    }
79
67
    *buffer = tbuffer;
80
67
    (*buffer)->size += expand_by;
81
82
67
    SCLogDebug("expanded buffer by %u, size is now %u", expand_by, (*buffer)->size);
83
67
    return 0;
84
67
}
85
86
void MemBufferFree(MemBuffer *buffer)
87
0
{
88
0
    SCFree(buffer);
89
90
0
    return;
91
0
}
92
93
void MemBufferPrintToFP(MemBuffer *buffer, FILE *fp)
94
0
{
95
0
    for (uint32_t i = 0; i < buffer->offset; i++) {
96
0
        if (isprint(buffer->buffer[i]))
97
0
            fprintf(fp, "%c", buffer->buffer[i]);
98
0
        else
99
0
            fprintf(fp, "|%02X|", buffer->buffer[i]);
100
0
    }
101
0
}
102
103
size_t MemBufferPrintToFPAsString(MemBuffer *b, FILE *fp)
104
0
{
105
0
    return fwrite(MEMBUFFER_BUFFER(b), sizeof(uint8_t), MEMBUFFER_OFFSET(b), fp);
106
0
}
107
108
void MemBufferPrintToFPAsHex(MemBuffer *b, FILE *fp)
109
0
{
110
0
    for (uint32_t i = 0; i < MEMBUFFER_OFFSET(b); i++) {
111
0
        if (MEMBUFFER_OFFSET(b) % 8 == 0)
112
0
            fprintf(fp, "\n");
113
0
        fprintf(fp, " %02X", b->buffer[i]);
114
0
    }
115
0
}
116
117
uint32_t MemBufferWriteRaw(MemBuffer *dst, const uint8_t *raw, const uint32_t raw_len)
118
12.8M
{
119
12.8M
    uint32_t write_len;
120
12.8M
    if (raw_len >= dst->size - dst->offset) {
121
115k
        SCLogDebug("Truncating data write since it exceeded buffer limit of %" PRIu32, dst->size);
122
115k
        write_len = dst->size - dst->offset - 1;
123
12.7M
    } else {
124
12.7M
        write_len = raw_len;
125
12.7M
    }
126
12.8M
    memcpy(dst->buffer + dst->offset, raw, write_len);
127
12.8M
    dst->offset += write_len;
128
12.8M
    dst->buffer[dst->offset] = '\0';
129
12.8M
    return write_len;
130
12.8M
}
131
132
void MemBufferWriteString(MemBuffer *dst, const char *fmt, ...)
133
15.1M
{
134
15.1M
    uint32_t available = dst->size - dst->offset;
135
15.1M
    uint32_t max_string_size = MIN(available, 2048);
136
15.1M
    va_list ap;
137
15.1M
    char string[max_string_size];
138
15.1M
    va_start(ap, fmt);
139
15.1M
    int written = vsnprintf(string, sizeof(string), fmt, ap);
140
15.1M
    va_end(ap);
141
15.1M
    if (written < 0) {
142
0
        return;
143
15.1M
    } else if ((uint32_t)written > max_string_size) {
144
509
        SCLogDebug("Truncating data write since it exceeded buffer "
145
509
                   "limit of %" PRIu32,
146
509
                dst->size);
147
509
    }
148
15.1M
    size_t string_size = strlen(string);
149
15.1M
    memcpy(dst->buffer + dst->offset, string, string_size);
150
15.1M
    dst->offset += string_size;
151
15.1M
    dst->buffer[dst->offset] = '\0';
152
15.1M
}