Fix CString compatibility with bincode v1 (#502)

This commit is contained in:
Lena Hellström 2022-02-06 10:36:03 +01:00 committed by GitHub
parent a8bdffa844
commit cbad043a53
5 changed files with 27 additions and 21 deletions

View File

@ -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

View File

@ -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 })
}
}

View File

@ -14,3 +14,6 @@ mod issue_459;
#[path = "issues/issue_474.rs"]
mod issue_474;
#[path = "issues/issue_498.rs"]
mod issue_498;

17
tests/issues/issue_498.rs Normal file
View File

@ -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),
}
}

View File

@ -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");