@@ -72,11 +72,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
72
72
u16vec_to_osstring ( u16_vec)
73
73
}
74
74
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.
80
78
fn write_os_str_to_c_str (
81
79
& mut self ,
82
80
os_str : & OsStr ,
@@ -87,19 +85,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
87
85
self . eval_context_mut ( ) . write_c_str ( bytes, ptr, size)
88
86
}
89
87
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 (
103
91
& mut self ,
104
92
os_str : & OsStr ,
105
93
ptr : Pointer < Option < Provenance > > ,
@@ -133,6 +121,29 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
133
121
Ok ( ( written, size_needed) )
134
122
}
135
123
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
+
136
147
/// Allocate enough memory to store the given `OsStr` as a null-terminated sequence of bytes.
137
148
fn alloc_os_str_as_c_str (
138
149
& mut self ,
@@ -160,9 +171,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
160
171
161
172
let arg_type = Ty :: new_array ( this. tcx . tcx , this. tcx . types . u16 , size) ;
162
173
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 ( ) ;
166
175
assert ! ( written) ;
167
176
Ok ( arg_place. ptr ( ) )
168
177
}
@@ -217,12 +226,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
217
226
path : & Path ,
218
227
ptr : Pointer < Option < Provenance > > ,
219
228
size : u64 ,
220
- truncate : bool ,
221
229
) -> InterpResult < ' tcx , ( bool , u64 ) > {
222
230
let this = self . eval_context_mut ( ) ;
223
231
let os_str =
224
232
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)
226
248
}
227
249
228
250
/// Allocate enough memory to store a Path as a null-terminated sequence of bytes,
0 commit comments