(
locale: PyStrRef,
flags: u32,
src: PyStrRef,
vm: &VirtualMachine,
)
| 748 | /// This is used by ntpath.normcase() for proper Windows case conversion |
| 749 | #[pyfunction] |
| 750 | fn LCMapStringEx( |
| 751 | locale: PyStrRef, |
| 752 | flags: u32, |
| 753 | src: PyStrRef, |
| 754 | vm: &VirtualMachine, |
| 755 | ) -> PyResult<PyStrRef> { |
| 756 | use windows_sys::Win32::Globalization::{ |
| 757 | LCMAP_BYTEREV, LCMAP_HASH, LCMAP_SORTHANDLE, LCMAP_SORTKEY, |
| 758 | LCMapStringEx as WinLCMapStringEx, |
| 759 | }; |
| 760 | |
| 761 | // Reject unsupported flags |
| 762 | if flags & (LCMAP_SORTHANDLE | LCMAP_HASH | LCMAP_BYTEREV | LCMAP_SORTKEY) != 0 { |
| 763 | return Err(vm.new_value_error("unsupported flags")); |
| 764 | } |
| 765 | |
| 766 | // Use ToWideString which properly handles WTF-8 (including surrogates) |
| 767 | let locale_wide = locale.as_wtf8().to_wide_with_nul(); |
| 768 | let src_wide = src.as_wtf8().to_wide(); |
| 769 | |
| 770 | if src_wide.len() > i32::MAX as usize { |
| 771 | return Err(vm.new_overflow_error("input string is too long")); |
| 772 | } |
| 773 | |
| 774 | // First call to get required buffer size |
| 775 | let dest_size = unsafe { |
| 776 | WinLCMapStringEx( |
| 777 | locale_wide.as_ptr(), |
| 778 | flags, |
| 779 | src_wide.as_ptr(), |
| 780 | src_wide.len() as i32, |
| 781 | null_mut(), |
| 782 | 0, |
| 783 | null(), |
| 784 | null(), |
| 785 | 0, |
| 786 | ) |
| 787 | }; |
| 788 | |
| 789 | if dest_size <= 0 { |
| 790 | return Err(vm.new_last_os_error()); |
| 791 | } |
| 792 | |
| 793 | // Second call to perform the mapping |
| 794 | let mut dest = vec![0u16; dest_size as usize]; |
| 795 | let nmapped = unsafe { |
| 796 | WinLCMapStringEx( |
| 797 | locale_wide.as_ptr(), |
| 798 | flags, |
| 799 | src_wide.as_ptr(), |
| 800 | src_wide.len() as i32, |
| 801 | dest.as_mut_ptr(), |
| 802 | dest_size, |
| 803 | null(), |
| 804 | null(), |
| 805 | 0, |
| 806 | ) |
| 807 | }; |
nothing calls this directly
no test coverage detected