Browse Source

protocol: deny unsafe code

ipv6
Denis Drakhnia 10 months ago
parent
commit
4ebe222478
  1. 55
      protocol/src/cursor.rs
  2. 1
      protocol/src/lib.rs

55
protocol/src/cursor.rs

@ -1,11 +1,8 @@
// SPDX-License-Identifier: LGPL-3.0-only // SPDX-License-Identifier: LGPL-3.0-only
// SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com> // SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com>
use std::fmt;
use std::io::{self, Write as _}; use std::io::{self, Write as _};
use std::mem; use std::{fmt, mem, str};
use std::slice;
use std::str;
use thiserror::Error; use thiserror::Error;
@ -385,8 +382,8 @@ impl_put_key_value! {
} }
pub struct CursorMut<'a> { pub struct CursorMut<'a> {
buffer: &'a [u8], buffer: &'a mut [u8],
buffer_mut: &'a mut [u8], pos: usize,
} }
macro_rules! impl_put { macro_rules! impl_put {
@ -400,42 +397,25 @@ macro_rules! impl_put {
impl<'a> CursorMut<'a> { impl<'a> CursorMut<'a> {
pub fn new(buffer: &'a mut [u8]) -> Self { pub fn new(buffer: &'a mut [u8]) -> Self {
let (buffer, buffer_mut) = buffer.split_at_mut(0); Self { buffer, pos: 0 }
Self { buffer, buffer_mut }
}
pub fn buffer(&self) -> &'a [u8] {
self.buffer
}
pub fn buffer_mut<'b: 'a>(&'b mut self) -> &'a mut [u8] {
self.buffer_mut
}
pub fn end(self) -> (&'a [u8], &'a mut [u8]) {
(self.buffer, self.buffer_mut)
} }
pub fn pos(&mut self) -> usize { pub fn pos(&mut self) -> usize {
self.buffer.len() self.pos
} }
#[inline(always)] #[inline(always)]
pub fn remaining(&self) -> usize { pub fn remaining(&self) -> usize {
self.buffer_mut.len() self.buffer.len() - self.pos
} }
pub fn advance<F>(&mut self, count: usize, mut f: F) -> Result<&mut Self, Error> pub fn advance<F>(&mut self, count: usize, mut f: F) -> Result<&mut Self, Error>
where where
F: FnMut(&'a mut [u8]), F: FnMut(&mut [u8]),
{ {
if count <= self.remaining() { if count <= self.remaining() {
let buffer_mut = mem::take(&mut self.buffer_mut); f(&mut self.buffer[self.pos..self.pos + count]);
let (head, tail) = buffer_mut.split_at_mut(count); self.pos += count;
f(head);
self.buffer =
unsafe { slice::from_raw_parts(self.buffer.as_ptr(), self.buffer.len() + count) };
self.buffer_mut = tail;
Ok(self) Ok(self)
} else { } else {
Err(Error::UnexpectedEnd) Err(Error::UnexpectedEnd)
@ -502,11 +482,10 @@ impl<'a> CursorMut<'a> {
} }
pub fn put_as_str<T: fmt::Display>(&mut self, value: T) -> Result<&mut Self, Error> { pub fn put_as_str<T: fmt::Display>(&mut self, value: T) -> Result<&mut Self, Error> {
let mut cur = io::Cursor::new(mem::take(&mut self.buffer_mut)); let mut cur = io::Cursor::new(&mut self.buffer[self.pos..]);
write!(&mut cur, "{}", value).map_err(|_| Error::UnexpectedEnd)?; write!(&mut cur, "{}", value).map_err(|_| Error::UnexpectedEnd)?;
let n = cur.position() as usize; self.pos += cur.position() as usize;
self.buffer_mut = cur.into_inner(); Ok(self)
self.advance(n, |_| {})
} }
pub fn put_key_value<T: PutKeyValue>(&mut self, value: T) -> Result<&mut Self, Error> { pub fn put_key_value<T: PutKeyValue>(&mut self, value: T) -> Result<&mut Self, Error> {
@ -535,7 +514,7 @@ mod tests {
#[test] #[test]
fn cursor() -> Result<(), Error> { fn cursor() -> Result<(), Error> {
let mut buf = [0; 64]; let mut buf = [0; 64];
let s = CursorMut::new(&mut buf) let n = CursorMut::new(&mut buf)
.put_bytes(b"12345678")? .put_bytes(b"12345678")?
.put_array(b"4321")? .put_array(b"4321")?
.put_str("abc")? .put_str("abc")?
@ -543,7 +522,8 @@ mod tests {
.put_u8(0x7f)? .put_u8(0x7f)?
.put_i8(-128)? .put_i8(-128)?
.put_u32_le(0x44332211)? .put_u32_le(0x44332211)?
.buffer(); .pos();
let s = &buf[..n];
let mut cur = Cursor::new(s); let mut cur = Cursor::new(s);
assert_eq!(cur.get_bytes(8), Ok(&b"12345678"[..])); assert_eq!(cur.get_bytes(8), Ok(&b"12345678"[..]));
@ -561,7 +541,7 @@ mod tests {
#[test] #[test]
fn key() -> Result<(), Error> { fn key() -> Result<(), Error> {
let mut buf = [0; 512]; let mut buf = [0; 512];
let s = CursorMut::new(&mut buf) let n = CursorMut::new(&mut buf)
.put_key("p", 49)? .put_key("p", 49)?
.put_key("map", "crossfire")? .put_key("map", "crossfire")?
.put_key("dm", true)? .put_key("dm", true)?
@ -572,7 +552,8 @@ mod tests {
.put_key("gamedir", "valve")? .put_key("gamedir", "valve")?
.put_key("password", false)? .put_key("password", false)?
.put_key("host", "test")? .put_key("host", "test")?
.buffer(); .pos();
let s = &buf[..n];
let mut cur = Cursor::new(s); let mut cur = Cursor::new(s);
assert_eq!(cur.get_key(), Ok((&b"p"[..], 49_u8))); assert_eq!(cur.get_key(), Ok((&b"p"[..], 49_u8)));

1
protocol/src/lib.rs

@ -1,6 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-only // SPDX-License-Identifier: LGPL-3.0-only
// SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com> // SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com>
#![deny(unsafe_code)]
#![deny(missing_docs)] #![deny(missing_docs)]
//! Xash3D protocol between clients, servers and masters. //! Xash3D protocol between clients, servers and masters.

Loading…
Cancel
Save