Skip to content

Commit 031723f

Browse files
authored
Merge pull request #1113 from dtolnay/exception
Fix incorrect string len if an exception's message is invalid UTF-8
2 parents a396524 + 438621c commit 031723f

File tree

3 files changed

+17
-11
lines changed

3 files changed

+17
-11
lines changed

src/cxx.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ void cxxbridge1$slice$new(void *self, const void *ptr,
6868
std::size_t len) noexcept;
6969
void *cxxbridge1$slice$ptr(const void *self) noexcept;
7070
std::size_t cxxbridge1$slice$len(const void *self) noexcept;
71-
72-
// try/catch
73-
const char *cxxbridge1$exception(const char *, std::size_t len) noexcept;
7471
} // extern "C"
7572

7673
namespace rust {
@@ -516,6 +513,10 @@ struct PtrLen final {
516513
};
517514
} // namespace repr
518515

516+
extern "C" {
517+
repr::PtrLen cxxbridge1$exception(const char *, std::size_t len) noexcept;
518+
}
519+
519520
namespace detail {
520521
// On some platforms size_t is the same C++ type as one of the sized integer
521522
// types; on others it is a distinct type. Only in the latter case do we need to
@@ -539,8 +540,7 @@ class Fail final {
539540
};
540541

541542
void Fail::operator()(const char *catch$) noexcept {
542-
throw$.len = std::strlen(catch$);
543-
throw$.ptr = const_cast<char *>(cxxbridge1$exception(catch$, throw$.len));
543+
throw$ = cxxbridge1$exception(catch$, std::strlen(catch$));
544544
}
545545
} // namespace detail
546546

src/result.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use core::str;
1212

1313
#[repr(C)]
1414
#[derive(Copy, Clone)]
15-
struct PtrLen {
16-
ptr: NonNull<u8>,
17-
len: usize,
15+
pub struct PtrLen {
16+
pub ptr: NonNull<u8>,
17+
pub len: usize,
1818
}
1919

2020
#[repr(C)]

src/symbols/exception.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
#![cfg(feature = "alloc")]
22

3+
use crate::result::PtrLen;
34
use alloc::boxed::Box;
45
use alloc::string::String;
6+
use core::ptr::NonNull;
57
use core::slice;
68

79
#[export_name = "cxxbridge1$exception"]
8-
unsafe extern "C" fn exception(ptr: *const u8, len: usize) -> *const u8 {
10+
unsafe extern "C" fn exception(ptr: *const u8, len: usize) -> PtrLen {
911
let slice = unsafe { slice::from_raw_parts(ptr, len) };
10-
let boxed = String::from_utf8_lossy(slice).into_owned().into_boxed_str();
11-
Box::leak(boxed).as_ptr()
12+
let string = String::from_utf8_lossy(slice);
13+
let len = string.len();
14+
let raw_str = Box::into_raw(string.into_owned().into_boxed_str());
15+
let raw_u8 = raw_str.cast::<u8>();
16+
let nonnull = unsafe { NonNull::new_unchecked(raw_u8) };
17+
PtrLen { ptr: nonnull, len }
1218
}

0 commit comments

Comments
 (0)