/src/zenoh/commons/zenoh-codec/fuzz/src/util.rs
Line | Count | Source |
1 | | // |
2 | | // Copyright (c) 2026 ZettaScale Technology |
3 | | // |
4 | | // This program and the accompanying materials are made available under the |
5 | | // terms of the Eclipse Public License 2.0 which is available at |
6 | | // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
7 | | // which is available at https://www.apache.org/licenses/LICENSE-2.0. |
8 | | // |
9 | | // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
10 | | // |
11 | | // Contributors: |
12 | | // ZettaScale Zenoh Team, <zenoh@zettascale.tech> |
13 | | // |
14 | | |
15 | | use arbitrary::{Result as ArbitraryResult, Unstructured}; |
16 | | use zenoh_protocol::core::ZenohIdProto; |
17 | | |
18 | | pub(crate) const TRANSPORT_CORPUS_DIR: &str = "corpus/transport_message"; |
19 | | pub(crate) const NETWORK_CORPUS_DIR: &str = "corpus/network_message"; |
20 | | pub(crate) const SCOUTING_CORPUS_DIR: &str = "corpus/scouting_message"; |
21 | | |
22 | | /// Decodes four arbitrary bytes into a little-endian `u32`. |
23 | 505 | pub(crate) fn arbitrary_u32(u: &mut Unstructured<'_>) -> ArbitraryResult<u32> { |
24 | 505 | let bytes = u.bytes(4)?; |
25 | 474 | Ok(u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])) |
26 | 505 | } |
27 | | |
28 | | /// Decodes two arbitrary bytes into a little-endian `u16`. |
29 | 149 | pub(crate) fn arbitrary_u16(u: &mut Unstructured<'_>) -> ArbitraryResult<u16> { |
30 | 149 | let bytes = u.bytes(2)?; |
31 | 143 | Ok(u16::from_le_bytes([bytes[0], bytes[1]])) |
32 | 149 | } |
33 | | |
34 | | /// Produces a bounded byte vector so the structured models stay small and fast. |
35 | 493 | pub(crate) fn arbitrary_small_bytes( |
36 | 493 | u: &mut Unstructured<'_>, |
37 | 493 | max_len: usize, |
38 | 493 | ) -> ArbitraryResult<Vec<u8>> { |
39 | 493 | let len = (u.arbitrary::<u8>()? as usize) % (max_len + 1); |
40 | 493 | Ok(u.bytes(len)?.to_vec()) |
41 | 493 | } |
42 | | |
43 | | /// Produces a bounded ASCII-ish identifier string for deterministic wire expr names. |
44 | 248 | pub(crate) fn arbitrary_small_identifier( |
45 | 248 | u: &mut Unstructured<'_>, |
46 | 248 | max_len: usize, |
47 | 248 | fallback: &str, |
48 | 248 | ) -> ArbitraryResult<String> { |
49 | 248 | let len = (u.arbitrary::<u8>()? as usize) % (max_len + 1); |
50 | 248 | let bytes = u.bytes(len)?; |
51 | 246 | let mut out = String::with_capacity(bytes.len().max(fallback.len())); |
52 | | |
53 | 483 | for &byte in bytes { |
54 | 237 | let ch = match byte % 37 { |
55 | 237 | 0..=9 => char::from(b'0' + (byte % 10)), |
56 | 140 | 10..=35 => char::from(b'a' + (byte % 26)), |
57 | 40 | _ => '_', |
58 | | }; |
59 | 237 | out.push(ch); |
60 | | } |
61 | | |
62 | 246 | if out.is_empty() { |
63 | 181 | out.push_str(fallback); |
64 | 181 | } |
65 | | |
66 | 246 | Ok(out) |
67 | 248 | } |
68 | | |
69 | | /// Returns the fixed Zenoh ID used by deterministic seed samples. |
70 | 0 | pub(crate) fn fixed_zid() -> ZenohIdProto { |
71 | 0 | ZenohIdProto::try_from([0x10, 0x20, 0x30, 0x40]).expect("fixed corpus ZenohId must be valid") |
72 | 0 | } |