aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Sacchini <joey@sacchini.net>2021-01-04 21:19:52 -0500
committerJoey Sacchini <joey@sacchini.net>2021-01-04 21:19:52 -0500
commit6ec44bd5b6a354c55f3f5175f55d26534ee5b886 (patch)
tree94a864e5aa6a3baaa72de09340cde3597965571d
parentdccbf0f736916f4ff4c36a2ea321397dee518a63 (diff)
downloadcraftio-rs-6ec44bd5b6a354c55f3f5175f55d26534ee5b886.tar.gz
craftio-rs-6ec44bd5b6a354c55f3f5175f55d26534ee5b886.tar.bz2
craftio-rs-6ec44bd5b6a354c55f3f5175f55d26534ee5b886.zip
remove some unsafe code and add max packet size (also add some debug assertions)
-rw-r--r--src/reader.rs33
-rw-r--r--src/util.rs28
2 files changed, 27 insertions, 34 deletions
diff --git a/src/reader.rs b/src/reader.rs
index f481824..7f2cd68 100644
--- a/src/reader.rs
+++ b/src/reader.rs
@@ -16,6 +16,8 @@ use thiserror::Error;
#[cfg(any(feature = "futures-io", feature = "tokio-io"))]
use async_trait::async_trait;
+pub const MAX_PACKET_SIZE: usize = 32 * 1000 * 1000;
+
#[derive(Debug, Error)]
pub enum ReadError {
#[error("i/o failure during read")]
@@ -259,7 +261,14 @@ where
fn read_raw_inner(&mut self) -> ReadResult<usize> {
self.move_ready_data_to_front();
let primary_packet_len = rr_unwrap!(self.read_packet_len_sync()).0 as usize;
- self.ensure_n_ready_sync(primary_packet_len)?;
+ if primary_packet_len > MAX_PACKET_SIZE {
+ return Ok(None);
+ }
+
+ if self.ensure_n_ready_sync(primary_packet_len)?.is_none() {
+ return Ok(None);
+ }
+
Ok(Some(primary_packet_len))
}
@@ -312,12 +321,19 @@ where
async fn read_raw_inner_async(&mut self) -> ReadResult<usize> {
self.move_ready_data_to_front();
let primary_packet_len = rr_unwrap!(self.read_packet_len_async().await).0 as usize;
- self.ensure_n_ready_async(primary_packet_len).await?;
+ if primary_packet_len > MAX_PACKET_SIZE {
+ return Ok(None);
+ }
+
+ if self.ensure_n_ready_async(primary_packet_len).await?.is_none() {
+ return Ok(None);
+ }
+
+ debug_assert!(self.raw_ready >= primary_packet_len, "{} packet len bytes are ready (actual: {})", primary_packet_len, self.raw_ready);
Ok(Some(primary_packet_len))
}
async fn read_packet_len_async(&mut self) -> ReadResult<VarInt> {
- self.move_ready_data_to_front();
let buf = rr_unwrap!(self.ensure_n_ready_async(VAR_INT_BUF_SIZE).await);
let (v, size) = rr_unwrap!(deserialize_varint(buf));
self.raw_ready -= size;
@@ -330,11 +346,13 @@ where
let to_read = n - self.raw_ready;
let target =
get_sized_buf(&mut self.raw_buf, self.raw_offset + self.raw_ready, to_read);
+ debug_assert_eq!(target.len(), to_read);
check_unexpected_eof!(self.inner.read_exact(target).await);
self.raw_ready = n;
}
let ready = get_sized_buf(&mut self.raw_buf, self.raw_offset, n);
+ debug_assert_eq!(ready.len(), n);
Ok(Some(ready))
}
}
@@ -440,7 +458,7 @@ impl<R> CraftReader<R> {
// find data in buf
let offset = self.raw_offset;
if self.raw_ready < size {
- panic!("not enough data is ready!");
+ panic!("not enough data is ready, got {} ready and {} desired ready!", self.raw_ready, size);
}
self.raw_ready -= size;
self.raw_offset += size;
@@ -507,12 +525,7 @@ impl<R> CraftReader<R> {
.as_mut()
.expect("if raw_ready > 0 and raw_offset > 0 then a raw_buf should exist!");
- unsafe {
- let dest = raw_buf.as_mut_ptr();
- let src = dest.offset(self.raw_offset as isize);
- let n_copy = self.raw_ready;
- std::ptr::copy(src, dest, n_copy);
- }
+ raw_buf.copy_within(self.raw_offset..(self.raw_offset+self.raw_ready), 0);
}
self.raw_offset = 0;
diff --git a/src/util.rs b/src/util.rs
index e33fc10..3f4bd9f 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -17,18 +17,8 @@ pub(crate) fn get_sized_buf(buf: &mut Option<Vec<u8>>, offset: usize, size: usiz
}
fn ensure_buf_has_size(buf: &mut Vec<u8>, total_size: usize) {
- let cur_len = buf.len();
- if cur_len >= total_size {
- return;
- }
-
- let additional = total_size - cur_len;
- buf.reserve(additional);
- unsafe {
- let start_at = buf.as_mut_ptr();
- let start_write_at = start_at.offset(cur_len as isize);
- std::ptr::write_bytes(start_write_at, 0, additional);
- buf.set_len(total_size);
+ if total_size > buf.len() {
+ buf.resize(total_size, 0u8);
}
}
@@ -42,15 +32,5 @@ pub(crate) fn move_data_rightwards(target: &mut [u8], size: usize, shift_amount:
)
}
- unsafe { move_data_rightwards_unchecked(target, size, shift_amount) }
-}
-
-unsafe fn move_data_rightwards_unchecked(target: &mut [u8], size: usize, shift_amount: usize) {
- if shift_amount == 0 {
- return;
- }
-
- let src_ptr = target.as_mut_ptr();
- let dst_ptr = src_ptr.offset(shift_amount as isize);
- std::ptr::copy(src_ptr, dst_ptr, size);
-}
+ target.copy_within(0..size, shift_amount);
+} \ No newline at end of file