From bfbaeaacd19b00233c05af9b030933434695f700 Mon Sep 17 00:00:00 2001 From: TyOverby Date: Mon, 5 Jan 2015 11:19:08 -0800 Subject: [PATCH] added size-limits to all functions. Currently the size limits aren't actually enforced. --- README.md | 6 ++++-- examples/basic.rs | 6 ++++-- examples/file.rs | 6 ++++-- src/lib.rs | 26 ++++++++++++++++++-------- src/reader.rs | 11 ++++++++--- src/test.rs | 14 +++++++++----- src/writer.rs | 15 +++++++++++---- 7 files changed, 58 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index f9b2ba8..4d446ae 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ library. extern crate bincode; extern crate "rustc-serialize" as rustc_serialize; +use bincode::SizeLimit; + #[derive(RustcEncodable, RustcDecodable, PartialEq)] struct Entity { x: f32, @@ -38,10 +40,10 @@ fn main() { entities: vec![Entity {x: 0.0, y: 4.0}, Entity {x: 10.0, y: 20.5}] }; - let encoded: Vec = bincode::encode(&world).unwrap(); + let encoded: Vec = bincode::encode(&world, SizeLimit::Infinite).unwrap(); // 8 bytes for the length of the vector, 4 bytes per float. assert_eq!(encoded.len(), 8 + 4 * 4); - let decoded: World = bincode::decode(encoded).unwrap(); + let decoded: World = bincode::decode(encoded, SizeLimit::Infinite).unwrap(); assert!(world == decoded); } diff --git a/examples/basic.rs b/examples/basic.rs index d9ef5d1..436e50c 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -3,6 +3,8 @@ extern crate bincode; extern crate "rustc-serialize" as rustc_serialize; +use bincode::SizeLimit; + #[derive(RustcEncodable, RustcDecodable, PartialEq)] struct Entity { x: f32, @@ -19,10 +21,10 @@ fn main() { entities: vec![Entity {x: 0.0, y: 4.0}, Entity {x: 10.0, y: 20.5}] }; - let encoded: Vec = bincode::encode(&world).unwrap(); + let encoded: Vec = bincode::encode(&world, SizeLimit::Infinite).unwrap(); // 8 bytes for the length of the vector, 4 bytes per float. assert_eq!(encoded.len(), 8 + 4 * 4); - let decoded: World = bincode::decode(encoded).unwrap(); + let decoded: World = bincode::decode(encoded, SizeLimit::Infinite).unwrap(); assert!(world == decoded); } diff --git a/examples/file.rs b/examples/file.rs index 08bb50e..65e26bd 100644 --- a/examples/file.rs +++ b/examples/file.rs @@ -4,6 +4,8 @@ extern crate serialize; use std::collections::HashMap; use std::io::{Truncate, ReadWrite, File, BufferedReader}; +use bincode::SizeLimit; + fn main() { let mut word_counts = HashMap::new(); word_counts.insert("foo".to_string(), 3u); @@ -11,11 +13,11 @@ fn main() { let file = File::open_mode(&Path::new("store.bin"), Truncate, ReadWrite); let mut file = file.unwrap(); - bincode::encode_into(&word_counts, &mut file).unwrap(); + bincode::encode_into(&word_counts, &mut file, SizeLimit::Infinite).unwrap(); file.fsync().unwrap(); let out: HashMap = - bincode::decode_from(&mut BufferedReader::new(file)).unwrap(); + bincode::decode_from(&mut BufferedReader::new(file), SizeLimit::Infinite).unwrap(); assert!(out == word_counts); } diff --git a/src/lib.rs b/src/lib.rs index d6d298d..4b150a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,32 +19,42 @@ pub use reader::DecoderReader; mod writer; mod reader; -pub fn encode<'a, T: Encodable, IoError>>(t: &T) ->IoResult> { +#[derive(Clone, Copy)] +pub enum SizeLimit { + Infinite, + UpperBound(u64) +} + +pub fn encode<'a, T>(t: &T, size_limit: SizeLimit) -> IoResult> +where T: Encodable, IoError> { let mut w = MemWriter::new(); - match encode_into(t, &mut w) { + match encode_into(t, &mut w, size_limit) { Ok(()) => Ok(w.into_inner()), Err(e) => Err(e) } } -pub fn decode<'a, T: Decodable, IoError>>(b: Vec) -> IoResult { - decode_from(&mut MemReader::new(b)) +pub fn decode<'a, T>(b: Vec, size_limit: SizeLimit) -> IoResult +where T: Decodable, IoError> { + decode_from(&mut MemReader::new(b), size_limit) } // In order to be able to pass MemReaders/MemWriters by reference, I borrowed the method used in // the current json encoder in the stdlib // TODO: Make code safe https://github.com/rust-lang/rust/issues/14302 -pub fn encode_into<'a, W: 'a+Writer, T: Encodable, IoError>>(t: &T, w: &mut W) -> IoResult<()> { +pub fn encode_into<'a, W, T>(t: &T, w: &mut W, size_limit: SizeLimit) -> IoResult<()> +where W: 'a + Writer, T: Encodable, IoError>{ unsafe { - t.encode(std::mem::transmute(&mut writer::EncoderWriter::new(w))) + t.encode(std::mem::transmute(&mut writer::EncoderWriter::new(w, size_limit))) } } // TODO: Make code safe https://github.com/rust-lang/rust/issues/14302 -pub fn decode_from<'a, R: 'a+Reader+Buffer, T: Decodable, IoError>>(r: &mut R) -> IoResult { +pub fn decode_from<'a, R, T>(r: &mut R, size_limit: SizeLimit) -> IoResult +where R: 'a + Reader + Buffer, T: Decodable, IoError>{ unsafe { - Decodable::decode(std::mem::transmute(&mut reader::DecoderReader::new(r))) + Decodable::decode(std::mem::transmute(&mut reader::DecoderReader::new(r, size_limit))) } } diff --git a/src/reader.rs b/src/reader.rs index 198940e..09b8523 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -1,14 +1,19 @@ use std::io::{Buffer, Reader, IoError, IoResult, OtherIoError}; + use rustc_serialize::Decoder; +use super::SizeLimit; + pub struct DecoderReader<'a, R: 'a> { - reader: &'a mut R + reader: &'a mut R, + size_limit: SizeLimit } impl<'a, R: Reader+Buffer> DecoderReader<'a, R> { - pub fn new(r: &'a mut R) -> DecoderReader<'a, R> { + pub fn new(r: &'a mut R, size_limit: SizeLimit) -> DecoderReader<'a, R> { DecoderReader { - reader: r + reader: r, + size_limit: size_limit } } } diff --git a/src/test.rs b/src/test.rs index 1ec6d73..884907c 100644 --- a/src/test.rs +++ b/src/test.rs @@ -13,16 +13,20 @@ use rustc_serialize::{ Decodable }; -use super::EncoderWriter; -use super::DecoderReader; -use super::encode; -use super::decode; +use super::{ + EncoderWriter, + DecoderReader, + encode, + decode, + SizeLimit +}; +use super::SizeLimit::Infinite; fn the_same<'a, V: Encodable, IoError> + Decodable, IoError> + PartialEq + Show>(element: V) { - assert!(element == decode(encode(&element).unwrap()).unwrap()); + assert!(element == decode(encode(&element, Infinite).unwrap(), Infinite).unwrap()); } #[test] diff --git a/src/writer.rs b/src/writer.rs index 2e0bba3..df7c8ad 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -1,16 +1,23 @@ use std::io::{Writer, IoError, IoResult}; -use rustc_serialize::Encoder; use std::num::Int; +use rustc_serialize::Encoder; + +use super::SizeLimit; + type EwResult = IoResult<()>; pub struct EncoderWriter<'a, W: 'a> { - writer: &'a mut W + writer: &'a mut W, + size_limit: SizeLimit } impl <'a, W: Writer> EncoderWriter<'a, W> { - pub fn new(w: &'a mut W) -> EncoderWriter<'a, W> { - EncoderWriter{ writer: w } + pub fn new(w: &'a mut W, size_limit: SizeLimit) -> EncoderWriter<'a, W> { + EncoderWriter { + writer: w, + size_limit: size_limit + } } }