1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
//! A collection of serialization and deserialization functions
//! that use the `serde` crate for the serializable and deserializable
//! implementation.

use std::io::{self, Write, Read};
use std::{error, fmt, result};
use std::str::Utf8Error;
use {CountSize, SizeLimit};
use byteorder::ByteOrder;
use std::error::Error as StdError;

pub use super::de::Deserializer;

pub use super::ser::Serializer;

use super::ser::SizeChecker;

use serde_crate as serde;

/// The result of a serialization or deserialization operation.
pub type Result<T> = result::Result<T, Error>;

/// An error that can be produced during (de)serializing.
pub type Error = Box<ErrorKind>;

/// The kind of error that can be produced during a serialization or deserialization.
#[derive(Debug)]
pub enum ErrorKind {
    /// If the error stems from the reader/writer that is being used
    /// during (de)serialization, that error will be stored and returned here.
    Io(io::Error),
    /// Returned if the deserializer attempts to deserialize a string that is not valid utf8
    InvalidUtf8Encoding(Utf8Error),
    /// Returned if the deserializer attempts to deserialize a bool that was
    /// not encoded as either a 1 or a 0
    InvalidBoolEncoding(u8),
    /// Returned if the deserializer attempts to deserialize a char that is not in the correct format.
    InvalidCharEncoding,
    /// Returned if the deserializer attempts to deserialize the tag of an enum that is
    /// not in the expected ranges
    InvalidTagEncoding(usize),
    /// Serde has a deserialize_any method that lets the format hint to the
    /// object which route to take in deserializing.
    DeserializeAnyNotSupported,
    /// If (de)serializing a message takes more than the provided size limit, this
    /// error is returned.
    SizeLimit,
    /// Bincode can not encode sequences of unknown length (like iterators).
    SequenceMustHaveLength,
    /// A custom error message from Serde.
    Custom(String),
}

impl StdError for ErrorKind {
    fn description(&self) -> &str {
        match *self {
            ErrorKind::Io(ref err) => error::Error::description(err),
            ErrorKind::InvalidUtf8Encoding(_) => "string is not valid utf8",
            ErrorKind::InvalidBoolEncoding(_) => "invalid u8 while decoding bool",
            ErrorKind::InvalidCharEncoding => "char is not valid",
            ErrorKind::InvalidTagEncoding(_) => "tag for enum is not valid",
            ErrorKind::SequenceMustHaveLength => "bincode can't encode infinite sequences",
            ErrorKind::DeserializeAnyNotSupported => {
                "bincode doesn't support serde::Deserializer::deserialize_any"
            }
            ErrorKind::SizeLimit => "the size limit for decoding has been reached",
            ErrorKind::Custom(ref msg) => msg,

        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            ErrorKind::Io(ref err) => Some(err),
            ErrorKind::InvalidUtf8Encoding(_) => None,
            ErrorKind::InvalidBoolEncoding(_) => None,
            ErrorKind::InvalidCharEncoding => None,
            ErrorKind::InvalidTagEncoding(_) => None,
            ErrorKind::SequenceMustHaveLength => None,
            ErrorKind::DeserializeAnyNotSupported => None,
            ErrorKind::SizeLimit => None,
            ErrorKind::Custom(_) => None,
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        ErrorKind::Io(err).into()
    }
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ErrorKind::Io(ref ioerr) => write!(fmt, "io error: {}", ioerr),
            ErrorKind::InvalidUtf8Encoding(ref e) => write!(fmt, "{}: {}", self.description(), e),
            ErrorKind::InvalidBoolEncoding(b) => {
                write!(fmt, "{}, expected 0 or 1, found {}", self.description(), b)
            }
            ErrorKind::InvalidCharEncoding => write!(fmt, "{}", self.description()),
            ErrorKind::InvalidTagEncoding(tag) => {
                write!(fmt, "{}, found {}", self.description(), tag)
            }
            ErrorKind::SequenceMustHaveLength => {
                write!(
                    fmt,
                    "bincode can only encode sequences and maps that have a knowable size ahead of time."
                )
            }
            ErrorKind::SizeLimit => write!(fmt, "{}", self.description()),
            ErrorKind::DeserializeAnyNotSupported => {
                write!(
                    fmt,
                    "bincode does not support the serde::Deserializer::deserialize_any method"
                )
            }
            ErrorKind::Custom(ref s) => s.fmt(fmt),
        }
    }
}

impl serde::de::Error for Error {
    fn custom<T: fmt::Display>(desc: T) -> Error {
        ErrorKind::Custom(desc.to_string()).into()
    }
}

impl serde::ser::Error for Error {
    fn custom<T: fmt::Display>(msg: T) -> Self {
        ErrorKind::Custom(msg.to_string()).into()
    }
}

/// Serializes an object directly into a `Writer`.
///
/// If the serialization would take more bytes than allowed by `size_limit`, an error
/// is returned and *no bytes* will be written into the `Writer`.
///
/// If this returns an `Error` (other than SizeLimit), assume that the
/// writer is in an invalid state, as writing could bail out in the middle of
/// serializing.
pub fn serialize_into<W, T: ?Sized, S, E>(writer: W, value: &T, size_limit: S) -> Result<()>
where
    W: Write,
    T: serde::Serialize,
    S: SizeLimit,
    E: ByteOrder,
{
    if let Some(limit) = size_limit.limit() {
        try!(serialized_size_bounded(value, limit).ok_or(
            ErrorKind::SizeLimit,
        ));
    }

    let mut serializer = Serializer::<_, E>::new(writer);
    serde::Serialize::serialize(value, &mut serializer)
}

/// Serializes a serializable object into a `Vec` of bytes.
///
/// If the serialization would take more bytes than allowed by `size_limit`,
/// an error is returned.
pub fn serialize<T: ?Sized, S, E>(value: &T, size_limit: S) -> Result<Vec<u8>>
where
    T: serde::Serialize,
    S: SizeLimit,
    E: ByteOrder,
{
    let mut writer = match size_limit.limit() {
        Some(size_limit) => {
            let actual_size = try!(serialized_size_bounded(value, size_limit).ok_or(
                ErrorKind::SizeLimit,
            ));
            Vec::with_capacity(actual_size as usize)
        }
        None => {
            let size = serialized_size(value) as usize;
            Vec::with_capacity(size)
        }
    };

    try!(serialize_into::<_, _, _, E>(
        &mut writer,
        value,
        super::Infinite,
    ));
    Ok(writer)
}

impl SizeLimit for CountSize {
    fn add(&mut self, c: u64) -> Result<()> {
        self.total += c;
        if let Some(limit) = self.limit {
            if self.total > limit {
                return Err(Box::new(ErrorKind::SizeLimit));
            }
        }
        Ok(())
    }

    fn limit(&self) -> Option<u64> {
        unreachable!();
    }
}

/// Returns the size that an object would be if serialized using bincode.
///
/// This is used internally as part of the check for encode_into, but it can
/// be useful for preallocating buffers if thats your style.
pub fn serialized_size<T: ?Sized>(value: &T) -> u64
where
    T: serde::Serialize,
{
    let mut size_counter = SizeChecker {
        size_limit: CountSize {
            total: 0,
            limit: None,
        },
    };

    value.serialize(&mut size_counter).ok();
    size_counter.size_limit.total
}

/// Given a maximum size limit, check how large an object would be if it
/// were to be serialized.
///
/// If it can be serialized in `max` or fewer bytes, that number will be returned
/// inside `Some`.  If it goes over bounds, then None is returned.
pub fn serialized_size_bounded<T: ?Sized>(value: &T, max: u64) -> Option<u64>
where
    T: serde::Serialize,
{
    let mut size_counter = SizeChecker {
        size_limit: CountSize {
            total: 0,
            limit: Some(max),
        },
    };

    match value.serialize(&mut size_counter) {
        Ok(_) => Some(size_counter.size_limit.total),
        Err(_) => None,
    }
}

/// Deserializes an object directly from a `Read`er.
///
/// If the provided `SizeLimit` is reached, the deserialization will bail immediately.
/// A SizeLimit can help prevent an attacker from flooding your server with
/// a neverending stream of values that runs your server out of memory.
///
/// If this returns an `Error`, assume that the buffer that you passed
/// in is in an invalid state, as the error could be returned during any point
/// in the reading.
pub fn deserialize_from<R, T, S, E>(reader: R, size_limit: S) -> Result<T>
where
    R: Read,
    T: serde::de::DeserializeOwned,
    S: SizeLimit,
    E: ByteOrder,
{
    let reader = ::de::read::IoReader::new(reader);
    let mut deserializer = Deserializer::<_, S, E>::new(reader, size_limit);
    serde::Deserialize::deserialize(&mut deserializer)
}

/// Deserializes a slice of bytes into an object.
///
/// This method does not have a size-limit because if you already have the bytes
/// in memory, then you don't gain anything by having a limiter.
pub fn deserialize<'a, T, E: ByteOrder>(bytes: &'a [u8]) -> Result<T>
where
    T: serde::de::Deserialize<'a>,
{
    let reader = ::de::read::SliceReader::new(bytes);
    let mut deserializer = Deserializer::<_, _, E>::new(reader, super::Infinite);
    serde::Deserialize::deserialize(&mut deserializer)
}