-
Notifications
You must be signed in to change notification settings - Fork 152
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
53da809
commit 63cabe6
Showing
2 changed files
with
94 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
use bincode::Options; | ||
use serde::de::DeserializeOwned; | ||
use serde::Serialize; | ||
|
||
const VERSION: &str = "0.3.0"; | ||
|
||
const VERSION_LENGTH_LIMIT: u64 = 100; | ||
|
||
const TYPE_LENGTH_LIMIT: u64 = 1000; | ||
|
||
pub fn safe_serialize<T: Serialize>( | ||
sk: &T, | ||
mut writer: impl std::io::Write, | ||
limit: u64, | ||
) -> bincode::Result<()> { | ||
let my_options = bincode::DefaultOptions::new() | ||
.with_fixint_encoding() | ||
.with_limit(0); | ||
|
||
my_options | ||
.with_limit(VERSION_LENGTH_LIMIT) | ||
.serialize_into::<_, String>(&mut writer, &VERSION.to_owned())?; | ||
|
||
my_options | ||
.with_limit(TYPE_LENGTH_LIMIT) | ||
.serialize_into::<_, String>(&mut writer, &std::any::type_name::<T>().to_owned())?; | ||
|
||
my_options | ||
.with_limit(limit) | ||
.serialize_into(&mut writer, sk)?; | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn safe_deserialize<T: DeserializeOwned>( | ||
mut reader: impl std::io::Read, | ||
limit: u64, | ||
) -> Result<T, String> { | ||
let my_options = bincode::DefaultOptions::new() | ||
.with_fixint_encoding() | ||
.with_limit(0); | ||
|
||
let deserialized_version: String = my_options | ||
.with_limit(10000) | ||
.deserialize_from::<_, String>(&mut reader) | ||
.map_err(|err| err.to_string())?; | ||
|
||
if deserialized_version != VERSION { | ||
return Err(format!( | ||
"Expected version {}, got version {}", | ||
VERSION, deserialized_version | ||
)); | ||
} | ||
|
||
let deserialized_type: String = my_options | ||
.with_limit(TYPE_LENGTH_LIMIT) | ||
.deserialize_from::<_, String>(&mut reader) | ||
.map_err(|err| err.to_string())?; | ||
|
||
if deserialized_type != std::any::type_name::<T>() { | ||
return Err(format!( | ||
"Expected type {}, got type {}", | ||
std::any::type_name::<T>(), | ||
deserialized_type | ||
)); | ||
} | ||
|
||
my_options | ||
.with_limit(limit) | ||
.deserialize_from(&mut reader) | ||
.map_err(|err| err.to_string()) | ||
} | ||
|
||
pub trait ParameterSetConformant { | ||
type ParameterSet; | ||
|
||
fn conformant(&self, param: &Self::ParameterSet) -> bool; | ||
} | ||
|
||
pub fn safe_deserialize_conformant<T: DeserializeOwned + ParameterSetConformant>( | ||
reader: impl std::io::Read, | ||
limit: u64, | ||
parameter: &T::ParameterSet, | ||
) -> Result<T, String> { | ||
let deser: T = safe_deserialize(reader, limit)?; | ||
|
||
if !deser.conformant(parameter) { | ||
return Err("Deserialized object not conformant with given parameter set".to_owned()); | ||
} | ||
|
||
Ok(deser) | ||
} |