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::borrow::Cow;
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
use std::ffi::CString;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
@ -58,7 +59,7 @@ impl ErrorStack {
|
||||||
/// Used to report errors from the Rust crate
|
/// Used to report errors from the Rust crate
|
||||||
#[cold]
|
#[cold]
|
||||||
pub(crate) fn internal_error(err: impl error::Error) -> Self {
|
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.
|
/// Empties the current thread's error queue.
|
||||||
|
|
@ -122,7 +123,14 @@ pub struct Error {
|
||||||
code: c_uint,
|
code: c_uint,
|
||||||
file: *const c_char,
|
file: *const c_char,
|
||||||
line: c_uint,
|
line: c_uint,
|
||||||
data: Option<Cow<'static, str>>,
|
data: Data,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum Data {
|
||||||
|
None,
|
||||||
|
CString(CString),
|
||||||
|
String(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Sync for Error {}
|
unsafe impl Sync for Error {}
|
||||||
|
|
@ -148,11 +156,9 @@ impl Error {
|
||||||
// The memory referenced by data is only valid until that slot is overwritten
|
// 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
|
// 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 {
|
let data = if flags & ffi::ERR_FLAG_STRING != 0 {
|
||||||
Some(Cow::Owned(
|
Data::CString(CStr::from_ptr(data.cast()).to_owned())
|
||||||
CStr::from_ptr(data.cast()).to_string_lossy().into_owned(),
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
None
|
Data::None
|
||||||
};
|
};
|
||||||
Some(Error {
|
Some(Error {
|
||||||
code,
|
code,
|
||||||
|
|
@ -176,22 +182,8 @@ impl Error {
|
||||||
self.file,
|
self.file,
|
||||||
self.line,
|
self.line,
|
||||||
);
|
);
|
||||||
let ptr = match self.data {
|
if let Some(cstr) = self.data_cstr() {
|
||||||
Some(Cow::Borrowed(data)) => Some(data.as_ptr() as *mut c_char),
|
ffi::ERR_set_error_data(cstr.as_ptr().cast_mut(), ffi::ERR_FLAG_STRING);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -297,15 +289,29 @@ impl Error {
|
||||||
/// Returns additional data describing the error.
|
/// Returns additional data describing the error.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn data(&self) -> Option<&str> {
|
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 {
|
Self {
|
||||||
code: ffi::ERR_PACK(ffi::ERR_LIB_NONE.0 as _, 0, 0) as _,
|
code: ffi::ERR_PACK(ffi::ERR_LIB_NONE.0 as _, 0, 0) as _,
|
||||||
file: BORING_INTERNAL.as_ptr(),
|
file: BORING_INTERNAL.as_ptr(),
|
||||||
line: 0,
|
line: 0,
|
||||||
data: Some(msg.into()),
|
data: msg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue