Skip to content

Commit

Permalink
add some sanity checks to compressed and decompressed size for snap e…
Browse files Browse the repository at this point in the history
…ncoded string tables
  • Loading branch information
icewind1991 committed May 23, 2021
1 parent 0cc00dd commit bb79d26
Showing 1 changed file with 17 additions and 7 deletions.
24 changes: 17 additions & 7 deletions src/demo/message/stringtable.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian};
use num_traits::{PrimInt, Unsigned};
use snap::raw::Decoder;
use snap::raw::{decompress_len, Decoder};

use crate::demo::packet::stringtable::{
ExtraData, FixedUserDataSize, StringTable, StringTableEntry,
Expand Down Expand Up @@ -48,12 +48,18 @@ impl<'a> Parse<'a> for CreateStringTableMessage<'a> {
let decompressed_size: u32 = table_data.read()?;
let compressed_size: u32 = table_data.read()?;

if compressed_size < 4 {
if compressed_size < 4 || compressed_size > 10 * 1024 * 1024 {
return Err(ParseError::InvalidDemo(
"Invalid compressed string table size",
));
}

if decompressed_size > 100 * 1024 * 1024 {
return Err(ParseError::InvalidDemo(
"Invalid decompressed string table size",
));
}

let magic = table_data.read_string(Some(4))?;

if magic != "SNAP" {
Expand All @@ -63,17 +69,21 @@ impl<'a> Parse<'a> for CreateStringTableMessage<'a> {
let compressed_data = table_data.read_bytes(compressed_size as usize - 4)?;

let mut decoder = Decoder::new();
let decompressed_data = decoder
.decompress_vec(&compressed_data)
.map_err(ParseError::from)?;

if decompressed_data.len() != decompressed_size as usize {
let decompressed_size_from_header = decompress_len(&compressed_data)?;

if decompressed_size_from_header != decompressed_size as usize {
return Err(ParseError::UnexpectedDecompressedSize {
expected: decompressed_size,
size: decompressed_data.len() as u32,
size: decompressed_size_from_header as u32,
});
}

let mut decompressed_data = vec![0; decompressed_size_from_header];
decoder
.decompress(&compressed_data, &mut decompressed_data)
.map_err(ParseError::from)?;

let buffer = BitReadBuffer::new_owned(decompressed_data, LittleEndian);
table_data = BitReadStream::new(buffer);
}
Expand Down

0 comments on commit bb79d26

Please sign in to comment.