修复未对齐问题, 添加一个 readi16 be api(虽说用不上

This commit is contained in:
shenjack 2024-03-10 20:52:36 +08:00
parent 1d8a7400eb
commit 395a26bd41
Signed by: shenjack
GPG Key ID: 7B1134A979775551
4 changed files with 89 additions and 21 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "shen-nbt5"
version = "0.4.3"
version = "0.4.4"
edition = "2021"
description = "Just A FASSST NBT parser/writer"
homepage = "https://github.com/shenjackyuanjie/nbt-rust"

View File

@ -721,6 +721,26 @@ impl NbtReader<'_> {
self.cursor += len;
value
}
/// 读取指定长度的 i16 数组
///
/// # 安全性
///
/// 长度溢出会导致 UB
#[inline]
pub unsafe fn read_be_i16_array_unsafe(&mut self, len: usize) -> Vec<i16> {
let mut value: Vec<i16> = Vec::with_capacity(len);
std::ptr::copy_nonoverlapping(
self.data[self.cursor..].as_ptr() as *const u8,
value.as_ptr() as *mut u8,
len * 2,
);
value.set_len(len);
for n in &mut value {
*n = n.to_be();
}
self.cursor += len * 2;
value
}
/// 读取指定长度的 i32 数组
///
/// # 安全性
@ -728,15 +748,39 @@ impl NbtReader<'_> {
/// 长度溢出会导致 UB
#[inline]
pub unsafe fn read_be_i32_array_unsafe(&mut self, len: usize) -> Vec<i32> {
let value =
std::slice::from_raw_parts(self.data[self.cursor..].as_ptr() as *const i32, len);
let mut value = value.to_vec();
let mut value: Vec<i32> = Vec::with_capacity(len);
std::ptr::copy_nonoverlapping(
self.data[self.cursor..].as_ptr() as *const u8,
value.as_ptr() as *mut u8,
len * 4,
);
value.set_len(len);
for n in &mut value {
*n = n.to_be();
}
self.cursor += len * 4;
value
}
/// 读取指定长度的 i64 数组
///
/// # 安全性
///
/// 长度溢出会导致 UB
#[inline]
pub unsafe fn read_be_i64_array_unsafe(&mut self, len: usize) -> Vec<i64> {
let mut value: Vec<i64> = Vec::with_capacity(len);
std::ptr::copy_nonoverlapping(
self.data[self.cursor..].as_ptr() as *const u8,
value.as_ptr() as *mut u8,
len * 8,
);
value.set_len(len);
for n in &mut value {
*n = n.to_be();
}
self.cursor += len * 8;
value
}
/// 读取指定长度的 i32 数组
///
/// # 安全性
@ -755,22 +799,6 @@ impl NbtReader<'_> {
///
/// # 安全性
///
/// 长度溢出会导致 UB
#[inline]
pub unsafe fn read_be_i64_array_unsafe(&mut self, len: usize) -> Vec<i64> {
let value =
std::slice::from_raw_parts(self.data[self.cursor..].as_ptr() as *const i64, len);
let mut value = value.to_vec();
for n in &mut value {
*n = n.to_be();
}
self.cursor += len * 8;
value
}
/// 读取指定长度的 i64 数组
///
/// # 安全性
///
/// 长度溢出会导致 panic
#[inline]
pub fn read_be_i64_array(&mut self, len: usize) -> Vec<i64> {

View File

@ -280,6 +280,46 @@ mod unsafe_test {
assert_eq!(reader.cursor, 100 * 8);
}
}
/// 未对齐的地址
#[test]
fn unaligned_read_u16_array() {
let mut value = vec![0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04];
let mut reader = NbtReader::new(&mut value);
let value = reader.read_u8();
assert_eq!(value, 0x01);
assert_eq!(reader.cursor, 1);
unsafe {
// 读取 u16 数组
let array = reader.read_be_i16_array_unsafe(3);
assert_eq!(array, vec![0x0203, 0x0401, 0x0203]);
assert_eq!(reader.cursor, 7);
let value = reader.read_u8();
assert_eq!(value, 0x04);
assert_eq!(reader.cursor, 8);
}
}
/// 依然是未对齐
/// 只不过是 u32/i32
#[test]
fn unaligned_read_x32_array() {
let mut value = gen_datas(202);
let mut reader = NbtReader::new(&mut value);
let value = reader.read_u8();
assert_eq!(value, 0x00);
assert_eq!(reader.cursor, 1);
unsafe {
let array = reader.read_be_i32_array_unsafe(50);
reader.roll_back(50 * 4);
let safe_array = reader.read_be_i32_array(50);
assert_eq!(array, safe_array);
assert_eq!(reader.cursor, 201);
}
let value = reader.read_u8();
assert_eq!(value, 201);
assert_eq!(reader.cursor, 202);
}
}
mod nbt {