From 4f914dd1617bb2aa3a5a3f5a4b8dec9356e851c1 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Thu, 1 Feb 2024 10:06:09 +0530 Subject: [PATCH] fix(fs): copyFile NUL path on macOS (#22216) Fixes https://github.com/denoland/deno/issues/22211 --- cli/tests/unit/copy_file_test.ts | 11 +++++++++++ ext/fs/std_fs.rs | 13 ++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/cli/tests/unit/copy_file_test.ts b/cli/tests/unit/copy_file_test.ts index 1c967b043b..ad467f5107 100644 --- a/cli/tests/unit/copy_file_test.ts +++ b/cli/tests/unit/copy_file_test.ts @@ -236,3 +236,14 @@ Deno.test( copyFileSyncMode("Hello world!".repeat(128 * 1024)); }, ); + +Deno.test( + { permissions: { read: true, write: true } }, + async function copyFileNulPath() { + const fromFilename = "from.txt\0"; + const toFilename = "to.txt\0"; + await assertRejects(async () => { + await Deno.copyFile(fromFilename, toFilename); + }, TypeError); + }, +); diff --git a/ext/fs/std_fs.rs b/ext/fs/std_fs.rs index bb8d114a06..c1c9200cb5 100644 --- a/ext/fs/std_fs.rs +++ b/ext/fs/std_fs.rs @@ -413,10 +413,11 @@ fn copy_file(from: &Path, to: &Path) -> FsResult<()> { use std::io::Read; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::fs::PermissionsExt; - use std::os::unix::prelude::OsStrExt; - let from_str = CString::new(from.as_os_str().as_bytes()).unwrap(); - let to_str = CString::new(to.as_os_str().as_bytes()).unwrap(); + let from_str = CString::new(from.as_os_str().as_encoded_bytes()) + .map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?; + let to_str = CString::new(to.as_os_str().as_encoded_bytes()) + .map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?; // SAFETY: `from` and `to` are valid C strings. // std::fs::copy does open() + fcopyfile() on macOS. We try to use @@ -555,8 +556,10 @@ fn cp(from: &Path, to: &Path) -> FsResult<()> { use std::ffi::CString; use std::os::unix::ffi::OsStrExt; - let from_str = CString::new(from.as_os_str().as_bytes()).unwrap(); - let to_str = CString::new(to.as_os_str().as_bytes()).unwrap(); + let from_str = CString::new(from.as_os_str().as_bytes()) + .map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?; + let to_str = CString::new(to.as_os_str().as_bytes()) + .map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?; // SAFETY: `from` and `to` are valid C strings. unsafe {