Skip to content

Commit

Permalink
Trim null bytes from Collateral strings (#427)
Browse files Browse the repository at this point in the history
The `Collateral` strings are coming from a C api which includes the null
trailing byte in the length. In order to work with strict JSON parsers
the null byte is omitted from the final rust `String`.
  • Loading branch information
nick-mobilecoin authored Oct 11, 2023
2 parents 0979868 + 3c06805 commit 90d236e
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion dcap/types/src/collateral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,18 @@ fn string_from_bytes(bytes: *mut core::ffi::c_char, size: u32) -> Result<String,
// thus no longer references the `bytes`.
#[allow(unsafe_code)]
let slice = unsafe { core::slice::from_raw_parts(bytes as *const u8, size as usize) };
Ok(String::from_utf8(slice.to_vec())?)

let string = String::from_utf8(slice.to_vec())?;

// The C API returns a null terminated string, so we need to trim the null
// byte(s) off for Json parsers.
let trimmed = string.trim_matches('\0');

if trimmed.is_empty() {
return Err(Error::MissingCollateral);
}

Ok(trimmed.into())
}

fn crl_from_bytes(bytes: *const core::ffi::c_char, size: u32) -> Result<CertificateList, Error> {
Expand Down Expand Up @@ -617,6 +628,20 @@ mod test {
assert_eq!(string, byte_string);
}

#[test]
fn null_terminated_string_strips_off_trailing_null_characters() {
let non_null_terminated_string =
String::from("This is my string. There are many like it, but this one is mine.");
let mut null_terminated_string = non_null_terminated_string.clone();
null_terminated_string.push('\0');
let string = string_from_bytes(
null_terminated_string.as_mut_ptr() as *mut core::ffi::c_char,
null_terminated_string.len() as u32,
)
.expect("Expect valid string");
assert_eq!(string, non_null_terminated_string);
}

#[test]
fn null_string_fails() {
assert_eq!(
Expand Down Expand Up @@ -649,6 +674,21 @@ mod test {
);
}

#[test]
fn string_of_only_null_bytes_fails() {
let mut null_string = String::new();
null_string.push('\0');
null_string.push('\0');
null_string.push('\0');
assert_eq!(
string_from_bytes(
null_string.as_mut_ptr() as *mut core::ffi::c_char,
null_string.len() as u32
),
Err(Error::MissingCollateral)
);
}

#[test]
fn valid_collateral() {
let mut root_crl = include_bytes!("../data/tests/root_crl.der").to_vec();
Expand Down

0 comments on commit 90d236e

Please sign in to comment.