Skip to content

Commit 9e6320f

Browse files
committed
Move convert_path_separator to trait and use it in readlink
1 parent bbba87c commit 9e6320f

File tree

2 files changed

+49
-46
lines changed

2 files changed

+49
-46
lines changed

src/shims/os_str.rs

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,52 +14,11 @@ use rustc_target::abi::LayoutOf;
1414
use crate::*;
1515

1616
/// Represent how path separator conversion should be done.
17-
enum Pathconversion {
17+
pub enum Pathconversion {
1818
HostToTarget,
1919
TargetToHost,
2020
}
2121

22-
/// Perform path separator conversion if needed.
23-
fn convert_path_separator<'a>(
24-
os_str: Cow<'a, OsStr>,
25-
target_os: &str,
26-
direction: Pathconversion,
27-
) -> Cow<'a, OsStr> {
28-
#[cfg(windows)]
29-
return if target_os == "windows" {
30-
// Windows-on-Windows, all fine.
31-
os_str
32-
} else {
33-
// Unix target, Windows host.
34-
let (from, to) = match direction {
35-
Pathconversion::HostToTarget => ('\\', '/'),
36-
Pathconversion::TargetToHost => ('/', '\\'),
37-
};
38-
let converted = os_str
39-
.encode_wide()
40-
.map(|wchar| if wchar == from as u16 { to as u16 } else { wchar })
41-
.collect::<Vec<_>>();
42-
Cow::Owned(OsString::from_wide(&converted))
43-
};
44-
#[cfg(unix)]
45-
return if target_os == "windows" {
46-
// Windows target, Unix host.
47-
let (from, to) = match direction {
48-
Pathconversion::HostToTarget => ('/', '\\'),
49-
Pathconversion::TargetToHost => ('\\', '/'),
50-
};
51-
let converted = os_str
52-
.as_bytes()
53-
.iter()
54-
.map(|&wchar| if wchar == from as u8 { to as u8 } else { wchar })
55-
.collect::<Vec<_>>();
56-
Cow::Owned(OsString::from_vec(converted))
57-
} else {
58-
// Unix-on-Unix, all is fine.
59-
os_str
60-
};
61-
}
62-
6322
#[cfg(unix)]
6423
pub fn os_str_to_bytes<'a, 'tcx>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
6524
Ok(os_str.as_bytes())
@@ -229,7 +188,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
229188
let this = self.eval_context_ref();
230189
let os_str = this.read_os_str_from_c_str(scalar)?;
231190

232-
Ok(match convert_path_separator(Cow::Borrowed(os_str), &this.tcx.sess.target.target.target_os, Pathconversion::TargetToHost) {
191+
Ok(match this.convert_path_separator(Cow::Borrowed(os_str), Pathconversion::TargetToHost) {
233192
Cow::Borrowed(x) => Cow::Borrowed(Path::new(x)),
234193
Cow::Owned(y) => Cow::Owned(PathBuf::from(y)),
235194
})
@@ -240,7 +199,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
240199
let this = self.eval_context_ref();
241200
let os_str = this.read_os_str_from_wide_str(scalar)?;
242201

243-
Ok(convert_path_separator(Cow::Owned(os_str), &this.tcx.sess.target.target.target_os, Pathconversion::TargetToHost).into_owned().into())
202+
Ok(this.convert_path_separator(Cow::Owned(os_str), Pathconversion::TargetToHost).into_owned().into())
244203
}
245204

246205
/// Write a Path to the machine memory (as a null-terminated sequence of bytes),
@@ -252,7 +211,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
252211
size: u64,
253212
) -> InterpResult<'tcx, (bool, u64)> {
254213
let this = self.eval_context_mut();
255-
let os_str = convert_path_separator(Cow::Borrowed(path.as_os_str()), &this.tcx.sess.target.target.target_os, Pathconversion::HostToTarget);
214+
let os_str = this.convert_path_separator(Cow::Borrowed(path.as_os_str()), Pathconversion::HostToTarget);
256215
this.write_os_str_to_c_str(&os_str, scalar, size)
257216
}
258217

@@ -265,8 +224,50 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
265224
size: u64,
266225
) -> InterpResult<'tcx, (bool, u64)> {
267226
let this = self.eval_context_mut();
268-
let os_str = convert_path_separator(Cow::Borrowed(path.as_os_str()), &this.tcx.sess.target.target.target_os, Pathconversion::HostToTarget);
227+
let os_str = this.convert_path_separator(Cow::Borrowed(path.as_os_str()), Pathconversion::HostToTarget);
269228
this.write_os_str_to_wide_str(&os_str, scalar, size)
270229
}
230+
231+
fn convert_path_separator<'a>(
232+
&self,
233+
os_str: Cow<'a, OsStr>,
234+
direction: Pathconversion,
235+
) -> Cow<'a, OsStr> {
236+
let this = self.eval_context_ref();
237+
let target_os = &this.tcx.sess.target.target.target_os;
238+
#[cfg(windows)]
239+
return if target_os == "windows" {
240+
// Windows-on-Windows, all fine.
241+
os_str
242+
} else {
243+
// Unix target, Windows host.
244+
let (from, to) = match direction {
245+
Pathconversion::HostToTarget => ('\\', '/'),
246+
Pathconversion::TargetToHost => ('/', '\\'),
247+
};
248+
let converted = os_str
249+
.encode_wide()
250+
.map(|wchar| if wchar == from as u16 { to as u16 } else { wchar })
251+
.collect::<Vec<_>>();
252+
Cow::Owned(OsString::from_wide(&converted))
253+
};
254+
#[cfg(unix)]
255+
return if target_os == "windows" {
256+
// Windows target, Unix host.
257+
let (from, to) = match direction {
258+
Pathconversion::HostToTarget => ('/', '\\'),
259+
Pathconversion::TargetToHost => ('\\', '/'),
260+
};
261+
let converted = os_str
262+
.as_bytes()
263+
.iter()
264+
.map(|&wchar| if wchar == from as u8 { to as u8 } else { wchar })
265+
.collect::<Vec<_>>();
266+
Cow::Owned(OsString::from_vec(converted))
267+
} else {
268+
// Unix-on-Unix, all is fine.
269+
os_str
270+
};
271+
}
271272
}
272273

src/shims/posix/fs.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::fs::{read_dir, remove_dir, remove_file, rename, DirBuilder, File, FileT
44
use std::io::{self, Read, Seek, SeekFrom, Write};
55
use std::path::Path;
66
use std::time::SystemTime;
7+
use std::borrow::Cow;
78

89
use log::trace;
910

@@ -1371,6 +1372,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
13711372
let result = std::fs::read_link(pathname);
13721373
match result {
13731374
Ok(resolved) => {
1375+
let resolved = this.convert_path_separator(Cow::Borrowed(resolved.as_ref()), crate::shims::os_str::Pathconversion::HostToTarget);
13741376
let mut path_bytes = crate::shims::os_str::os_str_to_bytes(resolved.as_ref())?;
13751377
let bufsize: usize = bufsize.try_into().unwrap();
13761378
if path_bytes.len() > bufsize {

0 commit comments

Comments
 (0)