mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 10:14:06 +02:00
Fix saturating overflow in ExtraData parsing
- Fix overflow in ExtraData by casting byte_len to usize before multiplication. This was previously multiplying a u16 with saturating_mul and would overflow when the extra data in string tables reaches a certain size. - Add test case for parsing large string table to verify correct stream position after read.
This commit is contained in:
parent
d9b711add6
commit
624efb6427
4 changed files with 26 additions and 2 deletions
|
|
@ -154,7 +154,7 @@ fn test_string_table_roundtrip() {
|
||||||
#[serde(bound(deserialize = "'a: 'static"))]
|
#[serde(bound(deserialize = "'a: 'static"))]
|
||||||
pub struct ExtraData<'a> {
|
pub struct ExtraData<'a> {
|
||||||
pub byte_len: u16,
|
pub byte_len: u16,
|
||||||
#[size = "byte_len.saturating_mul(8)"]
|
#[size = "(byte_len as usize).saturating_mul(8)"]
|
||||||
pub data: Stream<'a>,
|
pub data: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
BIN
test_data/string_tables/ServerMapCycleLarge.bin
Normal file
BIN
test_data/string_tables/ServerMapCycleLarge.bin
Normal file
Binary file not shown.
4
test_data/string_tables/ServerMapCycleLarge_meta.json
Normal file
4
test_data/string_tables/ServerMapCycleLarge_meta.json
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"name": "ServerMapCycle",
|
||||||
|
"marker": 4039822362
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ use test_case::test_case;
|
||||||
use tf_demo_parser::demo::message::stringtable::{
|
use tf_demo_parser::demo::message::stringtable::{
|
||||||
parse_string_table_update, write_string_table_update, StringTableMeta,
|
parse_string_table_update, write_string_table_update, StringTableMeta,
|
||||||
};
|
};
|
||||||
use tf_demo_parser::demo::packet::stringtable::FixedUserDataSize;
|
use tf_demo_parser::demo::packet::stringtable::{FixedUserDataSize, StringTable};
|
||||||
|
|
||||||
#[test_case("test_data/string_tables/decalprecache.bin", "test_data/string_tables/decalprecache_meta.json"; "decalprecache")]
|
#[test_case("test_data/string_tables/decalprecache.bin", "test_data/string_tables/decalprecache_meta.json"; "decalprecache")]
|
||||||
#[test_case("test_data/string_tables/downloadables.bin", "test_data/string_tables/downloadables_meta.json"; "downloadables")]
|
#[test_case("test_data/string_tables/downloadables.bin", "test_data/string_tables/downloadables_meta.json"; "downloadables")]
|
||||||
|
|
@ -67,3 +67,23 @@ fn string_table_reencode(input_file: &str, meta_file: &str) {
|
||||||
pretty_assertions::assert_eq!(data, out);
|
pretty_assertions::assert_eq!(data, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test_case("test_data/string_tables/ServerMapCycleLarge.bin", "test_data/string_tables/ServerMapCycleLarge_meta.json"; "ServerMapCycleLarge")]
|
||||||
|
fn large_string_table_parsing(input_file: &str, meta_file: &str) {
|
||||||
|
let data = fs::read(input_file).unwrap();
|
||||||
|
let meta: serde_json::Value =
|
||||||
|
serde_json::from_str(&fs::read_to_string(meta_file).unwrap()).unwrap();
|
||||||
|
|
||||||
|
let expected_table_name = meta["name"].as_str().unwrap();
|
||||||
|
let expected_marker = meta["marker"].as_u64().unwrap() as u32;
|
||||||
|
|
||||||
|
let mut stream = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
|
||||||
|
|
||||||
|
// Parse the table data
|
||||||
|
let table: StringTable<'_> = stream.read().unwrap();
|
||||||
|
pretty_assertions::assert_eq!(expected_table_name, table.name);
|
||||||
|
|
||||||
|
// Ensure the stream position is correct (previously the byte_len.saturated_mul(8) in ExtraData could overflow and would leave the BitReadStream in a bad state).
|
||||||
|
let marker: u32 = stream.read().unwrap();
|
||||||
|
pretty_assertions::assert_eq!(expected_marker, marker);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue