cellos-supervisor 0.5.1

CellOS execution-cell runner โ€” boots cells in Firecracker microVMs or gVisor, enforces narrow typed authority, emits signed CloudEvents.
Documentation
//! HPACK string literal (RFC 7541 ยง5.2).
//!
//! Length-prefixed integer with a 7-bit prefix; the top bit is the Huffman
//! flag. Phase 3g dispatches both raw and Huffman-coded payloads โ€” the
//! Huffman path goes through [`super::huffman::decode`].

use super::super::error::H2ParseError;
use super::huffman;
use super::integer::decode_integer;

/// Decode an HPACK string literal. Returns the decoded string and the slice
/// after it.
pub fn decode_string(buf: &[u8]) -> Result<(String, &[u8]), H2ParseError> {
    if buf.is_empty() {
        return Err(H2ParseError::MalformedHeaders);
    }
    let huffman = buf[0] & 0x80 != 0;
    let (len, rest) = decode_integer(buf, 7)?;
    let len_usize = usize::try_from(len).map_err(|_| H2ParseError::MalformedHeaders)?;
    if rest.len() < len_usize {
        return Err(H2ParseError::MalformedHeaders);
    }
    let payload = &rest[..len_usize];
    let after = &rest[len_usize..];
    if huffman {
        let s = huffman::decode(payload)?;
        Ok((s, after))
    } else {
        let s = std::str::from_utf8(payload)
            .map_err(|_| H2ParseError::NonAsciiAuthority)?
            .to_string();
        Ok((s, after))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn raw_literal_round_trips() {
        // 7-bit length 5 + b"hello".
        let buf: Vec<u8> = std::iter::once(5u8)
            .chain(b"hello".iter().copied())
            .collect();
        let (s, rest) = decode_string(&buf).unwrap();
        assert_eq!(s, "hello");
        assert!(rest.is_empty());
    }

    #[test]
    fn huffman_literal_round_trips() {
        let payload = huffman::encode("api.example.com");
        let mut buf = Vec::new();
        // Length prefix: top bit set (Huffman flag) + length.
        assert!(payload.len() < 0x7F);
        buf.push(0x80 | payload.len() as u8);
        buf.extend_from_slice(&payload);
        let (s, rest) = decode_string(&buf).unwrap();
        assert_eq!(s, "api.example.com");
        assert!(rest.is_empty());
    }

    #[test]
    fn malformed_truncated_payload() {
        // Length 5 but only 3 bytes follow.
        let buf = vec![5u8, b'a', b'b', b'c'];
        let err = decode_string(&buf).unwrap_err();
        assert_eq!(err, H2ParseError::MalformedHeaders);
    }
}