Skip to content

Commit

Permalink
Merge pull request #1113 from dtolnay/exception
Browse files Browse the repository at this point in the history
Fix incorrect string len if an exception's message is invalid UTF-8
  • Loading branch information
dtolnay committed Oct 15, 2022
2 parents a396524 + 438621c commit 031723f
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 11 deletions.
10 changes: 5 additions & 5 deletions src/cxx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ void cxxbridge1$slice$new(void *self, const void *ptr,
std::size_t len) noexcept;
void *cxxbridge1$slice$ptr(const void *self) noexcept;
std::size_t cxxbridge1$slice$len(const void *self) noexcept;

// try/catch
const char *cxxbridge1$exception(const char *, std::size_t len) noexcept;
} // extern "C"

namespace rust {
Expand Down Expand Up @@ -516,6 +513,10 @@ struct PtrLen final {
};
} // namespace repr

extern "C" {
repr::PtrLen cxxbridge1$exception(const char *, std::size_t len) noexcept;
}

namespace detail {
// On some platforms size_t is the same C++ type as one of the sized integer
// types; on others it is a distinct type. Only in the latter case do we need to
Expand All @@ -539,8 +540,7 @@ class Fail final {
};

void Fail::operator()(const char *catch$) noexcept {
throw$.len = std::strlen(catch$);
throw$.ptr = const_cast<char *>(cxxbridge1$exception(catch$, throw$.len));
throw$ = cxxbridge1$exception(catch$, std::strlen(catch$));
}
} // namespace detail

Expand Down
6 changes: 3 additions & 3 deletions src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use core::str;

#[repr(C)]
#[derive(Copy, Clone)]
struct PtrLen {
ptr: NonNull<u8>,
len: usize,
pub struct PtrLen {
pub ptr: NonNull<u8>,
pub len: usize,
}

#[repr(C)]
Expand Down
12 changes: 9 additions & 3 deletions src/symbols/exception.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
#![cfg(feature = "alloc")]

use crate::result::PtrLen;
use alloc::boxed::Box;
use alloc::string::String;
use core::ptr::NonNull;
use core::slice;

#[export_name = "cxxbridge1$exception"]
unsafe extern "C" fn exception(ptr: *const u8, len: usize) -> *const u8 {
unsafe extern "C" fn exception(ptr: *const u8, len: usize) -> PtrLen {
let slice = unsafe { slice::from_raw_parts(ptr, len) };
let boxed = String::from_utf8_lossy(slice).into_owned().into_boxed_str();
Box::leak(boxed).as_ptr()
let string = String::from_utf8_lossy(slice);
let len = string.len();
let raw_str = Box::into_raw(string.into_owned().into_boxed_str());
let raw_u8 = raw_str.cast::<u8>();
let nonnull = unsafe { NonNull::new_unchecked(raw_u8) };
PtrLen { ptr: nonnull, len }
}

0 comments on commit 031723f

Please sign in to comment.