Skip to content

Instantly share code, notes, and snippets.

@borntyping
Created March 17, 2015 17:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save borntyping/ae4b2436b668ebc8e774 to your computer and use it in GitHub Desktop.
Save borntyping/ae4b2436b668ebc8e774 to your computer and use it in GitHub Desktop.
rust-protobuf failing to encode messages with numbers set
[root]
name = "rust-protobuf-repro"
version = "0.0.1"
dependencies = [
"protobuf 0.0.9 (git+https://github.com/stepancheg/rust-protobuf.git)",
]
[[package]]
name = "protobuf"
version = "0.0.9"
source = "git+https://github.com/stepancheg/rust-protobuf.git#1578f31740418e6844dbea3ac2bbef135f648a01"
[package]
name = "rust-protobuf-repro"
version = "0.0.1"
[dependencies.protobuf]
git = "https://github.com/stepancheg/rust-protobuf.git"
Compiling rust-protobuf-repro v0.0.1 (file:///home/sam/Development/borntyping-sandbox/rust-protobuf-repro)
Running target/debug/rust-protobuf-repro-daf18ce99eb33b9f
running 1 test
test test_message_write ... FAILED
failures:
---- test_message_write stdout ----
thread 'test_message_write' panicked at 'Result A {str: "hello world"} -> [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] was the same as result B {num_int64: 64 str: "hello world"} -> [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]', src/main.rs:72
failures:
test_message_write
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
thread '<main>' panicked at 'Some tests failed', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libtest/lib.rs:262
message Example {
optional int64 num_int64 = 1;
optional sint64 num_sint64 = 2;
optional double num_double = 3;
optional float num_float = 4;
optional string str = 5;
}
// This file is generated. Do not edit
#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
#![allow(unused_imports)]
use protobuf::Message as Message_imported_for_functions;
use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
#[derive(Clone,Default)]
pub struct Example {
// message fields
num_int64: ::std::option::Option<i64>,
num_sint64: ::std::option::Option<i64>,
num_double: ::std::option::Option<f64>,
num_float: ::std::option::Option<f32>,
str: ::protobuf::SingularField<::std::string::String>,
// special fields
unknown_fields: ::protobuf::UnknownFields,
cached_size: ::std::cell::Cell<u32>,
}
impl Example {
pub fn new() -> Example {
::std::default::Default::default()
}
pub fn default_instance() -> &'static Example {
static mut instance: ::protobuf::lazy::Lazy<Example> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const Example,
};
unsafe {
instance.get(|| {
Example {
num_int64: ::std::option::Option::None,
num_sint64: ::std::option::Option::None,
num_double: ::std::option::Option::None,
num_float: ::std::option::Option::None,
str: ::protobuf::SingularField::none(),
unknown_fields: ::protobuf::UnknownFields::new(),
cached_size: ::std::cell::Cell::new(0),
}
})
}
}
// optional int64 num_int64 = 1;
pub fn clear_num_int64(&mut self) {
self.num_int64 = ::std::option::Option::None;
}
pub fn has_num_int64(&self) -> bool {
self.num_int64.is_some()
}
// Param is passed by value, moved
pub fn set_num_int64(&mut self, v: i64) {
self.num_int64 = ::std::option::Option::Some(v);
}
pub fn get_num_int64<'a>(&self) -> i64 {
self.num_int64.unwrap_or(0)
}
// optional sint64 num_sint64 = 2;
pub fn clear_num_sint64(&mut self) {
self.num_sint64 = ::std::option::Option::None;
}
pub fn has_num_sint64(&self) -> bool {
self.num_sint64.is_some()
}
// Param is passed by value, moved
pub fn set_num_sint64(&mut self, v: i64) {
self.num_sint64 = ::std::option::Option::Some(v);
}
pub fn get_num_sint64<'a>(&self) -> i64 {
self.num_sint64.unwrap_or(0)
}
// optional double num_double = 3;
pub fn clear_num_double(&mut self) {
self.num_double = ::std::option::Option::None;
}
pub fn has_num_double(&self) -> bool {
self.num_double.is_some()
}
// Param is passed by value, moved
pub fn set_num_double(&mut self, v: f64) {
self.num_double = ::std::option::Option::Some(v);
}
pub fn get_num_double<'a>(&self) -> f64 {
self.num_double.unwrap_or(0.)
}
// optional float num_float = 4;
pub fn clear_num_float(&mut self) {
self.num_float = ::std::option::Option::None;
}
pub fn has_num_float(&self) -> bool {
self.num_float.is_some()
}
// Param is passed by value, moved
pub fn set_num_float(&mut self, v: f32) {
self.num_float = ::std::option::Option::Some(v);
}
pub fn get_num_float<'a>(&self) -> f32 {
self.num_float.unwrap_or(0.)
}
// optional string str = 5;
pub fn clear_str(&mut self) {
self.str.clear();
}
pub fn has_str(&self) -> bool {
self.str.is_some()
}
// Param is passed by value, moved
pub fn set_str(&mut self, v: ::std::string::String) {
self.str = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_str<'a>(&'a mut self) -> &'a mut ::std::string::String {
if self.str.is_none() {
self.str.set_default();
};
self.str.as_mut().unwrap()
}
// Take field
pub fn take_str(&mut self) -> ::std::string::String {
self.str.take().unwrap_or_else(|| ::std::string::String::new())
}
pub fn get_str<'a>(&'a self) -> &'a str {
match self.str.as_ref() {
Some(v) => v.as_slice(),
None => "",
}
}
}
impl ::protobuf::Message for Example {
fn is_initialized(&self) -> bool {
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
while !try!(is.eof()) {
let (field_number, wire_type) = try!(is.read_tag_unpack());
match field_number {
1 => {
if wire_type != ::protobuf::wire_format::WireTypeVarint {
return ::std::result::Result::Err(::protobuf::ProtobufError::WireError("unexpected wire type".to_string()));
};
let tmp = try!(is.read_int64());
self.num_int64 = ::std::option::Option::Some(tmp);
},
2 => {
if wire_type != ::protobuf::wire_format::WireTypeVarint {
return ::std::result::Result::Err(::protobuf::ProtobufError::WireError("unexpected wire type".to_string()));
};
let tmp = try!(is.read_sint64());
self.num_sint64 = ::std::option::Option::Some(tmp);
},
3 => {
if wire_type != ::protobuf::wire_format::WireTypeFixed64 {
return ::std::result::Result::Err(::protobuf::ProtobufError::WireError("unexpected wire type".to_string()));
};
let tmp = try!(is.read_double());
self.num_double = ::std::option::Option::Some(tmp);
},
4 => {
if wire_type != ::protobuf::wire_format::WireTypeFixed32 {
return ::std::result::Result::Err(::protobuf::ProtobufError::WireError("unexpected wire type".to_string()));
};
let tmp = try!(is.read_float());
self.num_float = ::std::option::Option::Some(tmp);
},
5 => {
if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
return ::std::result::Result::Err(::protobuf::ProtobufError::WireError("unexpected wire type".to_string()));
};
let tmp = self.str.set_default();
try!(is.read_string_into(tmp))
},
_ => {
let unknown = try!(is.read_unknown(wire_type));
self.mut_unknown_fields().add_value(field_number, unknown);
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
fn compute_size(&self) -> u32 {
let mut my_size = 0;
for value in self.num_int64.iter() {
my_size += ::protobuf::rt::value_size(1, *value, ::protobuf::wire_format::WireTypeVarint);
};
for value in self.num_sint64.iter() {
my_size += ::protobuf::rt::value_size(2, *value, ::protobuf::wire_format::WireTypeVarint);
};
if self.num_double.is_some() {
my_size += 9;
};
if self.num_float.is_some() {
my_size += 5;
};
for value in self.str.iter() {
my_size += ::protobuf::rt::string_size(5, value.as_slice());
};
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
if let Some(v) = self.num_int64 {
try!(os.write_int64(1, v));
};
if let Some(v) = self.num_sint64 {
try!(os.write_sint64(2, v));
};
if let Some(v) = self.num_double {
try!(os.write_double(3, v));
};
if let Some(v) = self.num_float {
try!(os.write_float(4, v));
};
if let Some(v) = self.str.as_ref() {
try!(os.write_string(5, v.as_slice()));
};
try!(os.write_unknown_fields(self.get_unknown_fields()));
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields<'s>(&'s self) -> &'s ::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields<'s>(&'s mut self) -> &'s mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn type_id(&self) -> ::std::any::TypeId {
::std::any::TypeId::of::<Example>()
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
::protobuf::MessageStatic::descriptor_static(None::<Self>)
}
}
impl ::protobuf::MessageStatic for Example {
fn new() -> Example {
Example::new()
}
#[allow(unused_unsafe,unused_mut)]
fn descriptor_static(_: ::std::option::Option<Example>) -> &'static ::protobuf::reflect::MessageDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
};
unsafe {
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_singular_i64_accessor(
"num_int64",
Example::has_num_int64,
Example::get_num_int64,
));
fields.push(::protobuf::reflect::accessor::make_singular_i64_accessor(
"num_sint64",
Example::has_num_sint64,
Example::get_num_sint64,
));
fields.push(::protobuf::reflect::accessor::make_singular_f64_accessor(
"num_double",
Example::has_num_double,
Example::get_num_double,
));
fields.push(::protobuf::reflect::accessor::make_singular_f32_accessor(
"num_float",
Example::has_num_float,
Example::get_num_float,
));
fields.push(::protobuf::reflect::accessor::make_singular_string_accessor(
"str",
Example::has_str,
Example::get_str,
));
::protobuf::reflect::MessageDescriptor::new::<Example>(
"Example",
fields,
file_descriptor_proto()
)
})
}
}
}
impl ::protobuf::Clear for Example {
fn clear(&mut self) {
self.clear_num_int64();
self.clear_num_sint64();
self.clear_num_double();
self.clear_num_float();
self.clear_str();
self.unknown_fields.clear();
}
}
impl ::std::cmp::PartialEq for Example {
fn eq(&self, other: &Example) -> bool {
self.num_int64 == other.num_int64 &&
self.num_sint64 == other.num_sint64 &&
self.num_double == other.num_double &&
self.num_float == other.num_float &&
self.str == other.str &&
self.unknown_fields == other.unknown_fields
}
}
impl ::std::fmt::Debug for Example {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
static file_descriptor_proto_data: &'static [u8] = &[
0x0a, 0x11, 0x73, 0x72, 0x63, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0x64, 0x0a, 0x07, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x11,
0x0a, 0x09, 0x6e, 0x75, 0x6d, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x01, 0x20, 0x01, 0x28,
0x03, 0x12, 0x12, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x73, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18,
0x02, 0x20, 0x01, 0x28, 0x12, 0x12, 0x12, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x64, 0x6f, 0x75,
0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x12, 0x11, 0x0a, 0x09, 0x6e, 0x75, 0x6d,
0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x12, 0x0b, 0x0a, 0x03,
0x73, 0x74, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x4a, 0xf9, 0x02, 0x0a, 0x06, 0x12, 0x04,
0x00, 0x00, 0x06, 0x01, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x00, 0x00, 0x06, 0x01,
0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x00, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04,
0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x01, 0x02, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02,
0x00, 0x04, 0x12, 0x03, 0x01, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05,
0x12, 0x03, 0x01, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03,
0x01, 0x12, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x01, 0x1e,
0x1f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x02, 0x02, 0x21, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x04, 0x12, 0x03, 0x02, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x02, 0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00,
0x02, 0x01, 0x01, 0x12, 0x03, 0x02, 0x12, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01,
0x03, 0x12, 0x03, 0x02, 0x1f, 0x20, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03,
0x03, 0x02, 0x21, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x04, 0x12, 0x03, 0x03, 0x02,
0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x05, 0x12, 0x03, 0x03, 0x0b, 0x11, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x03, 0x12, 0x1c, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x03, 0x1f, 0x20, 0x0a, 0x0b, 0x0a, 0x04, 0x04,
0x00, 0x02, 0x03, 0x12, 0x03, 0x04, 0x02, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03,
0x04, 0x12, 0x03, 0x04, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x05, 0x12,
0x03, 0x04, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x04,
0x12, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x04, 0x1e, 0x1f,
0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x04, 0x12, 0x03, 0x05, 0x02, 0x1a, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x00, 0x02, 0x04, 0x04, 0x12, 0x03, 0x05, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x00, 0x02, 0x04, 0x05, 0x12, 0x03, 0x05, 0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02,
0x04, 0x01, 0x12, 0x03, 0x05, 0x12, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x04, 0x03,
0x12, 0x03, 0x05, 0x18, 0x19,
];
static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
};
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
}
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
unsafe {
file_descriptor_proto_lazy.get(|| {
parse_descriptor_proto()
})
}
}
#![feature(core)]
#![feature(io)]
extern crate protobuf;
use std::io::Write;
use std::slice::SliceExt;
use protobuf::Message;
mod example;
struct FakeWriter {
vec: Vec<u8>
}
impl FakeWriter {
fn new() -> Self {
FakeWriter { vec: Vec::new() }
}
}
impl std::io::Write for FakeWriter {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.vec = buf.to_vec();
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
#[test]
fn test_message_write() {
let mut a = example::Example::new();
a.set_str("hello world".to_string());
let mut b = example::Example::new();
b.set_num_int64(64);
// b.set_num_sint64(64);
// b.set_num_float(64.0);
// b.set_num_double(64);
b.set_str("hello world".to_string());
let result_a = {
let mut stream = FakeWriter::new();
{
let mut output_stream = protobuf::CodedOutputStream::new(&mut stream);
a.compute_size();
a.write_to_with_cached_sizes(&mut output_stream).unwrap();
output_stream.flush().unwrap();
}
stream.vec
};
let result_b = {
let mut stream = FakeWriter::new();
{
let mut output_stream = protobuf::CodedOutputStream::new(&mut stream);
b.compute_size();
b.write_to_with_cached_sizes(&mut output_stream).unwrap();
output_stream.flush().unwrap();
}
stream.vec
};
assert!(result_a != result_b,
"Result A {{{:?}}} -> {:?} was the same as result B {{{:?}}} -> {:?}",
a, result_a, b, result_b);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment