bincode/config/
legacy.rs

1use std::io::{Read, Write};
2
3use self::EndianOption::*;
4use self::LimitOption::*;
5use super::{DefaultOptions, Options};
6use de::read::BincodeRead;
7use error::Result;
8use serde;
9
10/// A configuration builder whose options Bincode will use
11/// while serializing and deserializing.
12///
13/// ### Options
14/// Endianness: The endianness with which multi-byte integers will be read/written.  *default: little endian*
15/// Limit: The maximum number of bytes that will be read/written in a bincode serialize/deserialize. *default: unlimited*
16///
17/// ### Byte Limit Details
18/// The purpose of byte-limiting is to prevent Denial-Of-Service attacks whereby malicious attackers get bincode
19/// deserialization to crash your process by allocating too much memory or keeping a connection open for too long.
20///
21/// When a byte limit is set, bincode will return `Err` on any deserialization that goes over the limit, or any
22/// serialization that goes over the limit.
23#[derive(Clone, Debug)]
24#[deprecated(
25    since = "1.3.0",
26    note = "please use the `DefaultOptions`/`Options` system instead"
27)]
28pub struct Config {
29    limit: LimitOption,
30    endian: EndianOption,
31}
32
33#[derive(Clone, Copy, Debug)]
34enum LimitOption {
35    Unlimited,
36    Limited(u64),
37}
38
39#[derive(Clone, Copy, Debug)]
40enum EndianOption {
41    Big,
42    Little,
43    Native,
44}
45
46macro_rules! config_map {
47    ($self:expr, $opts:ident => $call:expr) => {
48        match ($self.limit, $self.endian) {
49            (Unlimited, Little) => {
50                let $opts = DefaultOptions::new()
51                    .with_fixint_encoding()
52                    .allow_trailing_bytes()
53                    .with_no_limit()
54                    .with_little_endian();
55                $call
56            }
57            (Unlimited, Big) => {
58                let $opts = DefaultOptions::new()
59                    .with_fixint_encoding()
60                    .allow_trailing_bytes()
61                    .with_no_limit()
62                    .with_big_endian();
63                $call
64            }
65            (Unlimited, Native) => {
66                let $opts = DefaultOptions::new()
67                    .with_fixint_encoding()
68                    .allow_trailing_bytes()
69                    .with_no_limit()
70                    .with_native_endian();
71                $call
72            }
73
74            (Limited(l), Little) => {
75                let $opts = DefaultOptions::new()
76                    .with_fixint_encoding()
77                    .allow_trailing_bytes()
78                    .with_limit(l)
79                    .with_little_endian();
80                $call
81            }
82            (Limited(l), Big) => {
83                let $opts = DefaultOptions::new()
84                    .with_fixint_encoding()
85                    .allow_trailing_bytes()
86                    .with_limit(l)
87                    .with_big_endian();
88                $call
89            }
90            (Limited(l), Native) => {
91                let $opts = DefaultOptions::new()
92                    .with_fixint_encoding()
93                    .allow_trailing_bytes()
94                    .with_limit(l)
95                    .with_native_endian();
96                $call
97            }
98        }
99    };
100}
101
102impl Config {
103    #[inline(always)]
104    pub(crate) fn new() -> Config {
105        Config {
106            limit: LimitOption::Unlimited,
107            endian: EndianOption::Little,
108        }
109    }
110
111    /// Sets the byte limit to be unlimited.
112    /// This is the default.
113    #[inline(always)]
114    pub fn no_limit(&mut self) -> &mut Self {
115        self.limit = LimitOption::Unlimited;
116        self
117    }
118
119    /// Sets the byte limit to `limit`.
120    #[inline(always)]
121    pub fn limit(&mut self, limit: u64) -> &mut Self {
122        self.limit = LimitOption::Limited(limit);
123        self
124    }
125
126    /// Sets the endianness to little-endian
127    /// This is the default.
128    #[inline(always)]
129    pub fn little_endian(&mut self) -> &mut Self {
130        self.endian = EndianOption::Little;
131        self
132    }
133
134    /// Sets the endianness to big-endian
135    #[inline(always)]
136    pub fn big_endian(&mut self) -> &mut Self {
137        self.endian = EndianOption::Big;
138        self
139    }
140
141    /// Sets the endianness to the the machine-native endianness
142    #[inline(always)]
143    pub fn native_endian(&mut self) -> &mut Self {
144        self.endian = EndianOption::Native;
145        self
146    }
147
148    /// Serializes a serializable object into a `Vec` of bytes using this configuration
149    #[inline(always)]
150    pub fn serialize<T: ?Sized + serde::Serialize>(&self, t: &T) -> Result<Vec<u8>> {
151        config_map!(self, opts => ::internal::serialize(t, opts))
152    }
153
154    /// Returns the size that an object would be if serialized using Bincode with this configuration
155    #[inline(always)]
156    pub fn serialized_size<T: ?Sized + serde::Serialize>(&self, t: &T) -> Result<u64> {
157        config_map!(self, opts => ::internal::serialized_size(t, opts))
158    }
159
160    /// Serializes an object directly into a `Writer` using this configuration
161    ///
162    /// If the serialization would take more bytes than allowed by the size limit, an error
163    /// is returned and *no bytes* will be written into the `Writer`
164    #[inline(always)]
165    pub fn serialize_into<W: Write, T: ?Sized + serde::Serialize>(
166        &self,
167        w: W,
168        t: &T,
169    ) -> Result<()> {
170        config_map!(self, opts => ::internal::serialize_into(w, t, opts))
171    }
172
173    /// Deserializes a slice of bytes into an instance of `T` using this configuration
174    #[inline(always)]
175    pub fn deserialize<'a, T: serde::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T> {
176        config_map!(self, opts => ::internal::deserialize(bytes, opts))
177    }
178
179    /// TODO: document
180    #[doc(hidden)]
181    #[inline(always)]
182    pub fn deserialize_in_place<'a, R, T>(&self, reader: R, place: &mut T) -> Result<()>
183    where
184        R: BincodeRead<'a>,
185        T: serde::de::Deserialize<'a>,
186    {
187        config_map!(self, opts => ::internal::deserialize_in_place(reader, opts, place))
188    }
189
190    /// Deserializes a slice of bytes with state `seed` using this configuration.
191    #[inline(always)]
192    pub fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>(
193        &self,
194        seed: T,
195        bytes: &'a [u8],
196    ) -> Result<T::Value> {
197        config_map!(self, opts => ::internal::deserialize_seed(seed, bytes, opts))
198    }
199
200    /// Deserializes an object directly from a `Read`er using this configuration
201    ///
202    /// If this returns an `Error`, `reader` may be in an invalid state.
203    #[inline(always)]
204    pub fn deserialize_from<R: Read, T: serde::de::DeserializeOwned>(
205        &self,
206        reader: R,
207    ) -> Result<T> {
208        config_map!(self, opts => ::internal::deserialize_from(reader, opts))
209    }
210
211    /// Deserializes an object directly from a `Read`er with state `seed` using this configuration
212    ///
213    /// If this returns an `Error`, `reader` may be in an invalid state.
214    #[inline(always)]
215    pub fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>(
216        &self,
217        seed: T,
218        reader: R,
219    ) -> Result<T::Value> {
220        config_map!(self, opts => ::internal::deserialize_from_seed(seed, reader, opts))
221    }
222
223    /// Deserializes an object from a custom `BincodeRead`er using the default configuration.
224    /// It is highly recommended to use `deserialize_from` unless you need to implement
225    /// `BincodeRead` for performance reasons.
226    ///
227    /// If this returns an `Error`, `reader` may be in an invalid state.
228    #[inline(always)]
229    pub fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>(
230        &self,
231        reader: R,
232    ) -> Result<T> {
233        config_map!(self, opts => ::internal::deserialize_from_custom(reader, opts))
234    }
235
236    /// Deserializes an object from a custom `BincodeRead`er with state `seed` using the default
237    /// configuration. It is highly recommended to use `deserialize_from` unless you need to
238    /// implement `BincodeRead` for performance reasons.
239    ///
240    /// If this returns an `Error`, `reader` may be in an invalid state.
241    #[inline(always)]
242    pub fn deserialize_from_custom_seed<
243        'a,
244        R: BincodeRead<'a>,
245        T: serde::de::DeserializeSeed<'a>,
246    >(
247        &self,
248        seed: T,
249        reader: R,
250    ) -> Result<T::Value> {
251        config_map!(self, opts => ::internal::deserialize_from_custom_seed(seed, reader, opts))
252    }
253}