From cfc88dfc73db4beae93ced94829f04469838f09c Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Tue, 24 Aug 2021 14:10:03 +0200 Subject: [PATCH] Add a function to copy a slice to a C pointer and length. - Add a function to copy a slice to a C pointer and length. - Use it. --- src/buffer.rs | 30 ++++++++++++++++++++++++++ src/lib.rs | 60 +++++++-------------------------------------------- 2 files changed, 38 insertions(+), 52 deletions(-) diff --git a/src/buffer.rs b/src/buffer.rs index 0ca67fd..635fa4b 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -9,6 +9,7 @@ use std::{ ptr::{ copy_nonoverlapping, }, + slice, }; use libc::{ @@ -66,6 +67,35 @@ pub fn rust_bytes_to_c_str_lossy>(mm: MM, s: S) } } +// Copies a slice to a pointer and length adding a terminating NUL. +pub fn rust_bytes_to_ptr_and_len>(mm: MM, s: S, + out: &mut *mut c_char, + out_len: &mut usize) + -> Result<()> +{ + let malloc = mm.malloc; + let s = s.as_ref(); + let len = s.len(); + + unsafe { + // Add a NULL byte. + let buffer = malloc(len + 1) as *mut u8; + if buffer.is_null() { + return Err(Error::OutOfMemory("slice".into(), len + 1)); + } + + slice::from_raw_parts_mut(buffer, len).copy_from_slice(&s); + + // Set the NUL byte. + slice::from_raw_parts_mut(buffer, len + 1)[len] = 0; + + *out = buffer as *mut _; + *out_len = len; + } + + Ok(()) +} + pub fn malloc_cleared(mm: MM) -> Result<*mut T> { let malloc = mm.malloc; diff --git a/src/lib.rs b/src/lib.rs index 38ca925..0d2c4eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -109,9 +109,13 @@ use ffi::MM; mod keystore; use keystore::Keystore; + mod buffer; +use buffer::{ + rust_bytes_to_c_str_lossy, + rust_bytes_to_ptr_and_len, +}; -use crate::buffer::rust_bytes_to_c_str_lossy; // If the PEP_TRACE environment variable is set or we are built in // debug mode, then enable tracing. @@ -946,7 +950,6 @@ ffi!(fn pgp_sign_only( { let session = Session::as_mut(session)?; let mm = session.mm(); - let malloc = mm.malloc; let fpr = unsafe { check_fpr!(fpr) }; let ptext = unsafe { check_slice!(ptext, psize) }; @@ -1002,22 +1005,7 @@ ffi!(fn pgp_sign_only( UnknownError, "Finalizing message")?; - // Add a trailing NUL. - stext.push(0); - - // We need to store it in a buffer backed by the libc allocator. - unsafe { - let buffer = malloc(stext.len()) as *mut u8; - if buffer.is_null() { - return Err(Error::OutOfMemory("stext".into(), stext.len())); - } - slice::from_raw_parts_mut(buffer, stext.len()) - .copy_from_slice(&stext); - *stextp = buffer as *mut _; - - // Don't count the trailing NUL. - *ssizep = stext.len() - 1; - } + rust_bytes_to_ptr_and_len(mm, stext, stextp, ssizep)?; Ok(()) }); @@ -1035,7 +1023,6 @@ fn pgp_encrypt_sign_optional( let session = Session::as_mut(session)?; let mm = session.mm(); - let malloc = mm.malloc; let ptext = unsafe { check_slice!(ptext, psize) }; @@ -1149,22 +1136,7 @@ fn pgp_encrypt_sign_optional( UnknownError, "Finalizing message")?; - // Add a trailing NUL. - ctext.push(0); - - // We need to store it in a buffer backed by the libc allocator. - unsafe { - let buffer = malloc(ctext.len()) as *mut u8; - if buffer.is_null() { - return Err(Error::OutOfMemory("ctext".into(), ctext.len())); - } - slice::from_raw_parts_mut(buffer, ctext.len()) - .copy_from_slice(&ctext); - *ctextp = buffer as *mut _; - - // Don't count the trailing NUL. - *csizep = ctext.len() - 1; - } + rust_bytes_to_ptr_and_len(mm, ctext, ctextp, csizep)?; Ok(()) } @@ -1644,7 +1616,6 @@ ffi!(fn pgp_export_keydata(session: *mut Session, { let session = Session::as_mut(session)?; let mm = session.mm(); - let malloc = mm.malloc; let fpr = unsafe { check_fpr!(fpr) }; t!("({}, {})", fpr, if secret { "secret" } else { "public" }); @@ -1669,22 +1640,7 @@ ffi!(fn pgp_export_keydata(session: *mut Session, format!("Serializing certificate: {}", cert.fingerprint()))?; } - // We need a NUL byte at the end. - keydata.push(0); - - // We need to store it in a buffer backed by the libc allocator. - unsafe { - let buffer = malloc(keydata.len()) as *mut u8; - if buffer.is_null() { - return Err(Error::OutOfMemory("keydata".into(), keydata.len())); - } - slice::from_raw_parts_mut(buffer, keydata.len()) - .copy_from_slice(&keydata); - *keydatap = buffer as *mut _; - - // Don't count the trailing NUL. - *keydata_lenp = keydata.len() - 1; - } + rust_bytes_to_ptr_and_len(mm, keydata, keydatap, keydata_lenp)?; Ok(()) }); -- GitLab