arcly-stream 0.1.6

An open-extensible live-media streaming kernel: lock-free zero-copy frame fan-out, instant-start GOP cache, a pluggable multi-protocol ingestion layer (RTMP, RTSP, SRT, WHIP/WHEP shipped), and a feature-gated pure-Rust media plane (MPEG-TS/HLS/fMP4) — runtime, config, and metrics free.
Documentation
//! Deterministic "no-panic sweep" over every network-facing byte parser.
//!
//! These parsers consume untrusted bytes straight off a socket, so the contract
//! is that *no input can make them panic* (slice out-of-bounds, arithmetic
//! overflow in debug, unwrap on `None`, …) — they must always return an
//! `Option`/`Result` or simply skip. A Rust panic aborts the test, so "the test
//! passes" *is* the assertion.
//!
//! This is the stable-toolchain companion to the coverage-guided libfuzzer
//! targets under `fuzz/`: it runs in normal CI on every commit and pins the
//! invariant deterministically, while the fuzz targets explore far deeper when a
//! nightly + `cargo-fuzz` environment is available.

/// A tiny deterministic xorshift64* PRNG — reproducible, dependency-free.
struct Rng(u64);

impl Rng {
    fn new(seed: u64) -> Self {
        Rng(seed | 1)
    }
    fn next_u64(&mut self) -> u64 {
        let mut x = self.0;
        x ^= x >> 12;
        x ^= x << 25;
        x ^= x >> 27;
        self.0 = x;
        x.wrapping_mul(0x2545_F491_4F6C_DD1D)
    }
    /// Fill a fresh `Vec` of pseudo-random bytes of the given length.
    fn bytes(&mut self, len: usize) -> Vec<u8> {
        (0..len).map(|_| (self.next_u64() & 0xFF) as u8).collect()
    }
}

/// Run `f` over many pseudo-random byte buffers across a spread of lengths.
fn sweep(mut f: impl FnMut(&[u8])) {
    for seed in 0..256u64 {
        let mut rng = Rng::new(seed.wrapping_mul(0x9E37_79B9_7F4A_7C15));
        for len in [0usize, 1, 2, 3, 4, 7, 12, 16, 47, 188, 200, 512] {
            f(&rng.bytes(len));
        }
    }
}

#[cfg(any(feature = "rtsp", feature = "webrtc"))]
#[test]
fn rtp_parsers_never_panic() {
    use arcly_stream::protocol::rtp::{AacDepacketizer, H264Depacketizer, RtpHeader};
    let aac = AacDepacketizer::new();
    sweep(|b| {
        let _ = RtpHeader::parse(b);
        let _ = aac.push(b);
        // Also exercise arbitrary AU-header widths (the public `with_lengths`):
        // a hostile/odd SDP `fmtp` must not over-shift or panic.
        if b.len() >= 2 {
            let _ = AacDepacketizer::with_lengths(b[0], b[1]).push(b);
        }
    });
    // Drive the stateful H.264 depacketizer with a sequence of random payloads.
    let mut depack = H264Depacketizer::new();
    let mut seq = 0u16;
    sweep(|b| {
        if !b.is_empty() {
            let _ = depack.push(b, b[0] & 1 == 0, b.len() as u32, seq);
            seq = seq.wrapping_add(1);
        }
    });
}

#[cfg(feature = "srt")]
#[test]
fn srt_parsers_never_panic() {
    use arcly_stream::protocol::srt::{SrtHandshake, SrtPacket, TsDemuxer};
    sweep(|b| {
        let _ = SrtPacket::parse(b);
        let _ = SrtHandshake::parse(b);
    });
    // The TS demuxer is stateful; feed it random chunks (it must resync on 0x47).
    let mut demux = TsDemuxer::new();
    sweep(|b| {
        let _ = demux.push(b);
    });
}

#[cfg(feature = "rtsp")]
#[test]
fn rtsp_parsers_never_panic() {
    use arcly_stream::protocol::rtsp::{InterleavedFrame, RtspRequest, RtspResponse, Sdp};
    sweep(|b| {
        let _ = InterleavedFrame::parse(b);
        let text = String::from_utf8_lossy(b);
        let _ = RtspRequest::parse(&text);
        let _ = RtspResponse::parse(&text, String::new());
        let _ = Sdp::parse(&text);
    });
}

#[cfg(feature = "codec-aac")]
#[test]
fn aac_adts_parser_never_panics() {
    use arcly_stream::codec::parse_adts;
    sweep(|b| {
        let _ = parse_adts(b);
    });
}