Fix string data conversion in ErrorStack::put()
This commit is contained in:
parent
353ea62c17
commit
e3998212ed
|
|
@ -20,6 +20,7 @@ use openssl_macros::corresponds;
|
|||
use std::borrow::Cow;
|
||||
use std::error;
|
||||
use std::ffi::CStr;
|
||||
use std::ffi::CString;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::ptr;
|
||||
|
|
@ -58,7 +59,7 @@ impl ErrorStack {
|
|||
/// Used to report errors from the Rust crate
|
||||
#[cold]
|
||||
pub(crate) fn internal_error(err: impl error::Error) -> Self {
|
||||
Self(vec![Error::new_internal(err.to_string())])
|
||||
Self(vec![Error::new_internal(Data::String(err.to_string()))])
|
||||
}
|
||||
|
||||
/// Empties the current thread's error queue.
|
||||
|
|
@ -122,7 +123,14 @@ pub struct Error {
|
|||
code: c_uint,
|
||||
file: *const c_char,
|
||||
line: c_uint,
|
||||
data: Option<Cow<'static, str>>,
|
||||
data: Data,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum Data {
|
||||
None,
|
||||
CString(CString),
|
||||
String(String),
|
||||
}
|
||||
|
||||
unsafe impl Sync for Error {}
|
||||
|
|
@ -148,11 +156,9 @@ impl Error {
|
|||
// The memory referenced by data is only valid until that slot is overwritten
|
||||
// in the error stack, so we'll need to copy it off if it's dynamic
|
||||
let data = if flags & ffi::ERR_FLAG_STRING != 0 {
|
||||
Some(Cow::Owned(
|
||||
CStr::from_ptr(data.cast()).to_string_lossy().into_owned(),
|
||||
))
|
||||
Data::CString(CStr::from_ptr(data.cast()).to_owned())
|
||||
} else {
|
||||
None
|
||||
Data::None
|
||||
};
|
||||
Some(Error {
|
||||
code,
|
||||
|
|
@ -176,22 +182,8 @@ impl Error {
|
|||
self.file,
|
||||
self.line,
|
||||
);
|
||||
let ptr = match self.data {
|
||||
Some(Cow::Borrowed(data)) => Some(data.as_ptr() as *mut c_char),
|
||||
Some(Cow::Owned(ref data)) => {
|
||||
let ptr = ffi::OPENSSL_malloc((data.len() + 1) as _) as *mut c_char;
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
ptr::copy_nonoverlapping(data.as_ptr(), ptr as *mut u8, data.len());
|
||||
*ptr.add(data.len()) = 0;
|
||||
Some(ptr)
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
if let Some(ptr) = ptr {
|
||||
ffi::ERR_add_error_data(1, ptr);
|
||||
if let Some(cstr) = self.data_cstr() {
|
||||
ffi::ERR_set_error_data(cstr.as_ptr().cast_mut(), ffi::ERR_FLAG_STRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -297,15 +289,29 @@ impl Error {
|
|||
/// Returns additional data describing the error.
|
||||
#[must_use]
|
||||
pub fn data(&self) -> Option<&str> {
|
||||
self.data.as_deref()
|
||||
match &self.data {
|
||||
Data::None => None,
|
||||
Data::CString(cstring) => cstring.to_str().ok(),
|
||||
Data::String(s) => Some(s),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_internal(msg: String) -> Self {
|
||||
#[must_use]
|
||||
fn data_cstr(&self) -> Option<Cow<'_, CStr>> {
|
||||
let s = match &self.data {
|
||||
Data::None => return None,
|
||||
Data::CString(cstr) => return Some(Cow::Borrowed(cstr)),
|
||||
Data::String(s) => s.as_str(),
|
||||
};
|
||||
CString::new(s).ok().map(Cow::Owned)
|
||||
}
|
||||
|
||||
fn new_internal(msg: Data) -> Self {
|
||||
Self {
|
||||
code: ffi::ERR_PACK(ffi::ERR_LIB_NONE.0 as _, 0, 0) as _,
|
||||
file: BORING_INTERNAL.as_ptr(),
|
||||
line: 0,
|
||||
data: Some(msg.into()),
|
||||
data: msg,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue