@@ -72,11 +72,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
7272 u16vec_to_osstring ( u16_vec)
7373 }
7474
75- /// Helper function to write an OsStr as a null-terminated sequence of bytes, which is what
76- /// the Unix APIs usually handle. This function returns `Ok((false, length))` without trying
77- /// to write if `size` is not large enough to fit the contents of `os_string` plus a null
78- /// terminator. It returns `Ok((true, length))` if the writing process was successful. The
79- /// string length returned does include the null terminator.
75+ /// Helper function to write an OsStr as a null-terminated sequence of bytes, which is what the
76+ /// Unix APIs usually handle. Returns `(success, full_len)`, where length includes the null
77+ /// terminator. On failure, nothing is written.
8078 fn write_os_str_to_c_str (
8179 & mut self ,
8280 os_str : & OsStr ,
@@ -87,19 +85,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
8785 self . eval_context_mut ( ) . write_c_str ( bytes, ptr, size)
8886 }
8987
90- /// Helper function to write an OsStr as a 0x0000-terminated u16-sequence, which is what the
91- /// Windows APIs usually handle.
92- ///
93- /// If `truncate == false` (the usual mode of operation), this function returns `Ok((false,
94- /// length))` without trying to write if `size` is not large enough to fit the contents of
95- /// `os_string` plus a null terminator. It returns `Ok((true, length))` if the writing process
96- /// was successful. The string length returned does include the null terminator. Length is
97- /// measured in units of `u16.`
98- ///
99- /// If `truncate == true`, then in case `size` is not large enough it *will* write the first
100- /// `size.saturating_sub(1)` many items, followed by a null terminator (if `size > 0`).
101- /// The return value is still `(false, length)` in that case.
102- fn write_os_str_to_wide_str (
88+ /// Internal helper to share code between `write_os_str_to_wide_str` and
89+ /// `write_os_str_to_wide_str_truncated`.
90+ fn write_os_str_to_wide_str_helper (
10391 & mut self ,
10492 os_str : & OsStr ,
10593 ptr : Pointer < Option < Provenance > > ,
@@ -133,6 +121,29 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
133121 Ok ( ( written, size_needed) )
134122 }
135123
124+ /// Helper function to write an OsStr as a 0x0000-terminated u16-sequence, which is what the
125+ /// Windows APIs usually handle. Returns `(success, full_len)`, where length is measured
126+ /// in units of `u16` and includes the null terminator. On failure, nothing is written.
127+ fn write_os_str_to_wide_str (
128+ & mut self ,
129+ os_str : & OsStr ,
130+ ptr : Pointer < Option < Provenance > > ,
131+ size : u64 ,
132+ ) -> InterpResult < ' tcx , ( bool , u64 ) > {
133+ self . write_os_str_to_wide_str_helper ( os_str, ptr, size, /*truncate*/ false )
134+ }
135+
136+ /// Like `write_os_str_to_wide_str`, but on failure as much as possible is written into
137+ /// the buffer (always with a null terminator).
138+ fn write_os_str_to_wide_str_truncated (
139+ & mut self ,
140+ os_str : & OsStr ,
141+ ptr : Pointer < Option < Provenance > > ,
142+ size : u64 ,
143+ ) -> InterpResult < ' tcx , ( bool , u64 ) > {
144+ self . write_os_str_to_wide_str_helper ( os_str, ptr, size, /*truncate*/ true )
145+ }
146+
136147 /// Allocate enough memory to store the given `OsStr` as a null-terminated sequence of bytes.
137148 fn alloc_os_str_as_c_str (
138149 & mut self ,
@@ -160,9 +171,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
160171
161172 let arg_type = Ty :: new_array ( this. tcx . tcx , this. tcx . types . u16 , size) ;
162173 let arg_place = this. allocate ( this. layout_of ( arg_type) . unwrap ( ) , memkind) ?;
163- let ( written, _) = self
164- . write_os_str_to_wide_str ( os_str, arg_place. ptr ( ) , size, /*truncate*/ false )
165- . unwrap ( ) ;
174+ let ( written, _) = self . write_os_str_to_wide_str ( os_str, arg_place. ptr ( ) , size) . unwrap ( ) ;
166175 assert ! ( written) ;
167176 Ok ( arg_place. ptr ( ) )
168177 }
@@ -217,12 +226,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
217226 path : & Path ,
218227 ptr : Pointer < Option < Provenance > > ,
219228 size : u64 ,
220- truncate : bool ,
221229 ) -> InterpResult < ' tcx , ( bool , u64 ) > {
222230 let this = self . eval_context_mut ( ) ;
223231 let os_str =
224232 this. convert_path ( Cow :: Borrowed ( path. as_os_str ( ) ) , PathConversion :: HostToTarget ) ;
225- this. write_os_str_to_wide_str ( & os_str, ptr, size, truncate)
233+ this. write_os_str_to_wide_str ( & os_str, ptr, size)
234+ }
235+
236+ /// Write a Path to the machine memory (as a null-terminated sequence of `u16`s),
237+ /// adjusting path separators if needed.
238+ fn write_path_to_wide_str_truncated (
239+ & mut self ,
240+ path : & Path ,
241+ ptr : Pointer < Option < Provenance > > ,
242+ size : u64 ,
243+ ) -> InterpResult < ' tcx , ( bool , u64 ) > {
244+ let this = self . eval_context_mut ( ) ;
245+ let os_str =
246+ this. convert_path ( Cow :: Borrowed ( path. as_os_str ( ) ) , PathConversion :: HostToTarget ) ;
247+ this. write_os_str_to_wide_str_truncated ( & os_str, ptr, size)
226248 }
227249
228250 /// Allocate enough memory to store a Path as a null-terminated sequence of bytes,
0 commit comments