#![forbid(unsafe_code)]
pub(crate) mod proc;
pub mod sandbox;
use std::os::fd::AsFd;
use nix::{errno::Errno, unistd::read};
use nom::{Finish, IResult};
pub(crate) fn read_to_end<Fd: AsFd>(fd: Fd, buf: &mut [u8]) -> Result<&mut [u8], Errno> {
let mut from = 0;
loop {
if from == buf.len() {
return Err(Errno::EOVERFLOW); }
match read(&fd, &mut buf[from..]) {
Ok(0) => return Ok(&mut buf[..from]),
Ok(n) => from = from.checked_add(n).ok_or(Errno::EOVERFLOW)?,
Err(Errno::EINTR) => {}
Err(errno) => return Err(errno),
}
}
}
pub(crate) fn map_result<T>(result: IResult<&[u8], T>) -> nix::Result<T> {
match result.finish() {
Ok((_, val)) => Ok(val),
Err(_) => Err(Errno::EINVAL),
}
}
#[cfg(test)]
mod tests {
use nom::bytes::complete::tag;
use super::*;
#[test]
fn test_map_result_1() {
let result: IResult<&[u8], &[u8]> = Ok((&b""[..], &b"hello"[..]));
assert_eq!(map_result(result).unwrap(), b"hello");
}
#[test]
fn test_map_result_2() {
let result: IResult<&[u8], &[u8]> = Ok((&b"rest"[..], &b"val"[..]));
assert_eq!(map_result(result).unwrap(), b"val");
}
#[test]
fn test_map_result_3() {
let result: IResult<&[u8], &[u8]> = Err(nom::Err::Error(nom::error::Error::new(
&b""[..],
nom::error::ErrorKind::Tag,
)));
assert_eq!(map_result(result), Err(Errno::EINVAL));
}
#[test]
fn test_map_result_4() {
let input = b"hello world";
let result = tag::<&[u8], &[u8], nom::error::Error<&[u8]>>(b"hello")(input);
let val = map_result(result).unwrap();
assert_eq!(val, b"hello");
}
#[test]
fn test_map_result_5() {
let input = b"world";
let result = tag::<&[u8], &[u8], nom::error::Error<&[u8]>>(b"hello")(input);
assert_eq!(map_result(result), Err(Errno::EINVAL));
}
}