Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Are bincode serialisations unique? #192

Closed
chrisdew opened this issue Jul 7, 2017 · 2 comments
Closed

Are bincode serialisations unique? #192

chrisdew opened this issue Jul 7, 2017 · 2 comments

Comments

@chrisdew
Copy link

@chrisdew chrisdew commented Jul 7, 2017

Can more than one bincode serialisation (especially malicious hand-coded byte-streams) be deserialised to the same data?

I need the hashes of serialised messages to uniquely represent their content, i.e. a 1:1 relation between serialised messages and their content.

Does bincode raise errors if there are more bytes in the serialised message than are needed for deserialisation? i.e. Are nonsense trailing bytes. appended to change the hash of the serialised message, detected?

I'm not using floats, so I don't care about denormal numbers, which might otherwise be an issue.

@dtolnay
Copy link
Collaborator

@dtolnay dtolnay commented Jul 7, 2017

Deserialize implementations can be any Rust code, so in general Bincode cannot guarantee that different serialized messages will produce different data structures. For example in Bincode the following reads any byte and ignores it:

struct Chrisdew;

impl<'de> Deserialize<'de> for Chrisdew {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        u8::deserialize(deserializer)?;
        Ok(Chrisdew)
    }
}

One common case of this would be associative container types. The following are the same map:

type Map = BTreeMap<char, char>;
println!("{:?}", bincode::deserialize::<Map>(b"\x02\0\0\0\0\0\0\0a0b1"));
println!("{:?}", bincode::deserialize::<Map>(b"\x02\0\0\0\0\0\0\0b1a0"));

I filed #193 to follow up on how to deal with trailing bytes. For now you can detect them yourself:

let mut data: &[u8] = /* ... */;
let value: T = bincode::deserialize_from(&mut data, Infinite)?;
if !data.is_empty() {
    bail!("trailing data: {:?}", data);
}
@chrisdew
Copy link
Author

@chrisdew chrisdew commented Jul 7, 2017

@dtolnay I only need to serialise basic types (integers and byte arrays) so it looks like bincode is what I need.

Many thanks for your help.

@chrisdew chrisdew closed this Jul 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.