Fix wc <-> mb conversion

This commit is contained in:
王宇逸
2025-03-08 00:53:01 +08:00
committed by Johannes Altmanninger
parent 4eceabeaad
commit b35825e618
5 changed files with 9 additions and 15 deletions

View File

@@ -1126,11 +1126,10 @@ pub fn str2wcstring(inp: &[u8]) -> WString {
// TODO This check used to be conditionally compiled only on affected platforms.
true
} else {
const _: () = assert!(mem::size_of::<libc::wchar_t>() == mem::size_of::<char>());
let mut codepoint = u32::from(c);
ret = unsafe {
mbrtowc(
std::ptr::addr_of_mut!(codepoint).cast(),
std::ptr::addr_of_mut!(codepoint),
std::ptr::addr_of!(inp[pos]).cast(),
inp.len() - pos,
&mut state,
@@ -1333,9 +1332,7 @@ macro_rules! LL {
fn can_be_encoded(wc: char) -> bool {
let mut converted = [0 as libc::c_char; AT_LEAST_MB_LEN_MAX];
let mut state = zero_mbstate();
unsafe {
wcrtomb(converted.as_mut_ptr(), wc as libc::wchar_t, &mut state) != 0_usize.wrapping_sub(1)
}
unsafe { wcrtomb(converted.as_mut_ptr(), wc as u32, &mut state) != 0_usize.wrapping_sub(1) }
}
/// Call read, blocking and repeating on EINTR. Exits on EAGAIN.

View File

@@ -898,7 +898,7 @@ fn parse_codepoint(
let mut codepoint = u32::from(res);
let sz = unsafe {
mbrtowc(
std::ptr::addr_of_mut!(codepoint).cast(),
std::ptr::addr_of_mut!(codepoint),
std::ptr::addr_of!(read_byte).cast(),
1,
state,

View File

@@ -246,7 +246,7 @@ fn test_convert_private_use() {
let len = unsafe {
wcrtomb(
std::ptr::addr_of_mut!(converted[0]).cast(),
c as libc::wchar_t,
c as u32,
&mut state,
)
};

View File

@@ -331,7 +331,7 @@ pub fn wcs2string_callback(input: &wstr, mut func: impl FnMut(&[u8]) -> bool) ->
let len = unsafe {
wcrtomb(
std::ptr::addr_of_mut!(converted[0]).cast(),
c as libc::wchar_t,
c as u32,
&mut state,
)
};

View File

@@ -1,11 +1,8 @@
extern "C" {
pub fn wcrtomb(s: *mut libc::c_char, wc: libc::wchar_t, ps: *mut mbstate_t) -> usize;
pub fn mbrtowc(
pwc: *mut libc::wchar_t,
s: *const libc::c_char,
n: usize,
p: *mut mbstate_t,
) -> usize;
#[cfg_attr(target_os = "cygwin", link_name = "c32rtomb")]
pub fn wcrtomb(s: *mut libc::c_char, wc: u32, ps: *mut mbstate_t) -> usize;
#[cfg_attr(target_os = "cygwin", link_name = "mbrtoc32")]
pub fn mbrtowc(pwc: *mut u32, s: *const libc::c_char, n: usize, p: *mut mbstate_t) -> usize;
}
// HACK This should be mbstate_t from libc but that's not exposed. Since it's only written by