-
-
Save koivunej/68321c230287f95f88816c278d721d16 to your computer and use it in GitHub Desktop.
Test case for bad decode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate quick_protobuf; | |
// enum OperationResult | |
// { | |
// Success = 0; | |
// PrepareTimeout = 1; | |
// CommitTimeout = 2; | |
// ForwardTimeout = 3; | |
// WrongExpectedVersion = 4; | |
// StreamDeleted = 5; | |
// InvalidTransaction = 6; | |
// AccessDenied = 7; | |
// } | |
// | |
// message WriteEventsCompleted { | |
// required OperationResult result = 1; | |
// optional string message = 2; | |
// required int32 first_event_number = 3; | |
// required int32 last_event_number = 4; | |
// optional int64 prepare_position = 5; | |
// optional int64 commit_position = 6; | |
// } | |
mod messages { | |
use std::io::Write; | |
use std::borrow::Cow; | |
use quick_protobuf::{MessageWrite, BytesReader, Writer, Result}; | |
use quick_protobuf::sizeofs::*; | |
#[derive(Debug, PartialEq, Eq, Clone, Copy)] | |
pub enum OperationResult { | |
Success = 0, | |
PrepareTimeout = 1, | |
CommitTimeout = 2, | |
ForwardTimeout = 3, | |
WrongExpectedVersion = 4, | |
StreamDeleted = 5, | |
InvalidTransaction = 6, | |
AccessDenied = 7, | |
} | |
impl Default for OperationResult { | |
fn default() -> Self { | |
OperationResult::Success | |
} | |
} | |
impl From<i32> for OperationResult { | |
fn from(i: i32) -> Self { | |
match i { | |
0 => OperationResult::Success, | |
1 => OperationResult::PrepareTimeout, | |
2 => OperationResult::CommitTimeout, | |
3 => OperationResult::ForwardTimeout, | |
4 => OperationResult::WrongExpectedVersion, | |
5 => OperationResult::StreamDeleted, | |
6 => OperationResult::InvalidTransaction, | |
7 => OperationResult::AccessDenied, | |
_ => Self::default(), | |
} | |
} | |
} | |
#[derive(Debug, Default, PartialEq, Clone)] | |
pub struct WriteEventsCompleted<'a> { | |
pub result: Option<OperationResult>, | |
pub message: Option<Cow<'a, str>>, | |
pub first_event_number: i32, | |
pub last_event_number: i32, | |
pub prepare_position: Option<i64>, | |
pub commit_position: Option<i64>, | |
} | |
impl<'a> WriteEventsCompleted<'a> { | |
pub fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result<Self> { | |
let mut msg = Self::default(); | |
while !r.is_eof() { | |
match r.next_tag(bytes) { | |
Ok(8) => msg.result = Some(r.read_enum(bytes)?), | |
Ok(18) => msg.message = Some(r.read_string(bytes).map(Cow::Borrowed)?), | |
Ok(24) => msg.first_event_number = r.read_int32(bytes)?, | |
Ok(32) => msg.last_event_number = r.read_int32(bytes)?, | |
Ok(40) => msg.prepare_position = Some(r.read_int64(bytes)?), | |
Ok(48) => msg.commit_position = Some(r.read_int64(bytes)?), | |
Ok(t) => { | |
r.read_unknown(bytes, t)?; | |
} | |
Err(e) => return Err(e), | |
} | |
} | |
Ok(msg) | |
} | |
} | |
impl<'a> MessageWrite for WriteEventsCompleted<'a> { | |
fn get_size(&self) -> usize { | |
0 + self.result.as_ref().map_or(0, |m| 1 + sizeof_varint(*(m) as u64)) + | |
self.message.as_ref().map_or(0, |m| 1 + sizeof_len((m).len())) + | |
1 + sizeof_varint(*(&self.first_event_number) as u64) + 1 + | |
sizeof_varint(*(&self.last_event_number) as u64) + | |
self.prepare_position.as_ref().map_or(0, |m| 1 + sizeof_varint(*(m) as u64)) + | |
self.commit_position.as_ref().map_or(0, |m| 1 + sizeof_varint(*(m) as u64)) | |
} | |
fn write_message<W: Write>(&self, w: &mut Writer<W>) -> Result<()> { | |
if let Some(ref s) = self.result { | |
w.write_with_tag(8, |w| w.write_enum(*s as i32))?; | |
} | |
if let Some(ref s) = self.message { | |
w.write_with_tag(18, |w| w.write_string(&**s))?; | |
} | |
w.write_with_tag(24, |w| w.write_int32(*&self.first_event_number))?; | |
w.write_with_tag(32, |w| w.write_int32(*&self.last_event_number))?; | |
if let Some(ref s) = self.prepare_position { | |
w.write_with_tag(40, |w| w.write_int64(*s))?; | |
} | |
if let Some(ref s) = self.commit_position { | |
w.write_with_tag(48, |w| w.write_int64(*s))?; | |
} | |
Ok(()) | |
} | |
} | |
} | |
use messages::*; | |
#[test] | |
fn test_decoding_example() { | |
let input = vec![8u8, 0, 24, 30, 32, 39, 40, 132, 214, 188, 86, 48, 132, 214, 188, 86]; | |
let mut reader = ::quick_protobuf::reader::BytesReader::from_bytes(&input); | |
let actual = reader.read_message(&input, WriteEventsCompleted::from_reader).unwrap(); | |
assert_eq!(actual, WriteEventsCompleted { | |
result: Some(OperationResult::Success), | |
message: None, | |
first_event_number: 30, | |
last_event_number: 39, | |
prepare_position: Some(181349124), | |
commit_position: Some(181349124) | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment