Skip to content

Commit

Permalink
Fix CString compatibility with bincode v1 (#502)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZoeyR authored Feb 6, 2022
1 parent 6c7be9c commit 2e16e13
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 21 deletions.
9 changes: 1 addition & 8 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,11 @@ pub enum DecodeError {
duration: core::time::Duration,
},

/// The decoder tried to decode a `CStr`, but the incoming data contained a 0 byte
#[cfg(feature = "std")]
CStrNulError {
/// The inner exception
inner: std::ffi::FromBytesWithNulError,
},

/// The decoder tried to decode a `CString`, but the incoming data contained a 0 byte
#[cfg(feature = "std")]
CStringNulError {
/// The inner exception
inner: std::ffi::FromVecWithNulError,
inner: std::ffi::NulError,
},

/// An uncommon error occurred, see the inner text for more information
Expand Down
13 changes: 3 additions & 10 deletions src/features/impl_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,27 +125,20 @@ impl<'storage, W: std::io::Write> Writer for IoWriter<'storage, W> {

impl<'a> Encode for &'a CStr {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
self.to_bytes_with_nul().encode(encoder)
}
}

impl<'de> BorrowDecode<'de> for &'de CStr {
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
let bytes = <&[u8]>::borrow_decode(decoder)?;
CStr::from_bytes_with_nul(bytes).map_err(|e| DecodeError::CStrNulError { inner: e })
self.to_bytes().encode(encoder)
}
}

impl Encode for CString {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
self.as_bytes_with_nul().encode(encoder)
self.as_bytes().encode(encoder)
}
}

impl Decode for CString {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
let vec = std::vec::Vec::decode(decoder)?;
CString::from_vec_with_nul(vec).map_err(|inner| DecodeError::CStringNulError { inner })
CString::new(vec).map_err(|inner| DecodeError::CStringNulError { inner })
}
}

Expand Down
3 changes: 3 additions & 0 deletions tests/issues.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ mod issue_459;

#[path = "issues/issue_474.rs"]
mod issue_474;

#[path = "issues/issue_498.rs"]
mod issue_498;
17 changes: 17 additions & 0 deletions tests/issues/issue_498.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#![cfg(feature = "std")]

extern crate std;

use std::ffi::CString;

#[test]
fn test_issue_498() {
let bytes = [1, 0, 0, 0, 0, 0, 0, 0, 0];
let out: Result<(CString, _), _> =
bincode::decode_from_slice(&bytes, bincode::config::legacy().with_limit::<1024>());

match out.unwrap_err() {
bincode::error::DecodeError::CStringNulError { inner: _ } => {}
err => panic!("Expected CStringNullErr, found {:?}", err),
}
}
6 changes: 3 additions & 3 deletions tests/std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ fn test_std_commons() {
// &CStr
let cstr = CStr::from_bytes_with_nul(b"Hello world\0").unwrap();
let len = bincode::encode_into_slice(cstr, &mut buffer, config).unwrap();
let (decoded, len): (&CStr, usize) =
let (decoded, len): (CString, usize) =
bincode::decode_from_slice(&mut buffer[..len], config).unwrap();
assert_eq!(cstr, decoded);
assert_eq!(len, 13);
assert_eq!(cstr, decoded.as_c_str());
assert_eq!(len, 12);

// Path
let path = Path::new("C:/Program Files/Foo");
Expand Down

0 comments on commit 2e16e13

Please sign in to comment.