1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-03 18:24:05 +02:00

remove some slice indexing

This commit is contained in:
Robin Appelman 2024-04-07 16:10:11 +02:00
commit 1d71aa8ba6
9 changed files with 42 additions and 33 deletions

View file

@ -14,6 +14,8 @@ impl ConstFnvHash {
let mut i = 0; let mut i = 0;
while i < bytes.len() { while i < bytes.len() {
// can't use better method in const fns
#[allow(clippy::indexing_slicing)]
let byte = bytes[i]; let byte = bytes[i];
hash ^= byte as u64; hash ^= byte as u64;
hash = hash.wrapping_mul(0x100000001b3); hash = hash.wrapping_mul(0x100000001b3);

View file

@ -1,12 +1,12 @@
use std::convert::TryInto;
pub fn decompress(input: &[u8], output: &mut Vec<u8>) { pub fn decompress(input: &[u8], output: &mut Vec<u8>) {
decompress_(input, output); decompress_(input, output);
} }
/// inner fn that returns an option so we can use ? for short circuiting return /// inner fn that returns an option so we can use ? for short circuiting return
fn decompress_(input: &[u8], output: &mut Vec<u8>) -> Option<()> { fn decompress_(input: &[u8], output: &mut Vec<u8>) -> Option<()> {
let target_len = u32::from_le_bytes(input[0..4].try_into().unwrap()) as usize; let mut len_bytes = [0; 4];
len_bytes.copy_from_slice(input.get(0..4)?);
let target_len = u32::from_le_bytes(len_bytes) as usize;
let mut read_pos = 4; let mut read_pos = 4;
let mut read_byte = move || { let mut read_byte = move || {
@ -35,7 +35,7 @@ fn decompress_(input: &[u8], output: &mut Vec<u8>) -> Option<()> {
let start = output.len() - pos - 1; let start = output.len() - pos - 1;
// can't do extend_from_within since it start + count can be larger than output.len // can't do extend_from_within since it start + count can be larger than output.len
for i in 0..count { for i in 0..count {
output.push(output[start + i]); output.push(*output.get(start + i)?);
} }
} else { } else {
output.push(read_byte()?); output.push(read_byte()?);

View file

@ -197,12 +197,15 @@ impl PacketEntity {
} }
pub fn get_baseline_props<'a>(&self, parser_state: &'a ParserState) -> Cow<'a, [SendProp]> { pub fn get_baseline_props<'a>(&self, parser_state: &'a ParserState) -> Cow<'a, [SendProp]> {
let Some(send_table) = parser_state.send_tables.get(usize::from(self.server_class)) else {
return Cow::default();
};
parser_state parser_state
.get_baseline( .get_baseline(
self.baseline_index, self.baseline_index,
self.entity_index, self.entity_index,
self.server_class, self.server_class,
&parser_state.send_tables[usize::from(self.server_class)], send_table,
self.delta.is_some(), self.delta.is_some(),
) )
.unwrap_or_default() .unwrap_or_default()

View file

@ -613,7 +613,13 @@ fn write_table_entry(
if let Some((history_index, history_count)) = history_item { if let Some((history_index, history_count)) = history_item {
history_index.write_sized(stream, 5)?; history_index.write_sized(stream, 5)?;
history_count.write_sized(stream, 5)?; history_count.write_sized(stream, 5)?;
let diff_bytes = &text.as_bytes()[history_count..]; let diff_bytes =
text.as_bytes()
.get(history_count..)
.ok_or(BitError::IndexOutOfBounds {
pos: history_count,
size: text.len(),
})?;
stream.write_bytes(diff_bytes)?; stream.write_bytes(diff_bytes)?;
0u8.write(stream)?; // writing the string as bytes doesn't add the null terminator 0u8.write(stream)?; // writing the string as bytes doesn't add the null terminator
} else { } else {

View file

@ -97,14 +97,10 @@ impl ParseBitSkip<'_> for TempEntitiesMessage {
impl Encode for TempEntitiesMessage { impl Encode for TempEntitiesMessage {
fn encode(&self, stream: &mut BitWriteStream<LittleEndian>, state: &ParserState) -> Result<()> { fn encode(&self, stream: &mut BitWriteStream<LittleEndian>, state: &ParserState) -> Result<()> {
let count = if self.events.len() == 1 { let count = match (self.events.len(), self.events.first()) {
if self.events[0].reliable { (1, Some(event)) if event.reliable => 0,
0 (1, _) => 1,
} else { (len, _) => len as u8,
1
}
} else {
self.events.len() as u8
}; };
count.write(stream)?; count.write(stream)?;

View file

@ -329,6 +329,7 @@ impl ParseSendTable {
// sort often changed props before the others // sort often changed props before the others
let mut start = 0; let mut start = 0;
for i in 0..flat.len() { for i in 0..flat.len() {
#[allow(clippy::indexing_slicing)]
if flat[i].parse_definition.changes_often() { if flat[i].parse_definition.changes_often() {
if i != start { if i != start {
flat.swap(i, start); flat.swap(i, start);

View file

@ -18,7 +18,6 @@ use serde::de::Error;
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
use std::convert::TryFrom; use std::convert::TryFrom;
use std::ops::{Index, IndexMut};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ChatMessage { pub struct ChatMessage {
@ -169,6 +168,18 @@ impl ClassList {
classes.sort_by(|a, b| a.1.cmp(&b.1).reverse()); classes.sort_by(|a, b| a.1.cmp(&b.1).reverse());
classes.into_iter() classes.into_iter()
} }
pub fn get(&self, class: Class) -> u8 {
// class number is always in bounds
#[allow(clippy::indexing_slicing)]
self.0[class as u8 as usize]
}
pub fn get_mut(&mut self, class: Class) -> &mut u8 {
// class number is always in bounds
#[allow(clippy::indexing_slicing)]
&mut self.0[class as u8 as usize]
}
} }
#[test] #[test]
@ -180,22 +191,6 @@ fn test_classlist_sorted() {
) )
} }
impl Index<Class> for ClassList {
type Output = u8;
#[cfg_attr(feature = "no-panic", no_panic::no_panic)]
fn index(&self, class: Class) -> &Self::Output {
&self.0[class as u8 as usize]
}
}
impl IndexMut<Class> for ClassList {
#[cfg_attr(feature = "no-panic", no_panic::no_panic)]
fn index_mut(&mut self, class: Class) -> &mut Self::Output {
&mut self.0[class as u8 as usize]
}
}
impl Serialize for ClassList { impl Serialize for ClassList {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -218,7 +213,7 @@ impl From<HashMap<Class, u8>> for ClassList {
let mut classes = ClassList::default(); let mut classes = ClassList::default();
for (class, count) in map.into_iter() { for (class, count) in map.into_iter() {
classes[class] = count; *classes.get_mut(class) = count;
} }
classes classes
@ -505,7 +500,7 @@ impl Analyser {
GameEvent::PlayerSpawn(event) => { GameEvent::PlayerSpawn(event) => {
let spawn = Spawn::from_event(event, tick); let spawn = Spawn::from_event(event, tick);
if let Some(user_state) = self.state.users.get_mut(&spawn.user) { if let Some(user_state) = self.state.users.get_mut(&spawn.user) {
user_state.classes[spawn.class] += 1; *user_state.classes.get_mut(spawn.class) += 1;
user_state.team = spawn.team; user_state.team = spawn.team;
} }
} }

View file

@ -282,6 +282,7 @@ impl GameState {
} }
}; };
#[allow(clippy::indexing_slicing)]
&mut self.players[index] &mut self.players[index]
} }
pub fn get_or_create_building( pub fn get_or_create_building(

View file

@ -1,3 +1,8 @@
#![cfg_attr(not(test), deny(clippy::unwrap_used))]
#![cfg_attr(not(test), deny(clippy::expect_used))]
#![cfg_attr(not(test), deny(clippy::indexing_slicing))]
#![cfg_attr(not(test), deny(clippy::panic))]
pub use bitbuffer::Result as ReadResult; pub use bitbuffer::Result as ReadResult;
pub use crate::demo::{ pub use crate::demo::{