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

OISF / suricata / 22550902417

01 Mar 2026 07:32PM UTC coverage: 68.401% (-5.3%) from 73.687%
22550902417

Pull #14922

github

web-flow
github-actions: bump actions/upload-artifact from 6.0.0 to 7.0.0

Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #14922: github-actions: bump actions/upload-artifact from 6.0.0 to 7.0.0

218243 of 319063 relevant lines covered (68.4%)

3284926.58 hits per line

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

65.33
/rust/src/detect/transforms/http_headers.rs
1
/* Copyright (C) 2024 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
use crate::detect::SIGMATCH_NOOPT;
19
use suricata_sys::sys::{
20
    DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister,
21
    SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate,
22
    SCTransformTableElmt, Signature,
23
};
24

25
use std::os::raw::{c_int, c_void};
26
use std::ptr;
27

28
static mut G_TRANSFORM_HEADER_LOWER_ID: c_int = 0;
29
static mut G_TRANSFORM_STRIP_PSEUDO_ID: c_int = 0;
30

31
unsafe extern "C" fn header_lowersetup(
×
32
    _de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
×
33
) -> c_int {
×
34
    return SCDetectSignatureAddTransform(s, G_TRANSFORM_HEADER_LOWER_ID, ptr::null_mut());
×
35
}
×
36

37
fn header_lowertransform_do(input: &[u8], output: &mut [u8]) {
1✔
38
    let mut state_value = false; // false in name, true in value
1✔
39
    for (i, o) in input.iter().zip(output.iter_mut()) {
31✔
40
        if !state_value {
31✔
41
            if (*i) == b':' {
16✔
42
                state_value = true;
2✔
43
                *o = *i;
2✔
44
            } else {
14✔
45
                *o = (*i).to_ascii_lowercase();
14✔
46
            }
14✔
47
        } else {
48
            *o = *i;
15✔
49
            if (*i) == b'\n' {
15✔
50
                state_value = false;
2✔
51
            }
13✔
52
        }
53
    }
54
}
1✔
55

56
unsafe extern "C" fn header_lowertransform(
×
57
    _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void,
×
58
) {
×
59
    let input = (*buffer).inspect;
×
60
    let input_len = (*buffer).inspect_len;
×
61
    if input.is_null() || input_len == 0 {
×
62
        return;
×
63
    }
×
64
    let input = build_slice!(input, input_len as usize);
×
65

×
66
    let output = SCInspectionBufferCheckAndExpand(buffer, input_len);
×
67
    if output.is_null() {
×
68
        // allocation failure
69
        return;
×
70
    }
×
71
    let output = std::slice::from_raw_parts_mut(output, input_len as usize);
×
72

×
73
    header_lowertransform_do(input, output);
×
74

×
75
    SCInspectionBufferTruncate(buffer, input_len);
×
76
}
×
77

78
#[no_mangle]
79
pub unsafe extern "C" fn DetectTransformHeaderLowercaseRegister() {
37✔
80
    let kw = SCTransformTableElmt {
37✔
81
        name: b"header_lowercase\0".as_ptr() as *const libc::c_char,
37✔
82
        desc: b"modify buffer via lowercaseing header names\0".as_ptr() as *const libc::c_char,
37✔
83
        url: b"/rules/transforms.html#header_lowercase\0".as_ptr() as *const libc::c_char,
37✔
84
        Setup: Some(header_lowersetup),
37✔
85
        flags: SIGMATCH_NOOPT,
37✔
86
        Transform: Some(header_lowertransform),
37✔
87
        Free: None,
37✔
88
        TransformValidate: None,
37✔
89
        TransformId: None,
37✔
90
    };
37✔
91
    G_TRANSFORM_HEADER_LOWER_ID = SCDetectHelperTransformRegister(&kw);
37✔
92
    if G_TRANSFORM_HEADER_LOWER_ID < 0 {
37✔
93
        SCLogWarning!("Failed registering transform tolower");
×
94
    }
37✔
95
}
37✔
96

97
unsafe extern "C" fn strip_pseudo_setup(
×
98
    _de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
×
99
) -> c_int {
×
100
    return SCDetectSignatureAddTransform(s, G_TRANSFORM_STRIP_PSEUDO_ID, ptr::null_mut());
×
101
}
×
102

103
fn strip_pseudo_transform_do(input: &[u8], output: &mut [u8]) -> u32 {
5✔
104
    let mut nb = 0;
5✔
105
    let mut inb = 0;
5✔
106
    let same = std::ptr::eq(output.as_ptr(), input.as_ptr());
5✔
107
    for subslice in input.split_inclusive(|c| *c == b'\n') {
179✔
108
        if !subslice.is_empty() && subslice[0] != b':' {
13✔
109
            if same {
7✔
110
                output.copy_within(inb..inb + subslice.len(), nb);
3✔
111
            } else {
4✔
112
                output[nb..nb + subslice.len()].copy_from_slice(subslice);
4✔
113
            }
4✔
114
            nb += subslice.len();
7✔
115
        }
6✔
116
        inb += subslice.len();
13✔
117
    }
118
    return nb as u32;
5✔
119
}
5✔
120

121
unsafe extern "C" fn strip_pseudo_transform(
×
122
    _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void,
×
123
) {
×
124
    let input = (*buffer).inspect;
×
125
    let input_len = (*buffer).inspect_len;
×
126
    if input.is_null() || input_len == 0 {
×
127
        return;
×
128
    }
×
129
    let input = build_slice!(input, input_len as usize);
×
130

×
131
    let output = SCInspectionBufferCheckAndExpand(buffer, input_len);
×
132
    if output.is_null() {
×
133
        // allocation failure
134
        return;
×
135
    }
×
136
    let output = std::slice::from_raw_parts_mut(output, input_len as usize);
×
137

×
138
    let out_len = strip_pseudo_transform_do(input, output);
×
139

×
140
    SCInspectionBufferTruncate(buffer, out_len);
×
141
}
×
142

143
#[no_mangle]
144
pub unsafe extern "C" fn DetectTransformStripPseudoHeadersRegister() {
37✔
145
    let kw = SCTransformTableElmt {
37✔
146
        name: b"strip_pseudo_headers\0".as_ptr() as *const libc::c_char,
37✔
147
        desc: b"modify buffer via stripping pseudo headers\0".as_ptr() as *const libc::c_char,
37✔
148
        url: b"/rules/transforms.html#strip_pseudo_headers\0".as_ptr() as *const libc::c_char,
37✔
149
        Setup: Some(strip_pseudo_setup),
37✔
150
        flags: SIGMATCH_NOOPT,
37✔
151
        Transform: Some(strip_pseudo_transform),
37✔
152
        Free: None,
37✔
153
        TransformValidate: None,
37✔
154
        TransformId: None,
37✔
155
    };
37✔
156
    G_TRANSFORM_STRIP_PSEUDO_ID = SCDetectHelperTransformRegister(&kw);
37✔
157
    if G_TRANSFORM_STRIP_PSEUDO_ID < 0 {
37✔
158
        SCLogWarning!("Failed registering transform toupper");
×
159
    }
37✔
160
}
37✔
161

162
#[cfg(test)]
163
mod tests {
164
    use super::*;
165

166
    #[test]
167
    fn test_header_lowertransform() {
1✔
168
        let buf = b"Header1: Value1\nheader2:Value2\n";
1✔
169
        let mut out = vec![0; buf.len()];
1✔
170
        header_lowertransform_do(buf, &mut out);
1✔
171
        assert_eq!(out, b"header1: Value1\nheader2:Value2\n");
1✔
172
    }
1✔
173

174
    #[test]
175
    fn test_strip_pseudo_transform() {
1✔
176
        let buf = b"Header1: Value1\n:method:get\nheader2:Value2\n";
1✔
177
        let mut out = vec![0; buf.len()];
1✔
178
        let nb = strip_pseudo_transform_do(buf, &mut out);
1✔
179
        assert_eq!(&out[..nb as usize], b"Header1: Value1\nheader2:Value2\n");
1✔
180
        let buf = b":method:get";
1✔
181
        let mut out = vec![0; buf.len()];
1✔
182
        let nb = strip_pseudo_transform_do(buf, &mut out);
1✔
183
        assert_eq!(nb, 0);
1✔
184
        let buf = b"Header1: Value1\n:method:get";
1✔
185
        let mut out = vec![0; buf.len()];
1✔
186
        let nb = strip_pseudo_transform_do(buf, &mut out);
1✔
187
        assert_eq!(&out[..nb as usize], b"Header1: Value1\n");
1✔
188
        let buf = b":method:get\nheader2:Value2";
1✔
189
        let mut out = vec![0; buf.len()];
1✔
190
        let nb = strip_pseudo_transform_do(buf, &mut out);
1✔
191
        assert_eq!(&out[..nb as usize], b"header2:Value2");
1✔
192
        let mut buf = Vec::new();
1✔
193
        buf.extend_from_slice(
1✔
194
            b"Header1: Value1\n:method:get\nheader2:Value2\n:scheme:https\nheader3:Value3\n",
1✔
195
        );
1✔
196
        // test in place
1✔
197
        let still_buf = unsafe { std::slice::from_raw_parts(buf.as_ptr(), buf.len()) };
1✔
198
        let nb = strip_pseudo_transform_do(still_buf, &mut buf);
1✔
199
        assert_eq!(
1✔
200
            &still_buf[..nb as usize],
1✔
201
            b"Header1: Value1\nheader2:Value2\nheader3:Value3\n"
1✔
202
        );
1✔
203
    }
1✔
204
}
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