@@ -1859,7 +1859,7 @@ unsafe fn convert_latin1_to_utf8_partial_raw(
1859
1859
/// a `&mut str`, use `convert_utf16_to_str()` instead of this function.
1860
1860
#[ inline]
1861
1861
pub fn convert_latin1_to_utf8 ( src : & [ u8 ] , dst : & mut [ u8 ] ) -> usize {
1862
- // SAFETY: the slices satisfy convert_latin1_to_utf8_raw's requirements
1862
+ // SAFETY: the slices are valid for reads and writes within them.
1863
1863
unsafe { convert_latin1_to_utf8_raw ( src. as_ptr ( ) , src. len ( ) , dst. as_mut_ptr ( ) , dst. len ( ) ) }
1864
1864
}
1865
1865
@@ -1956,15 +1956,24 @@ pub fn convert_latin1_to_str(src: &[u8], dst: &mut str) -> usize {
1956
1956
///
1957
1957
/// If debug assertions are enabled (and not fuzzing) and the input is
1958
1958
/// not in the range U+0000 to U+00FF, inclusive.
1959
+ #[ inline]
1959
1960
pub fn convert_utf8_to_latin1_lossy ( src : & [ u8 ] , dst : & mut [ u8 ] ) -> usize {
1961
+ // SAFETY: the slices are valid for reads and writes within them.
1962
+ unsafe { convert_utf8_to_latin1_lossy_raw ( src, dst. as_mut_ptr ( ) , dst. len ( ) ) }
1963
+ }
1964
+
1965
+ /// # Safety
1966
+ /// dst_ptr must be valid for writes at offsets `0..dst_len`.
1967
+ ///
1968
+ /// NOTE: this method does not read values from `dst_ptr`, so `dst_ptr` can point to uninitialized memory.
1969
+ unsafe fn convert_utf8_to_latin1_lossy_raw ( src : & [ u8 ] , dst_ptr : * mut u8 , dst_len : usize ) -> usize {
1960
1970
assert ! (
1961
- dst . len ( ) >= src. len( ) ,
1971
+ dst_len >= src. len( ) ,
1962
1972
"Destination must not be shorter than the source."
1963
1973
) ;
1964
1974
non_fuzz_debug_assert ! ( is_utf8_latin1( src) ) ;
1965
1975
let src_len = src. len ( ) ;
1966
1976
let src_ptr = src. as_ptr ( ) ;
1967
- let dst_ptr = dst. as_mut_ptr ( ) ;
1968
1977
let mut total_read = 0usize ;
1969
1978
let mut total_written = 0usize ;
1970
1979
loop {
@@ -1987,7 +1996,9 @@ pub fn convert_utf8_to_latin1_lossy(src: &[u8], dst: &mut [u8]) -> usize {
1987
1996
let trail = src[ total_read] ;
1988
1997
total_read += 1 ;
1989
1998
1990
- dst[ total_written] = ( ( non_ascii & 0x1F ) << 6 ) | ( trail & 0x3F ) ;
1999
+ dst_ptr
2000
+ . add ( total_written)
2001
+ . write ( ( ( non_ascii & 0x1F ) << 6 ) | ( trail & 0x3F ) ) ;
1991
2002
total_written += 1 ;
1992
2003
continue ;
1993
2004
}
@@ -2091,11 +2102,13 @@ pub fn encode_latin1_lossy<'a>(string: &'a str) -> Cow<'a, [u8]> {
2091
2102
}
2092
2103
let ( head, tail) = bytes. split_at ( up_to) ;
2093
2104
let capacity = bytes. len ( ) ;
2094
- let mut vec = Vec :: with_capacity ( capacity) ;
2105
+ let mut vec = Vec :: < u8 > :: with_capacity ( capacity) ;
2095
2106
vec. extend ( head) ;
2096
- vec. resize ( capacity, 0 ) ;
2097
- let written = convert_utf8_to_latin1_lossy ( tail, & mut vec[ up_to..] ) ;
2098
- vec. truncate ( up_to + written) ;
2107
+ // SAFETY: these pointers and lengths are valid for the required reads and writes.
2108
+ let written = unsafe {
2109
+ convert_utf8_to_latin1_lossy_raw ( tail, vec. as_mut_ptr ( ) . add ( up_to) , capacity - up_to)
2110
+ } ;
2111
+ unsafe { vec. set_len ( up_to + written) } ;
2099
2112
Cow :: Owned ( vec)
2100
2113
}
2101
2114
0 commit comments