1 //! `bincode` uses a Builder-pattern to configure the Serializers and Deserializers in this 2 //! crate. This means that if you need to customize the behavior of `bincode`, you should create an 3 //! instance of the `DefaultOptions` struct: 4 //! 5 //! ```rust 6 //! use bincode::Options; 7 //! let my_options = bincode::DefaultOptions::new(); 8 //! ``` 9 //! 10 //! # Options Struct vs bincode functions 11 //! 12 //! Due to historical reasons, the default options used by the `serialize()` and `deserialize()` 13 //! family of functions are different than the default options created by the `DefaultOptions` struct: 14 //! 15 //! | | Byte limit | Endianness | Int Encoding | Trailing Behavior | 16 //! |----------|------------|------------|--------------|-------------------| 17 //! | struct | Unlimited | Little | Varint | Reject | 18 //! | function | Unlimited | Little | Fixint | Allow | 19 //! 20 //! This means that if you want to use the `Serialize` / `Deserialize` structs with the same 21 //! settings as the functions, you should adjust the `DefaultOptions` struct like so: 22 //! 23 //! ```rust 24 //! use bincode::Options; 25 //! let my_options = bincode::DefaultOptions::new() 26 //! .with_fixint_encoding() 27 //! .allow_trailing_bytes(); 28 //! ``` 29 30 use de::read::BincodeRead; 31 use error::Result; 32 use serde; 33 use std::io::{Read, Write}; 34 use std::marker::PhantomData; 35 36 pub(crate) use self::endian::BincodeByteOrder; 37 pub(crate) use self::int::IntEncoding; 38 pub(crate) use self::internal::*; 39 pub(crate) use self::limit::SizeLimit; 40 pub(crate) use self::trailing::TrailingBytes; 41 42 pub use self::endian::{BigEndian, LittleEndian, NativeEndian}; 43 pub use self::int::{FixintEncoding, VarintEncoding}; 44 pub use self::legacy::*; 45 pub use self::limit::{Bounded, Infinite}; 46 pub use self::trailing::{AllowTrailing, RejectTrailing}; 47 48 mod endian; 49 mod int; 50 mod legacy; 51 mod limit; 52 mod trailing; 53 54 /// The default options for bincode serialization/deserialization. 55 /// 56 /// ### Defaults 57 /// By default bincode will use little-endian encoding for multi-byte integers, and will not 58 /// limit the number of serialized/deserialized bytes. 59 /// 60 /// ### Configuring `DefaultOptions` 61 /// 62 /// `DefaultOptions` implements the [Options] trait, which means it exposes functions to change the behavior of bincode. 63 /// 64 /// For example, if you wanted to limit the bincode deserializer to 1 kilobyte of user input: 65 /// 66 /// ```rust 67 /// use bincode::Options; 68 /// let my_options = bincode::DefaultOptions::new().with_limit(1024); 69 /// ``` 70 /// 71 /// ### DefaultOptions struct vs. functions 72 /// 73 /// The default configuration used by this struct is not the same as that used by the bincode 74 /// helper functions in the root of this crate. See the 75 /// [config](index.html#options-struct-vs-bincode-functions) module for more details 76 #[derive(Copy, Clone)] 77 pub struct DefaultOptions(Infinite); 78 79 impl DefaultOptions { 80 /// Get a default configuration object. 81 /// 82 /// ### Default Configuration: 83 /// 84 /// | Byte limit | Endianness | Int Encoding | Trailing Behavior | 85 /// |------------|------------|--------------|-------------------| 86 /// | Unlimited | Little | Varint | Reject | new() -> DefaultOptions87 pub fn new() -> DefaultOptions { 88 DefaultOptions(Infinite) 89 } 90 } 91 92 impl Default for DefaultOptions { default() -> Self93 fn default() -> Self { 94 Self::new() 95 } 96 } 97 98 impl InternalOptions for DefaultOptions { 99 type Limit = Infinite; 100 type Endian = LittleEndian; 101 type IntEncoding = VarintEncoding; 102 type Trailing = RejectTrailing; 103 104 #[inline(always)] limit(&mut self) -> &mut Infinite105 fn limit(&mut self) -> &mut Infinite { 106 &mut self.0 107 } 108 } 109 110 /// A configuration builder trait whose options Bincode will use 111 /// while serializing and deserializing. 112 /// 113 /// ### Options 114 /// Endianness: The endianness with which multi-byte integers will be read/written. *default: little endian* 115 /// 116 /// Limit: The maximum number of bytes that will be read/written in a bincode serialize/deserialize. *default: unlimited* 117 /// 118 /// Int Encoding: The encoding used for numbers, enum discriminants, and lengths. *default: varint* 119 /// 120 /// Trailing Behavior: The behavior when there are trailing bytes left over in a slice after deserialization. *default: reject* 121 /// 122 /// ### Byte Limit Details 123 /// The purpose of byte-limiting is to prevent Denial-Of-Service attacks whereby malicious attackers get bincode 124 /// deserialization to crash your process by allocating too much memory or keeping a connection open for too long. 125 /// 126 /// When a byte limit is set, bincode will return `Err` on any deserialization that goes over the limit, or any 127 /// serialization that goes over the limit. 128 pub trait Options: InternalOptions + Sized { 129 /// Sets the byte limit to be unlimited. 130 /// This is the default. with_no_limit(self) -> WithOtherLimit<Self, Infinite>131 fn with_no_limit(self) -> WithOtherLimit<Self, Infinite> { 132 WithOtherLimit::new(self, Infinite) 133 } 134 135 /// Sets the byte limit to `limit`. with_limit(self, limit: u64) -> WithOtherLimit<Self, Bounded>136 fn with_limit(self, limit: u64) -> WithOtherLimit<Self, Bounded> { 137 WithOtherLimit::new(self, Bounded(limit)) 138 } 139 140 /// Sets the endianness to little-endian 141 /// This is the default. with_little_endian(self) -> WithOtherEndian<Self, LittleEndian>142 fn with_little_endian(self) -> WithOtherEndian<Self, LittleEndian> { 143 WithOtherEndian::new(self) 144 } 145 146 /// Sets the endianness to big-endian with_big_endian(self) -> WithOtherEndian<Self, BigEndian>147 fn with_big_endian(self) -> WithOtherEndian<Self, BigEndian> { 148 WithOtherEndian::new(self) 149 } 150 151 /// Sets the endianness to the the machine-native endianness with_native_endian(self) -> WithOtherEndian<Self, NativeEndian>152 fn with_native_endian(self) -> WithOtherEndian<Self, NativeEndian> { 153 WithOtherEndian::new(self) 154 } 155 156 /// Sets the length encoding to varint with_varint_encoding(self) -> WithOtherIntEncoding<Self, VarintEncoding>157 fn with_varint_encoding(self) -> WithOtherIntEncoding<Self, VarintEncoding> { 158 WithOtherIntEncoding::new(self) 159 } 160 161 /// Sets the length encoding to be fixed with_fixint_encoding(self) -> WithOtherIntEncoding<Self, FixintEncoding>162 fn with_fixint_encoding(self) -> WithOtherIntEncoding<Self, FixintEncoding> { 163 WithOtherIntEncoding::new(self) 164 } 165 166 /// Sets the deserializer to reject trailing bytes reject_trailing_bytes(self) -> WithOtherTrailing<Self, RejectTrailing>167 fn reject_trailing_bytes(self) -> WithOtherTrailing<Self, RejectTrailing> { 168 WithOtherTrailing::new(self) 169 } 170 171 /// Sets the deserializer to allow trailing bytes allow_trailing_bytes(self) -> WithOtherTrailing<Self, AllowTrailing>172 fn allow_trailing_bytes(self) -> WithOtherTrailing<Self, AllowTrailing> { 173 WithOtherTrailing::new(self) 174 } 175 176 /// Serializes a serializable object into a `Vec` of bytes using this configuration 177 #[inline(always)] serialize<S: ?Sized + serde::Serialize>(self, t: &S) -> Result<Vec<u8>>178 fn serialize<S: ?Sized + serde::Serialize>(self, t: &S) -> Result<Vec<u8>> { 179 ::internal::serialize(t, self) 180 } 181 182 /// Returns the size that an object would be if serialized using Bincode with this configuration 183 #[inline(always)] serialized_size<T: ?Sized + serde::Serialize>(self, t: &T) -> Result<u64>184 fn serialized_size<T: ?Sized + serde::Serialize>(self, t: &T) -> Result<u64> { 185 ::internal::serialized_size(t, self) 186 } 187 188 /// Serializes an object directly into a `Writer` using this configuration 189 /// 190 /// If the serialization would take more bytes than allowed by the size limit, an error 191 /// is returned and *no bytes* will be written into the `Writer` 192 #[inline(always)] serialize_into<W: Write, T: ?Sized + serde::Serialize>(self, w: W, t: &T) -> Result<()>193 fn serialize_into<W: Write, T: ?Sized + serde::Serialize>(self, w: W, t: &T) -> Result<()> { 194 ::internal::serialize_into(w, t, self) 195 } 196 197 /// Deserializes a slice of bytes into an instance of `T` using this configuration 198 #[inline(always)] deserialize<'a, T: serde::Deserialize<'a>>(self, bytes: &'a [u8]) -> Result<T>199 fn deserialize<'a, T: serde::Deserialize<'a>>(self, bytes: &'a [u8]) -> Result<T> { 200 ::internal::deserialize(bytes, self) 201 } 202 203 /// TODO: document 204 #[doc(hidden)] 205 #[inline(always)] deserialize_in_place<'a, R, T>(self, reader: R, place: &mut T) -> Result<()> where R: BincodeRead<'a>, T: serde::de::Deserialize<'a>,206 fn deserialize_in_place<'a, R, T>(self, reader: R, place: &mut T) -> Result<()> 207 where 208 R: BincodeRead<'a>, 209 T: serde::de::Deserialize<'a>, 210 { 211 ::internal::deserialize_in_place(reader, self, place) 212 } 213 214 /// Deserializes a slice of bytes with state `seed` using this configuration. 215 #[inline(always)] deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>( self, seed: T, bytes: &'a [u8], ) -> Result<T::Value>216 fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>( 217 self, 218 seed: T, 219 bytes: &'a [u8], 220 ) -> Result<T::Value> { 221 ::internal::deserialize_seed(seed, bytes, self) 222 } 223 224 /// Deserializes an object directly from a `Read`er using this configuration 225 /// 226 /// If this returns an `Error`, `reader` may be in an invalid state. 227 #[inline(always)] deserialize_from<R: Read, T: serde::de::DeserializeOwned>(self, reader: R) -> Result<T>228 fn deserialize_from<R: Read, T: serde::de::DeserializeOwned>(self, reader: R) -> Result<T> { 229 ::internal::deserialize_from(reader, self) 230 } 231 232 /// Deserializes an object directly from a `Read`er with state `seed` using this configuration 233 /// 234 /// If this returns an `Error`, `reader` may be in an invalid state. 235 #[inline(always)] deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>( self, seed: T, reader: R, ) -> Result<T::Value>236 fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>( 237 self, 238 seed: T, 239 reader: R, 240 ) -> Result<T::Value> { 241 ::internal::deserialize_from_seed(seed, reader, self) 242 } 243 244 /// Deserializes an object from a custom `BincodeRead`er using the default configuration. 245 /// It is highly recommended to use `deserialize_from` unless you need to implement 246 /// `BincodeRead` for performance reasons. 247 /// 248 /// If this returns an `Error`, `reader` may be in an invalid state. 249 #[inline(always)] deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>( self, reader: R, ) -> Result<T>250 fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>( 251 self, 252 reader: R, 253 ) -> Result<T> { 254 ::internal::deserialize_from_custom(reader, self) 255 } 256 257 /// Deserializes an object from a custom `BincodeRead`er with state `seed` using the default 258 /// configuration. It is highly recommended to use `deserialize_from` unless you need to 259 /// implement `BincodeRead` for performance reasons. 260 /// 261 /// If this returns an `Error`, `reader` may be in an invalid state. 262 #[inline(always)] deserialize_from_custom_seed<'a, R: BincodeRead<'a>, T: serde::de::DeserializeSeed<'a>>( self, seed: T, reader: R, ) -> Result<T::Value>263 fn deserialize_from_custom_seed<'a, R: BincodeRead<'a>, T: serde::de::DeserializeSeed<'a>>( 264 self, 265 seed: T, 266 reader: R, 267 ) -> Result<T::Value> { 268 ::internal::deserialize_from_custom_seed(seed, reader, self) 269 } 270 } 271 272 impl<T: InternalOptions> Options for T {} 273 274 /// A configuration struct with a user-specified byte limit 275 #[derive(Clone, Copy)] 276 pub struct WithOtherLimit<O: Options, L: SizeLimit> { 277 _options: O, 278 pub(crate) new_limit: L, 279 } 280 281 /// A configuration struct with a user-specified endian order 282 #[derive(Clone, Copy)] 283 pub struct WithOtherEndian<O: Options, E: BincodeByteOrder> { 284 options: O, 285 _endian: PhantomData<E>, 286 } 287 288 /// A configuration struct with a user-specified length encoding 289 #[derive(Clone, Copy)] 290 pub struct WithOtherIntEncoding<O: Options, I: IntEncoding> { 291 options: O, 292 _length: PhantomData<I>, 293 } 294 295 /// A configuration struct with a user-specified trailing bytes behavior. 296 #[derive(Clone, Copy)] 297 pub struct WithOtherTrailing<O: Options, T: TrailingBytes> { 298 options: O, 299 _trailing: PhantomData<T>, 300 } 301 302 impl<O: Options, L: SizeLimit> WithOtherLimit<O, L> { 303 #[inline(always)] new(options: O, limit: L) -> WithOtherLimit<O, L>304 pub(crate) fn new(options: O, limit: L) -> WithOtherLimit<O, L> { 305 WithOtherLimit { 306 _options: options, 307 new_limit: limit, 308 } 309 } 310 } 311 312 impl<O: Options, E: BincodeByteOrder> WithOtherEndian<O, E> { 313 #[inline(always)] new(options: O) -> WithOtherEndian<O, E>314 pub(crate) fn new(options: O) -> WithOtherEndian<O, E> { 315 WithOtherEndian { 316 options, 317 _endian: PhantomData, 318 } 319 } 320 } 321 322 impl<O: Options, I: IntEncoding> WithOtherIntEncoding<O, I> { 323 #[inline(always)] new(options: O) -> WithOtherIntEncoding<O, I>324 pub(crate) fn new(options: O) -> WithOtherIntEncoding<O, I> { 325 WithOtherIntEncoding { 326 options, 327 _length: PhantomData, 328 } 329 } 330 } 331 332 impl<O: Options, T: TrailingBytes> WithOtherTrailing<O, T> { 333 #[inline(always)] new(options: O) -> WithOtherTrailing<O, T>334 pub(crate) fn new(options: O) -> WithOtherTrailing<O, T> { 335 WithOtherTrailing { 336 options, 337 _trailing: PhantomData, 338 } 339 } 340 } 341 342 impl<O: Options, E: BincodeByteOrder + 'static> InternalOptions for WithOtherEndian<O, E> { 343 type Limit = O::Limit; 344 type Endian = E; 345 type IntEncoding = O::IntEncoding; 346 type Trailing = O::Trailing; 347 #[inline(always)] limit(&mut self) -> &mut O::Limit348 fn limit(&mut self) -> &mut O::Limit { 349 self.options.limit() 350 } 351 } 352 353 impl<O: Options, L: SizeLimit + 'static> InternalOptions for WithOtherLimit<O, L> { 354 type Limit = L; 355 type Endian = O::Endian; 356 type IntEncoding = O::IntEncoding; 357 type Trailing = O::Trailing; limit(&mut self) -> &mut L358 fn limit(&mut self) -> &mut L { 359 &mut self.new_limit 360 } 361 } 362 363 impl<O: Options, I: IntEncoding + 'static> InternalOptions for WithOtherIntEncoding<O, I> { 364 type Limit = O::Limit; 365 type Endian = O::Endian; 366 type IntEncoding = I; 367 type Trailing = O::Trailing; 368 limit(&mut self) -> &mut O::Limit369 fn limit(&mut self) -> &mut O::Limit { 370 self.options.limit() 371 } 372 } 373 374 impl<O: Options, T: TrailingBytes + 'static> InternalOptions for WithOtherTrailing<O, T> { 375 type Limit = O::Limit; 376 type Endian = O::Endian; 377 type IntEncoding = O::IntEncoding; 378 type Trailing = T; 379 limit(&mut self) -> &mut O::Limit380 fn limit(&mut self) -> &mut O::Limit { 381 self.options.limit() 382 } 383 } 384 385 mod internal { 386 use super::*; 387 388 pub trait InternalOptions { 389 type Limit: SizeLimit + 'static; 390 type Endian: BincodeByteOrder + 'static; 391 type IntEncoding: IntEncoding + 'static; 392 type Trailing: TrailingBytes + 'static; 393 limit(&mut self) -> &mut Self::Limit394 fn limit(&mut self) -> &mut Self::Limit; 395 } 396 397 impl<'a, O: InternalOptions> InternalOptions for &'a mut O { 398 type Limit = O::Limit; 399 type Endian = O::Endian; 400 type IntEncoding = O::IntEncoding; 401 type Trailing = O::Trailing; 402 403 #[inline(always)] limit(&mut self) -> &mut Self::Limit404 fn limit(&mut self) -> &mut Self::Limit { 405 (*self).limit() 406 } 407 } 408 } 409