Skip to content

Commit dcb118d

Browse files
committed
change canonicalization to also work on freshly created files
1 parent 0249b97 commit dcb118d

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

src/common/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl Context {
115115

116116
// resolve file arguments; if something can't be resolved, don't add it to the "edit" list
117117
let resolved_args = sudo_options.positional_args.iter().map(|arg| {
118-
std::fs::canonicalize(arg)
118+
crate::common::resolve::canonicalize_newfile(arg)
119119
.map_err(|_| arg)
120120
.and_then(|path| path.into_os_string().into_string().map_err(|_| arg))
121121
});

src/common/resolve.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,20 @@ mod tests {
329329
/// Resolve symlinks in all the directories leading up to a file, but
330330
/// not the file itself; this allows sudo to specify a precise policy with
331331
/// tools like busybox or pgrep (which is a symlink to pgrep on systems)
332+
/// This function will check for existence.
332333
pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
334+
let reconstructed_path = canonicalize_newfile(path)?;
335+
336+
// access the object to generate the regular error if it does not exist
337+
let _ = fs::metadata(&reconstructed_path)?;
338+
339+
Ok(reconstructed_path)
340+
}
341+
342+
/// Resolve symlinks in all the directories leading up to a file, but
343+
/// not the file itself; this allows us to keep symlinks as is, and will
344+
/// also work on non-existing files.
345+
pub fn canonicalize_newfile<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
333346
let path = path.as_ref();
334347
let Some(parent) = path.parent() else {
335348
// path is "/" or a prefix
@@ -344,9 +357,6 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
344357
canon_path
345358
};
346359

347-
// access the object to generate the regular error if it does not exist
348-
let _ = fs::metadata(&reconstructed_path)?;
349-
350360
Ok(reconstructed_path)
351361
}
352362

@@ -358,7 +368,7 @@ mod test {
358368
#[test]
359369
fn canonicalization() {
360370
assert_eq!(canonicalize("/").unwrap(), Path::new("/"));
361-
assert_eq!(canonicalize("").unwrap(), Path::new(""));
371+
assert!(canonicalize("").is_err());
362372
if cfg!(any(target_os = "linux", target_os = "macos")) {
363373
// this test REQUIRES /usr/bin/unxz to be a symlink for /usr/bin/xz
364374
assert_eq!(

0 commit comments

Comments
 (0)