document-graphics 0.1.6

Render graphics from untrusted documents to RGBA, with resource limits and isolated workers.
Documentation
use super::{Info, Region};
use serde::{Deserialize, Serialize};
use std::io::{self, Read, Write};
const MAX_MESSAGE: usize = 16 * 1024;
#[derive(Serialize, Deserialize, Clone)]
pub(super) enum Operation {
    Info,
    Render(Vec<Region>),
}
#[derive(Serialize, Deserialize)]
pub(super) enum Response {
    Info(Info),
    Pixels { regions: Vec<Region>, delay_ms: u32 },
    Error(String),
}
pub(super) fn write(output: &mut impl Write, value: &impl Serialize) -> io::Result<()> {
    let bytes = serde_json::to_vec(value)?;
    if bytes.len() > MAX_MESSAGE {
        return Err(io::Error::other("Image message exceeds limit"));
    }
    output.write_all(&(bytes.len() as u32).to_le_bytes())?;
    output.write_all(&bytes)?;
    output.flush()
}
pub(super) fn read<T: serde::de::DeserializeOwned>(input: &mut impl Read) -> io::Result<T> {
    let mut size = [0; 4];
    input.read_exact(&mut size)?;
    let size = u32::from_le_bytes(size) as usize;
    if size > MAX_MESSAGE {
        return Err(io::Error::other("Image message exceeds limit"));
    }
    let mut bytes = vec![0; size];
    input.read_exact(&mut bytes)?;
    Ok(serde_json::from_slice(&bytes)?)
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn oversized_headers_fail_before_payload_allocation_or_read() {
        let bytes = (MAX_MESSAGE as u32 + 1).to_le_bytes();
        let result = read::<Response>(&mut &bytes[..]);
        assert!(result.err().unwrap().to_string().contains("exceeds limit"));
    }
}