2024-01-01 14:58:21 -05:00
|
|
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
2023-03-07 04:13:44 -05:00
|
|
|
|
2024-03-07 20:16:32 -05:00
|
|
|
mod in_memory_fs;
|
2023-04-12 09:13:32 -04:00
|
|
|
mod interface;
|
|
|
|
mod ops;
|
|
|
|
mod std_fs;
|
2023-05-08 11:02:02 -04:00
|
|
|
pub mod sync;
|
2023-04-12 09:13:32 -04:00
|
|
|
|
2024-03-07 20:16:32 -05:00
|
|
|
pub use crate::in_memory_fs::InMemoryFs;
|
2024-04-19 20:12:03 -04:00
|
|
|
pub use crate::interface::AccessCheckCb;
|
|
|
|
pub use crate::interface::AccessCheckFn;
|
2023-04-12 09:13:32 -04:00
|
|
|
pub use crate::interface::FileSystem;
|
2023-05-08 11:02:02 -04:00
|
|
|
pub use crate::interface::FileSystemRc;
|
2023-04-12 09:13:32 -04:00
|
|
|
pub use crate::interface::FsDirEntry;
|
|
|
|
pub use crate::interface::FsFileType;
|
|
|
|
pub use crate::interface::OpenOptions;
|
2023-05-04 14:28:42 -04:00
|
|
|
pub use crate::std_fs::RealFs;
|
2023-05-08 11:02:02 -04:00
|
|
|
pub use crate::sync::MaybeSend;
|
|
|
|
pub use crate::sync::MaybeSync;
|
|
|
|
|
|
|
|
use crate::ops::*;
|
2023-04-12 09:13:32 -04:00
|
|
|
|
2023-04-17 10:10:59 -04:00
|
|
|
use deno_core::error::AnyError;
|
2024-04-19 20:12:03 -04:00
|
|
|
use deno_io::fs::FsError;
|
2024-06-06 23:37:53 -04:00
|
|
|
use std::borrow::Cow;
|
2023-04-17 10:10:59 -04:00
|
|
|
use std::path::Path;
|
2024-09-16 16:39:37 -04:00
|
|
|
use std::path::PathBuf;
|
2023-03-07 04:13:44 -05:00
|
|
|
|
2024-06-06 23:37:53 -04:00
|
|
|
pub trait FsPermissions {
|
2024-04-19 20:12:03 -04:00
|
|
|
fn check_open<'a>(
|
|
|
|
&mut self,
|
|
|
|
resolved: bool,
|
|
|
|
read: bool,
|
|
|
|
write: bool,
|
|
|
|
path: &'a Path,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<std::borrow::Cow<'a, Path>, FsError>;
|
2024-09-16 16:39:37 -04:00
|
|
|
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
|
|
|
fn check_read(
|
|
|
|
&mut self,
|
|
|
|
path: &str,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<PathBuf, AnyError>;
|
|
|
|
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
|
|
|
fn check_read_path<'a>(
|
|
|
|
&mut self,
|
|
|
|
path: &'a Path,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<Cow<'a, Path>, AnyError>;
|
2023-04-17 10:10:59 -04:00
|
|
|
fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError>;
|
|
|
|
fn check_read_blind(
|
|
|
|
&mut self,
|
|
|
|
p: &Path,
|
|
|
|
display: &str,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<(), AnyError>;
|
2024-09-16 16:39:37 -04:00
|
|
|
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
2023-08-03 07:19:19 -04:00
|
|
|
fn check_write(
|
|
|
|
&mut self,
|
2024-09-16 16:39:37 -04:00
|
|
|
path: &str,
|
2023-08-03 07:19:19 -04:00
|
|
|
api_name: &str,
|
2024-09-16 16:39:37 -04:00
|
|
|
) -> Result<PathBuf, AnyError>;
|
|
|
|
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
|
|
|
fn check_write_path<'a>(
|
|
|
|
&mut self,
|
|
|
|
path: &'a Path,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<Cow<'a, Path>, AnyError>;
|
|
|
|
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
2023-08-03 07:19:19 -04:00
|
|
|
fn check_write_partial(
|
|
|
|
&mut self,
|
2024-09-16 16:39:37 -04:00
|
|
|
path: &str,
|
2023-08-03 07:19:19 -04:00
|
|
|
api_name: &str,
|
2024-09-16 16:39:37 -04:00
|
|
|
) -> Result<PathBuf, AnyError>;
|
2023-04-17 10:10:59 -04:00
|
|
|
fn check_write_all(&mut self, api_name: &str) -> Result<(), AnyError>;
|
|
|
|
fn check_write_blind(
|
|
|
|
&mut self,
|
|
|
|
p: &Path,
|
|
|
|
display: &str,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<(), AnyError>;
|
|
|
|
|
2024-04-19 20:12:03 -04:00
|
|
|
fn check<'a>(
|
2023-04-17 10:10:59 -04:00
|
|
|
&mut self,
|
2024-04-19 20:12:03 -04:00
|
|
|
resolved: bool,
|
2023-04-17 10:10:59 -04:00
|
|
|
open_options: &OpenOptions,
|
2024-04-19 20:12:03 -04:00
|
|
|
path: &'a Path,
|
2023-04-17 10:10:59 -04:00
|
|
|
api_name: &str,
|
2024-04-19 20:12:03 -04:00
|
|
|
) -> Result<std::borrow::Cow<'a, Path>, FsError> {
|
|
|
|
self.check_open(
|
|
|
|
resolved,
|
|
|
|
open_options.read,
|
|
|
|
open_options.write || open_options.append,
|
|
|
|
path,
|
|
|
|
api_name,
|
|
|
|
)
|
2023-04-17 10:10:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-06 23:37:53 -04:00
|
|
|
impl FsPermissions for deno_permissions::PermissionsContainer {
|
|
|
|
fn check_open<'a>(
|
|
|
|
&mut self,
|
|
|
|
resolved: bool,
|
|
|
|
read: bool,
|
|
|
|
write: bool,
|
|
|
|
path: &'a Path,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<Cow<'a, Path>, FsError> {
|
|
|
|
if resolved {
|
2024-08-19 13:45:10 -04:00
|
|
|
self
|
|
|
|
.check_special_file(path, api_name)
|
2024-09-10 14:12:24 -04:00
|
|
|
.map_err(FsError::NotCapable)?;
|
2024-06-06 23:37:53 -04:00
|
|
|
return Ok(Cow::Borrowed(path));
|
|
|
|
}
|
|
|
|
|
|
|
|
// If somehow read or write aren't specified, use read
|
|
|
|
let read = read || !write;
|
2024-09-16 16:39:37 -04:00
|
|
|
let mut path: Cow<'a, Path> = Cow::Borrowed(path);
|
2024-06-06 23:37:53 -04:00
|
|
|
if read {
|
2024-09-16 16:39:37 -04:00
|
|
|
let resolved_path = FsPermissions::check_read_path(self, &path, api_name)
|
2024-09-10 14:12:24 -04:00
|
|
|
.map_err(|_| FsError::NotCapable("read"))?;
|
2024-09-16 16:39:37 -04:00
|
|
|
if let Cow::Owned(resolved_path) = resolved_path {
|
|
|
|
path = Cow::Owned(resolved_path);
|
|
|
|
}
|
2024-06-06 23:37:53 -04:00
|
|
|
}
|
|
|
|
if write {
|
2024-09-16 16:39:37 -04:00
|
|
|
let resolved_path =
|
|
|
|
FsPermissions::check_write_path(self, &path, api_name)
|
|
|
|
.map_err(|_| FsError::NotCapable("write"))?;
|
|
|
|
if let Cow::Owned(resolved_path) = resolved_path {
|
|
|
|
path = Cow::Owned(resolved_path);
|
|
|
|
}
|
2024-06-06 23:37:53 -04:00
|
|
|
}
|
2024-09-16 16:39:37 -04:00
|
|
|
Ok(path)
|
2024-06-06 23:37:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
fn check_read(
|
|
|
|
&mut self,
|
2024-09-16 16:39:37 -04:00
|
|
|
path: &str,
|
2024-06-06 23:37:53 -04:00
|
|
|
api_name: &str,
|
2024-09-16 16:39:37 -04:00
|
|
|
) -> Result<PathBuf, AnyError> {
|
2024-06-06 23:37:53 -04:00
|
|
|
deno_permissions::PermissionsContainer::check_read(self, path, api_name)
|
|
|
|
}
|
|
|
|
|
2024-09-16 16:39:37 -04:00
|
|
|
fn check_read_path<'a>(
|
|
|
|
&mut self,
|
|
|
|
path: &'a Path,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<Cow<'a, Path>, AnyError> {
|
|
|
|
deno_permissions::PermissionsContainer::check_read_path(
|
|
|
|
self,
|
|
|
|
path,
|
|
|
|
Some(api_name),
|
|
|
|
)
|
|
|
|
}
|
2024-06-06 23:37:53 -04:00
|
|
|
fn check_read_blind(
|
|
|
|
&mut self,
|
|
|
|
path: &Path,
|
|
|
|
display: &str,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<(), AnyError> {
|
|
|
|
deno_permissions::PermissionsContainer::check_read_blind(
|
|
|
|
self, path, display, api_name,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_write(
|
|
|
|
&mut self,
|
2024-09-16 16:39:37 -04:00
|
|
|
path: &str,
|
2024-06-06 23:37:53 -04:00
|
|
|
api_name: &str,
|
2024-09-16 16:39:37 -04:00
|
|
|
) -> Result<PathBuf, AnyError> {
|
2024-06-06 23:37:53 -04:00
|
|
|
deno_permissions::PermissionsContainer::check_write(self, path, api_name)
|
|
|
|
}
|
|
|
|
|
2024-09-16 16:39:37 -04:00
|
|
|
fn check_write_path<'a>(
|
|
|
|
&mut self,
|
|
|
|
path: &'a Path,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<Cow<'a, Path>, AnyError> {
|
|
|
|
deno_permissions::PermissionsContainer::check_write_path(
|
|
|
|
self, path, api_name,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2024-06-06 23:37:53 -04:00
|
|
|
fn check_write_partial(
|
|
|
|
&mut self,
|
2024-09-16 16:39:37 -04:00
|
|
|
path: &str,
|
2024-06-06 23:37:53 -04:00
|
|
|
api_name: &str,
|
2024-09-16 16:39:37 -04:00
|
|
|
) -> Result<PathBuf, AnyError> {
|
2024-06-06 23:37:53 -04:00
|
|
|
deno_permissions::PermissionsContainer::check_write_partial(
|
|
|
|
self, path, api_name,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_write_blind(
|
|
|
|
&mut self,
|
|
|
|
p: &Path,
|
|
|
|
display: &str,
|
|
|
|
api_name: &str,
|
|
|
|
) -> Result<(), AnyError> {
|
|
|
|
deno_permissions::PermissionsContainer::check_write_blind(
|
|
|
|
self, p, display, api_name,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError> {
|
|
|
|
deno_permissions::PermissionsContainer::check_read_all(self, api_name)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_write_all(&mut self, api_name: &str) -> Result<(), AnyError> {
|
|
|
|
deno_permissions::PermissionsContainer::check_write_all(self, api_name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-12 11:55:50 -04:00
|
|
|
pub const UNSTABLE_FEATURE_NAME: &str = "fs";
|
|
|
|
|
2023-03-17 14:22:15 -04:00
|
|
|
deno_core::extension!(deno_fs,
|
2023-04-12 09:13:32 -04:00
|
|
|
deps = [ deno_web ],
|
2023-05-04 14:28:42 -04:00
|
|
|
parameters = [P: FsPermissions],
|
2023-03-17 14:22:15 -04:00
|
|
|
ops = [
|
2023-05-08 17:07:45 -04:00
|
|
|
op_fs_cwd<P>,
|
|
|
|
op_fs_umask,
|
|
|
|
op_fs_chdir<P>,
|
2023-04-12 09:13:32 -04:00
|
|
|
|
2023-05-08 17:07:45 -04:00
|
|
|
op_fs_open_sync<P>,
|
|
|
|
op_fs_open_async<P>,
|
|
|
|
op_fs_mkdir_sync<P>,
|
|
|
|
op_fs_mkdir_async<P>,
|
|
|
|
op_fs_chmod_sync<P>,
|
|
|
|
op_fs_chmod_async<P>,
|
|
|
|
op_fs_chown_sync<P>,
|
|
|
|
op_fs_chown_async<P>,
|
|
|
|
op_fs_remove_sync<P>,
|
|
|
|
op_fs_remove_async<P>,
|
|
|
|
op_fs_copy_file_sync<P>,
|
|
|
|
op_fs_copy_file_async<P>,
|
|
|
|
op_fs_stat_sync<P>,
|
|
|
|
op_fs_stat_async<P>,
|
|
|
|
op_fs_lstat_sync<P>,
|
|
|
|
op_fs_lstat_async<P>,
|
|
|
|
op_fs_realpath_sync<P>,
|
|
|
|
op_fs_realpath_async<P>,
|
|
|
|
op_fs_read_dir_sync<P>,
|
|
|
|
op_fs_read_dir_async<P>,
|
|
|
|
op_fs_rename_sync<P>,
|
|
|
|
op_fs_rename_async<P>,
|
|
|
|
op_fs_link_sync<P>,
|
|
|
|
op_fs_link_async<P>,
|
|
|
|
op_fs_symlink_sync<P>,
|
|
|
|
op_fs_symlink_async<P>,
|
|
|
|
op_fs_read_link_sync<P>,
|
|
|
|
op_fs_read_link_async<P>,
|
|
|
|
op_fs_truncate_sync<P>,
|
|
|
|
op_fs_truncate_async<P>,
|
|
|
|
op_fs_utime_sync<P>,
|
|
|
|
op_fs_utime_async<P>,
|
|
|
|
op_fs_make_temp_dir_sync<P>,
|
|
|
|
op_fs_make_temp_dir_async<P>,
|
|
|
|
op_fs_make_temp_file_sync<P>,
|
|
|
|
op_fs_make_temp_file_async<P>,
|
|
|
|
op_fs_write_file_sync<P>,
|
|
|
|
op_fs_write_file_async<P>,
|
|
|
|
op_fs_read_file_sync<P>,
|
|
|
|
op_fs_read_file_async<P>,
|
|
|
|
op_fs_read_file_text_sync<P>,
|
|
|
|
op_fs_read_file_text_async<P>,
|
2023-04-12 09:13:32 -04:00
|
|
|
|
2023-05-08 17:07:45 -04:00
|
|
|
op_fs_seek_sync,
|
|
|
|
op_fs_seek_async,
|
2024-09-09 07:09:57 -04:00
|
|
|
op_fs_file_sync_data_sync,
|
|
|
|
op_fs_file_sync_data_async,
|
2024-09-09 18:39:56 -04:00
|
|
|
op_fs_file_sync_sync,
|
|
|
|
op_fs_file_sync_async,
|
2024-02-19 08:33:42 -05:00
|
|
|
op_fs_file_stat_sync,
|
|
|
|
op_fs_file_stat_async,
|
2023-05-08 17:07:45 -04:00
|
|
|
op_fs_flock_async,
|
2024-05-22 19:17:00 -04:00
|
|
|
op_fs_flock_sync,
|
2023-05-08 17:07:45 -04:00
|
|
|
op_fs_funlock_async,
|
2024-05-22 19:17:00 -04:00
|
|
|
op_fs_funlock_sync,
|
2023-05-08 17:07:45 -04:00
|
|
|
op_fs_ftruncate_sync,
|
2024-09-04 04:53:43 -04:00
|
|
|
op_fs_file_truncate_async,
|
2023-05-08 17:07:45 -04:00
|
|
|
op_fs_futime_sync,
|
|
|
|
op_fs_futime_async,
|
2023-04-12 09:13:32 -04:00
|
|
|
|
2023-03-17 14:22:15 -04:00
|
|
|
],
|
|
|
|
esm = [ "30_fs.js" ],
|
2023-03-17 18:15:27 -04:00
|
|
|
options = {
|
2023-05-08 11:02:02 -04:00
|
|
|
fs: FileSystemRc,
|
2023-03-17 14:22:15 -04:00
|
|
|
},
|
2023-03-17 18:15:27 -04:00
|
|
|
state = |state, options| {
|
2023-04-12 09:13:32 -04:00
|
|
|
state.put(options.fs);
|
2023-03-17 14:22:15 -04:00
|
|
|
},
|
|
|
|
);
|