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 integer encoding (RFC 7541 §5.1).
//!
//! Pure-byte parsing: takes a buffer + the prefix bit-width and returns the
//! integer + remaining slice. Bounded iteration to defend against an
//! adversary who emits an unbounded chain of continuation octets.

use super::super::error::H2ParseError;

/// Decode an HPACK integer with `prefix_bits` of the first octet allocated
/// to the integer prefix. Returns the integer and the slice immediately
/// after it.
pub fn decode_integer(buf: &[u8], prefix_bits: u32) -> Result<(u64, &[u8]), H2ParseError> {
    if buf.is_empty() {
        return Err(H2ParseError::MalformedHeaders);
    }
    let mask: u8 = ((1u16 << prefix_bits) - 1) as u8;
    let prefix = buf[0] & mask;
    if prefix < mask {
        return Ok((prefix as u64, &buf[1..]));
    }
    // Multi-octet form. Continuation bytes use the bottom 7 bits as data;
    // the top bit signals "more". Cap the iterations to bound CPU.
    let mut value: u64 = mask as u64;
    let mut shift: u32 = 0;
    let mut idx: usize = 1;
    loop {
        if idx >= buf.len() {
            return Err(H2ParseError::MalformedHeaders);
        }
        let b = buf[idx];
        idx += 1;
        let chunk = (b & 0x7F) as u64;
        let shifted = chunk
            .checked_shl(shift)
            .ok_or(H2ParseError::MalformedHeaders)?;
        value = value
            .checked_add(shifted)
            .ok_or(H2ParseError::MalformedHeaders)?;
        if b & 0x80 == 0 {
            return Ok((value, &buf[idx..]));
        }
        shift = shift.checked_add(7).ok_or(H2ParseError::MalformedHeaders)?;
        if shift >= 64 {
            return Err(H2ParseError::MalformedHeaders);
        }
    }
}

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

    #[test]
    fn decodes_short_form_under_prefix_max() {
        // 7-bit prefix, value 10 < 127 → single octet.
        let (v, rest) = decode_integer(&[0x0A, 0xAA], 7).unwrap();
        assert_eq!(v, 10);
        assert_eq!(rest, &[0xAA]);
    }

    #[test]
    fn decodes_multi_octet_form() {
        // 7-bit prefix saturated (127) + one continuation octet 0x05 → 132.
        let (v, _) = decode_integer(&[0x7F, 0x05], 7).unwrap();
        assert_eq!(v, 127 + 5);
    }

    #[test]
    fn rejects_unbounded_continuation() {
        // 9 continuation octets all with high bit set → shift overflow.
        let buf: Vec<u8> = std::iter::once(0x7F)
            .chain(std::iter::repeat_n(0xFF, 16))
            .collect();
        assert!(decode_integer(&buf, 7).is_err());
    }
}