mirror of
https://github.com/openharmony/third_party_rust_libloading.git
synced 2026-07-21 00:26:36 -04:00
Remove failure path from util::CowCString
This commit is contained in:
+2
-2
@@ -1,7 +1,7 @@
|
||||
/// UNIX implementation of dynamic library loading.
|
||||
///
|
||||
/// This module should eventually be expanded with more UNIX-specific functionality in the future.
|
||||
use util::{CheckedCStr, CStringAsRef};
|
||||
use util::{CowCString, CStringAsRef};
|
||||
|
||||
use std::ffi::{CStr, CString, OsStr};
|
||||
use std::marker;
|
||||
@@ -125,7 +125,7 @@ impl Library {
|
||||
/// You may append a null byte at the end of the byte string to avoid string allocation in some
|
||||
/// cases. E.g. for symbol `sin` you may write `b"sin\0"` instead of `b"sin"`.
|
||||
pub unsafe fn get<T>(&self, symbol: &[u8]) -> ::Result<Symbol<T>> {
|
||||
let symbol = try!(CheckedCStr::from_bytes(symbol));
|
||||
let symbol = try!(CowCString::from_bytes(symbol));
|
||||
// `dlsym` may return nullptr in two cases: when a symbol genuinely points to a null
|
||||
// pointer or the symbol cannot be found. In order to detect this case a double dlerror
|
||||
// pattern must be used, which is, sadly, a little bit racy.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
extern crate winapi;
|
||||
extern crate kernel32;
|
||||
|
||||
use util::{CheckedCStr, CStringAsRef};
|
||||
use util::{CowCString, CStringAsRef};
|
||||
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::marker;
|
||||
@@ -67,7 +67,7 @@ impl Library {
|
||||
/// You may append a null byte at the end of the byte string to avoid string allocation in some
|
||||
/// cases. E.g. for symbol `sin` you may write `b"sin\0"` instead of `b"sin"`.
|
||||
pub unsafe fn get<T>(&self, symbol: &[u8]) -> ::Result<Symbol<T>> {
|
||||
let symbol = try!(CheckedCStr::from_bytes(symbol));
|
||||
let symbol = try!(CowCString::from_bytes(symbol));
|
||||
with_get_last_error(|| {
|
||||
let symbol = kernel32::GetProcAddress(self.0, symbol.cstring_ref());
|
||||
if symbol.is_null() {
|
||||
|
||||
+13
-25
@@ -26,22 +26,19 @@ impl ::std::fmt::Display for NullError {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CheckedCStr<'a> {
|
||||
s: Option<CString>,
|
||||
p: Option<&'a raw::c_char>
|
||||
pub enum CowCString<'a> {
|
||||
Owned(CString),
|
||||
Ref(&'a raw::c_char)
|
||||
}
|
||||
|
||||
impl<'a> CheckedCStr<'a> {
|
||||
impl<'a> CowCString<'a> {
|
||||
/// Checks for last byte and avoids alocatting if its zero.
|
||||
///
|
||||
/// Non-last null bytes still result in an error.
|
||||
pub fn from_bytes(slice: &'a [u8]) -> Result<CheckedCStr<'a>, NullError> {
|
||||
pub fn from_bytes(slice: &'a [u8]) -> Result<CowCString<'a>, NullError> {
|
||||
Ok(if slice.len() == 0 {
|
||||
static ZERO: raw::c_char = 0;
|
||||
CheckedCStr {
|
||||
s: None,
|
||||
p: Some(&ZERO)
|
||||
}
|
||||
CowCString::Ref(&ZERO)
|
||||
} else if let Some(&0) = slice.last() {
|
||||
// check for inner nulls
|
||||
for (c, i) in slice.iter().zip(0..slice.len()-2) {
|
||||
@@ -49,15 +46,9 @@ impl<'a> CheckedCStr<'a> {
|
||||
return Err(NullError(i));
|
||||
}
|
||||
}
|
||||
CheckedCStr {
|
||||
s: None,
|
||||
p: Some(unsafe { ::std::mem::transmute(slice.get_unchecked(0)) }),
|
||||
}
|
||||
CowCString::Ref(unsafe {::std::mem::transmute(slice.get_unchecked(0))})
|
||||
} else {
|
||||
CheckedCStr {
|
||||
s: Some(try!(CString::new(slice))),
|
||||
p: None
|
||||
}
|
||||
CowCString::Owned(try!(CString::new(slice)))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -72,14 +63,11 @@ impl CStringAsRef for CString {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> CStringAsRef for CheckedCStr<'a> {
|
||||
fn cstring_ref(&self) -> &raw::c_char {
|
||||
if let Some(ref p) = self.p {
|
||||
*p
|
||||
} else if let Some(ref s) = self.s {
|
||||
s.cstring_ref()
|
||||
} else {
|
||||
unreachable!()
|
||||
impl<'a> CStringAsRef for CowCString<'a> {
|
||||
fn cstring_ref(&self) -> &raw::c_char {
|
||||
match self {
|
||||
&CowCString::Ref(r) => r,
|
||||
&CowCString::Owned(ref o) => o.cstring_ref()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user